I'm calculating the matrix value with Python, but I want to distinguish the value of equtaion, is there a way?
x - y - 2z = 4
2x - y - z = 2
2x +y +4z = 16
I want to make the expression above like this when I print out the matrix from the function I created
1 -1 -2 | 4
2 -1 -1 | 2
2 1 4 | 16
Same as the rref result of this
1 0 0 | 24
0 1 0 | 72
0 0 1 | -26
def showMatrix():
print("\n")
for i in sd:
for j in i:
print(j, end="\t")
print("\n")
def getone(pp):
for i in range(len(sd[0])):
if sd[pp][pp] != 1:
q00 = sd[pp][pp]
for j in range(len(sd[0])):
sd[pp][j] = sd[pp][j] / q00
def getzero(r, c):
for i in range(len(sd[0])):
if sd[r][c] != 0:
q04 = sd[r][c]
for j in range(len(sd[0])):
sd[r][j] = sd[r][j] - ((q04) * sd[c][j])
sd = [
[1, 1, 2, 9],
[2, 4, -3, 1],
[3, 6, -5, 0]
]
showMatrix()
for i in range(len(sd)):
getone(i)
for j in range(len(sd)):
if i != j:
getzero(j, i)
showMatrix()
print("FiNAL result")
showMatrix()
Here is a function which takes a list of 4 numbers and returns a string representing an equation in x,y,z. It handles coefficients which are negative, zero, or +/-1 appropriately:
def make_equation(nums):
coefficients = nums[:3]
variables = 'xyz'
terms = []
for c,v in zip(coefficients,variables):
if c == 0:
continue
elif c == 1:
coef = ''
elif c == -1:
coef = '-'
else:
coef = str(c)
terms.append(coef + v)
s = ' + '.join(terms)
s = s.replace('+ -','- ')
return s + ' = ' + str(nums[3])
Typical example:
make_equation([2,-3,1,6])
With output:
'2x - 3y + z = 6'
I am programming a vehicle routing problem in Python with PuLP. I got all my code in it, but for some reason I get a negative value for one of my decision variables, even though I restricted all of them to be nonnegative.
My code is as follows (Traveltimes is a two dimensional np array, with travel times between each pair of customers (i,j), where c(i,j) = c(j,i) and c(i,i) = 0.):
My code:
numVehicles = 2
numCustomers = 2
prob = LpProblem("DSP", LpMinimize)
var = [[[0 for k in range(numVehicles)] for j in range(numCustomers+1)] for i in range(numCustomers+1)]
for i in range(numCustomers+1):
for j in range(numCustomers+1):
for k in range(numVehicles):
var[i][j][k] = LpVariable("x"+str(i)+","+str(j)+","+str(k), 0,1, cat='Binary')
# ADD OBJECTIVE
obj = ""
for i in range(numCustomers+1):
for j in range(numCustomers+1):
for k in range(numVehicles):
obj += traveltimes[i][j]*var[i][j][k]
prob += obj
# ADD CONSTRAINTS
# All customers visited
for j in range(numCustomers+1):
for k in range(numVehicles):
nr = ""
for i in range(numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Enter each customer exactly once
for i in range(numCustomers+1):
nr = ""
for k in range(numVehicles):
for j in range(1, numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Leave each customer exactly once
for j in range(numCustomers+1):
nr = ""
for k in range(numVehicles):
for i in range(1, numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Per vehicle only one customer can be visited as first
nrFirst = ""
for k in range(numVehicles):
for j in range(numCustomers+1):
nrFirst += var[0][j][k]
prob += nrFirst <= 1
# Max num vehicles
nrOut = ""
for k in range(numVehicles):
for j in range(numCustomers+1):
nrOut += var[0][j][k]
prob += nrOut <= numVehicles
# Restrict x(0,j,k) to be nonpositive
for j in range(numCustomers+1):
for k in range(numVehicles):
prob += var[0][j][k] >= 0
print(prob)
# Solve LP
prob.solve()
for v in prob.variables():
print(v.name, "=", v.varValue)
print("objective=", value(prob.objective))
The first output is the formulation printed
MINIMIZE
1.731*x0,1,0 + 1.731*x0,1,1 + 2.983*x0,2,0 + 2.983*x0,2,1 + 1.731*x1,0,0 + 1.731*x1,0,1 + 9.375*x1,2,0 + 9.375*x1,2,1 + 2.983*x2,0,0 + 2.983*x2,0,1 + 9.375*x2,1,0 + 9.375*x2,1,1 + 0.0
SUBJECT TO
_C1: x0,0,0 + x1,0,0 + x2,0,0 = 1
_C2: x0,0,1 + x1,0,1 + x2,0,1 = 1
_C3: x0,1,0 + x1,1,0 + x2,1,0 = 1
_C4: x0,1,1 + x1,1,1 + x2,1,1 = 1
_C5: x0,2,0 + x1,2,0 + x2,2,0 = 1
_C6: x0,2,1 + x1,2,1 + x2,2,1 = 1
_C7: x0,1,0 + x0,1,1 + x0,2,0 + x0,2,1 <= 1
_C8: x1,1,0 + x1,1,1 + x1,2,0 + x1,2,1 <= 1
_C9: x2,1,0 + x2,1,1 + x2,2,0 + x2,2,1 <= 1
_C10: x0,0,0 + x0,1,0 + x0,2,0 <= 1
_C11: x0,0,0 + x0,0,1 + x0,1,0 + x0,1,1 + x0,2,0 + x0,2,1 <= 1
VARIABLES
0 <= x0,0,0 <= 1 Integer
0 <= x0,0,1 <= 1 Integer
0 <= x0,1,0 <= 1 Integer
0 <= x0,1,1 <= 1 Integer
0 <= x0,2,0 <= 1 Integer
0 <= x0,2,1 <= 1 Integer
0 <= x1,0,0 <= 1 Integer
0 <= x1,0,1 <= 1 Integer
0 <= x1,1,0 <= 1 Integer
0 <= x1,1,1 <= 1 Integer
0 <= x1,2,0 <= 1 Integer
0 <= x1,2,1 <= 1 Integer
0 <= x2,0,0 <= 1 Integer
0 <= x2,0,1 <= 1 Integer
0 <= x2,1,0 <= 1 Integer
0 <= x2,1,1 <= 1 Integer
0 <= x2,2,0 <= 1 Integer
0 <= x2,2,1 <= 1 Integer
It can clearly be observed that all variables are restricted to be an integer between 0 and 1 (thus binary). However, for some reason, I do get negative values for some variable(s), as can be seen below
x0,0,0 = 0.0
x0,0,1 = -1.0
x0,1,0 = 0.0
x0,1,1 = 1.0
x0,2,0 = 0.0
x0,2,1 = 1.0
x1,0,0 = 1.0
x1,0,1 = 1.0
x1,1,0 = 1.0
x1,1,1 = 0.0
x1,2,0 = 0.0
x1,2,1 = 0.0
x2,0,0 = 0.0
x2,0,1 = 1.0
x2,1,0 = 0.0
x2,1,1 = 0.0
x2,2,0 = 1.0
x2,2,1 = 0.0
objective= 11.159
Really looking forward to any suggestions on how to solve this problem, since I clearly do not want negative values!
As a few others have suggested you should write a Minimum Complete and Verifiable Example.
That said, if you are getting constraints violated, and you are sure you've implemented them correctly, I reckon you have an infeasible problem (i.e. if you looked at your constraints carefully you would find there is a combination which makes solving impossible).
To check this add:
print (("Status:"), LpStatus[prob.status])
Just after you do prob.solve(). I reckon you'll find it's infeasible.
prob += nr == 1
"+=" is for assignment
"==" is checking for equivalence, and belongs in an "if" statement or a "while".
For instance:
if prob + nr == 1: #execute what follows if prob + nr is equal to 1
I have been trying to implement the Baillie-PSW primality test for a few days, and have ran into some problems. Sepcifically when trying to use the Lucas probable prime test. My question is not about Baile, but on how to generate the correct Lucas sequence modulo some number
For the first two psudoprimes my code gives the correct result, eg for 323 and 377. However for the next psudoprime, both the standard implementation and the doubling version fails.
Trying to do modulo operations on V_1 completely breaks the doubling version of the Luckas sequence generator.
Any tips or suggestions on how to correctly implement the Lucas probable prime test in Python?
from fractions import gcd
from math import log
def luckas_sequence_standard(num, D=0):
if D == 0:
D = smallest_D(num)
P = 1
Q = (1-D)/4
V0 = 2
V1 = P
U0 = 0
U1 = 1
for _ in range(num):
U2 = (P*U1 - Q*U0) % num
U1, U0 = U2, U1
V2 = (P*V1 - Q*V0) % num
V1, V0 = V2, V1
return U2%num, V2%num
def luckas_sequence_doubling(num, D=0):
if D == 0:
D = smallest_D(num)
P = 1
Q = (1 - D)/4
V0 = P
U0 = 1
temp_num = num + 1
double = []
while temp_num > 1:
if temp_num % 2 == 0:
double.append(True)
temp_num //= 2
else:
double.append(False)
temp_num += -1
k = 1
double.reverse()
for is_double in double:
if is_double:
U1 = (U0*V0) % num
V1 = V0**2 - 2*Q**k
U0 = U1
V0 = V1
k *= 2
elif not is_double:
U1 = ((P*U0 + V0)/2) % num
V1 = (D*U0 + P*V0)/2
U0 = U1
V0 = V1
k += 1
return U1%num, V1%num
def jacobi(a, m):
if a in [0, 1]:
return a
elif gcd(a, m) != 1:
return 0
elif a == 2:
if m % 8 in [3, 5]:
return -1
elif m % 8 in [1, 7]:
return 1
if a % 2 == 0:
return jacobi(2,m)*jacobi(a/2, m)
elif a >= m or a < 0:
return jacobi(a % m, m)
elif a % 4 == 3 and m % 4 == 3:
return -jacobi(m, a)
return jacobi(m, a)
def smallest_D(num):
D = 5
k = 1
while k > 0 and jacobi(k*D, num) != -1:
D += 2
k *= -1
return k*D
if __name__ == '__main__':
print luckas_sequence_standard(323)
print luckas_sequence_doubling(323)
print
print luckas_sequence_standard(377)
print luckas_sequence_doubling(377)
print
print luckas_sequence_standard(1159)
print luckas_sequence_doubling(1159)
Here is my Lucas pseudoprimality test; you can run it at ideone.com/57Iayq.
# lucas pseudoprimality test
def gcd(a,b): # euclid's algorithm
if b == 0: return a
return gcd(b, a%b)
def jacobi(a, m):
# assumes a an integer and
# m an odd positive integer
a, t = a % m, 1
while a <> 0:
z = -1 if m % 8 in [3,5] else 1
while a % 2 == 0:
a, t = a / 2, t * z
if a%4 == 3 and m%4 == 3: t = -t
a, m = m % a, a
return t if m == 1 else 0
def selfridge(n):
d, s = 5, 1
while True:
ds = d * s
if gcd(ds, n) > 1:
return ds, 0, 0
if jacobi(ds, n) == -1:
return ds, 1, (1 - ds) / 4
d, s = d + 2, s * -1
def lucasPQ(p, q, m, n):
# nth element of lucas sequence with
# parameters p and q (mod m); ignore
# modulus operation when m is zero
def mod(x):
if m == 0: return x
return x % m
def half(x):
if x % 2 == 1: x = x + m
return mod(x / 2)
un, vn, qn = 1, p, q
u = 0 if n % 2 == 0 else 1
v = 2 if n % 2 == 0 else p
k = 1 if n % 2 == 0 else q
n, d = n // 2, p * p - 4 * q
while n > 0:
u2 = mod(un * vn)
v2 = mod(vn * vn - 2 * qn)
q2 = mod(qn * qn)
n2 = n // 2
if n % 2 == 1:
uu = half(u * v2 + u2 * v)
vv = half(v * v2 + d * u * u2)
u, v, k = uu, vv, k * q2
un, vn, qn, n = u2, v2, q2, n2
return u, v, k
def isLucasPseudoprime(n):
d, p, q = selfridge(n)
if p == 0: return n == d
u, v, k = lucasPQ(p, q, n, n+1)
return u == 0
print isLucasPseudoprime(1159)
Note that 1159 is a known Lucas pseudoprime (A217120).
I'm solving my way through Euler project. I have reached question 84 and I have created a simulation of the game. I have run the simulation against the statistic provided in the question and I get the right sequence. When I try to run this with 2d4 I get wrong results. Usually I get 101516. What am I missing?
Please note, I'm not looking for the solution or for you to fix my code. I only want to know where my algorithm is flawed.
from random import randint
import sys
pos = 0
doubles = 0
csqs = [2,17,33] #The cc position
hsqs = [7,22,36] #The ch positions
rounds = 0
stop = 100000
sqs = dict() #will store how many visit I had on each square
for i in range (0,40): #initial values of sqs
sqs[i] = 0
def doCC():# the cc cards. There is no real effect of randomly picking a card or kipping them in order on my result
global pos,doubles
global CC
if CC == 0:
pos = 0
elif CC == 1:
pos = 10
doubles = 0
CC += 1
if CC == 16: CC = 0
def doCH(): #CH cards
global pos, doubles, CH
if CH == 0: pos = 0
elif CH == 1:
pos = 10
doubles = 0
elif CH == 2: pos = 11
elif CH == 3: pos = 24
elif CH == 4: pos = 39
elif CH == 5: pos = 5
elif CH == 6 or CH == 7:
if pos == 7:
pos = 15
elif pos == 22:
pos = 25
elif pos == 36:
pos = 5
elif CH ==8:
if pos == 22: pos = 28
else: pos = 12
elif CH == 9:
pos -= 3
CH += 1
if CH == 16: CH = 0
while rounds < stop:
d1 = randint(1,4)
d2 = randint(1,4)
if d1 == d2:
doubles += 1 #counting doubles
else:
doubles = 0
if doubles == 3:
pos = 10
doubles = 0
pos += d1+d2
if pos>= 40 : #you have just crossed go
pos -= 40
rounds += 1
if rounds %10000 == 0: print rounds,
if pos == 30: #g2j
doubles = 0
pos = 10
if pos in hsqs:
doCH()
if pos in csqs:
doCC()
sqs[pos] += 1
sys.stdout.flush()
# Setting values
m1 = 0
m2 = 0
m3 = 0
v1 = 0
v2 = 0
v3 = 0
su = 0
for v in sqs:
m = sqs[v]
su += m
if m > m1:
m1 = m
v1 = v
for v in sqs:
m = sqs[v]
if m > m2 and m < m1:
m2 = m
v2 = v
for v in sqs:
m = sqs[v]
if m > m3 and m < m2:
m3 = m
v3 = v
for v in sqs:
sqs[v] = sqs[v]*100.0/su
print m1,m2,m3
print v1,v2,v3
print m1*100.0/su, m2*100.0/su, m3*100.0/su
print sqs
When you have three doubles in a row,
if doubles == 3:
pos = 10
doubles = 0
pos += d1+d2
you still hop out of jail, but you shouldn't.