About Divisor must be a constant in iteration
OngoingHi,
- MAX ∑ -1 * L [ k, j ] * L [ k, j ]
- L [ k, j ] = norm(q [ j ] - s [ k ])
- MAX ∑ -1 * L [ k, j ] * L [ k, j ] / dc [ j ] ** 4
- L [ k, j ] = norm(q [ j ] - s [ k ])

def gurobi_demo(qc):
model = grb.Model('')
s = np.array([[-250, -250, 0], [-250, 250, 0], [250, -250, 0], [250, 250, 0]])
q = model.addVars(4, 3, lb=-500, vtype=GRB.CONTINUOUS, name='q')
term2 = model.addVars(4, 4, vtype=GRB.CONTINUOUS, name='term2')
l = model.addVars(4, 4, vtype=GRB.CONTINUOUS, name='l')
model.update()
sum = LinExpr()
for k in range(4):
for j in range(4):
term2[k, j] = -1 * (l[k, j] * l[k, j])
sum += term2[k, j]
model.setObjective(sum, sense=GRB.MAXIMIZE)
for k in range(4):
model.addConstr(q[k, 2] == 100)
model.addConstr(q[k, 0] <= 500)
model.addConstr(q[k, 0] >= -500)
model.addConstr(q[k, 1] <= 500)
model.addConstr(q[k, 1] >= -500)
# np.linalg.norm(q[j] - s[k])
for k in range(4):
for j in range(4):
rhs = QuadExpr()
for i in range(3):
rhs += q[j, i] * q[j, i] - 2 * s[k][i] * q[j, i]
model.addConstr(l[k, j] * l[k, j] == rhs + s[k][0] ** 2 + s[k][1] ** 2 + s[k][2] ** 2)
model.setParam('NonConvex', 2)
model.optimize()
for v in model.getVars():
print('var name is {}, var value is {}'.format(v.VarName, v.X))
return [[q[i, j].X for j in range(3)] for i in range(4)]
def main():
qc = [[[0 for j in range(3)] for i in range(4)]]
while True:
qc.append(gurobi_demo(qc[-1]))
print(qc)
def gurobi_fixp_q_sca(qc):
model = grb.Model('')
s = np.array([[-250, -250, 0], [-250, 250, 0], [250, -250, 0], [250, 250, 0]])
q = model.addVars(4, 3, lb=-500, vtype=GRB.CONTINUOUS, name='q')
term2 = model.addVars(4, 4, vtype=GRB.CONTINUOUS, name='term2')
l = model.addVars(4, 4, vtype=GRB.CONTINUOUS, name='l')
dc = np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])
for k in range(4):
for j in range(4):
dc[k, j] = np.linalg.norm(qc[j] - s[k])
model.update()
sum = LinExpr()
for k in range(4):
for j in range(4):
term2[k, j] = -1 * (l[k, j] * l[k, j]) / ((dc[k, j] ** 3) * dc[k, j])
sum += term2[k, j]
model.setObjective(sum, sense=GRB.MAXIMIZE)
for k in range(4):
model.addConstr(q[k, 2] == 100)
# model.addConstr(q[k, 2] <= 300)
model.addConstr(q[k, 0] <= 500)
model.addConstr(q[k, 0] >= -500)
model.addConstr(q[k, 1] <= 500)
model.addConstr(q[k, 1] >= -500)
# np.linalg.norm(q[j] - s[k])
for k in range(4):
for j in range(4):
rhs = QuadExpr()
for i in range(3):
rhs += q[j, i] * q[j, i] - 2 * s[k][i] * q[j, i]
model.addConstr(l[k, j] * l[k, j] == rhs + s[k][0] ** 2 + s[k][1] ** 2 + s[k][2] ** 2)
model.setParam('NonConvex', 2)
model.optimize()
for v in model.getVars():
print('var name is {}, var value is {}'.format(v.VarName, v.X))
return [[q[i, j].X for j in range(3)] for i in range(4)]
def main():
qc = [[[0 for j in range(3)] for i in range(4)]]
while True:
qc.append(gurobi_demo(qc[-1]))
print(qc)
It is worth mentioning that this error message appears after several iterations.
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Can you try printing out the value of \( \texttt{dc[k, j]} \) immediately before the line where the error occurs? I would guess that you receive this error because \( \texttt{dc[k, j]} \) is \( 0 \), which can't be used as a divisor.
0 -
Hi Eli Towle,
First of all, thank you for your reply. I originally thought it was possible that 0 was in the denominator during the iteration. But, by outputting the dc in each optimization process, I find that the dc in the wrong iteration is not the item of 0. This is the error message and the dc of the iteration where the error occurred. dc is [[524,524...], ...].
Yanbo
0 -
I haven't been able to reproduce the error with your code. Could you please try adding the following print statement immediately before the line where you set \( \texttt{term2[k, j]} \) equal to \( \texttt{-1 * (l[k, j] * l[k, j]) / ((dc[k, j] ** 3) * dc[k, j])} \), then post the output you see when the error is thrown?
print(f'dc[{k},{j}]={dc[k,j]} {type(dc[k,j])}')
Also, did you cut off part of the error message? It would be helpful to see the full error traceback (the red text), which should be longer than the three lines you posted.
Two comments about the code:
- \( \texttt{term2} \) does not need to be defined as a set of model variables. It is only used in the code to temporarily store a QuadExpr object.
- Consider a \( \texttt{dc} \) value of \( 524 \). Your objective includes the quadratic coefficient \( 1 / 524^4 \), which is approximately \( 10^{-11} \). This is much smaller than Gurobi's default feasibility tolerance of \( 10^{-6} \). As a result, Gurobi may not handle such small coefficients the way you expect.
0 -
Hi Eli Towle,
I'm very moved to see your detailed reply. I'm sorry for the error message I can't describe clearly before.
First of all, this is the code that can show my complete error message. You can try it again.
def gurobi_demo(qc):
model = grb.Model('')
s = np.array([[-250, -250, 0], [-250, 250, 0], [250, -250, 0], [250, 250, 0]])
q = model.addVars(4, 3, lb=-500, vtype=GRB.CONTINUOUS, name='q')
term2 = model.addVars(4, 4, vtype=GRB.CONTINUOUS, name='term2')
l = model.addVars(4, 4, vtype=GRB.CONTINUOUS, name='l')
dc = np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])
for k in range(4):
for j in range(4):
dc[k, j] = np.linalg.norm(qc[j] - s[k])
model.update()
sum = LinExpr()
for k in range(4):
for j in range(4):
print(f'dc[{k},{j}]={dc[k, j]} {type(dc[k, j])}')
term2[k, j] = -1 * (l[k, j] * l[k, j]) / ((dc[k, j] ** 3) * dc[k, j])
sum += term2[k, j]
model.setObjective(sum, sense=GRB.MAXIMIZE)
for k in range(4):
model.addConstr(q[k, 2] == 100)
# model.addConstr(q[k, 2] <= 300)
model.addConstr(q[k, 0] <= 500)
model.addConstr(q[k, 0] >= -500)
model.addConstr(q[k, 1] <= 500)
model.addConstr(q[k, 1] >= -500)
# np.linalg.norm(q[j] - s[k])
for k in range(4):
for j in range(4):
rhs = QuadExpr()
for i in range(3):
rhs += q[j, i] * q[j, i] - 2 * s[k][i] * q[j, i]
model.addConstr(l[k, j] * l[k, j] == rhs + s[k][0] ** 2 + s[k][1] ** 2 + s[k][2] ** 2)
model.setParam('NonConvex', 2)
model.optimize()
for v in model.getVars():
print('var name is {}, var value is {}'.format(v.VarName, v.X))
return [[q[i, j].X for j in range(3)] for i in range(4)]def main():
qc = [[[0 for j in range(3)] for i in range(4)]]
while True:
qc.append(gurobi_demo(qc[-1]))
print(qc)
What' s more, This is the complete error message (the red text).This is the output I see when solver throws an error after adding
print(f'dc[{k},{j}]={dc[k,j]} {type(dc[k,j])}')
The last, about the problem which the dc is much smaller than Gurobi's default feasibility tolerance of 10−6. If the actual problem is that dc needs to be such a small value, how will this problem be solved? I don't know how to deal with such a problem when using gurobi.
Best regards,
Yanbo
0 -
I could reproduce this on a Windows machine. The error is related to the \( \texttt{numpy.int32} \) data type. 32-bit integers can only store values up to ~2 billion:
>>> np.iinfo(np.int32)
iinfo(min=-2147483648, max=2147483647, dtype=int32)You will get strange results when trying to store numbers larger than this with a \( \texttt{numpy.int32} \) data type. This is where the \( \texttt{ZeroDivisionError} \) comes from:
>>> np.int32(256)**4
0
>>> np.int32(512)**4
0To resolve the issue, you could try using 64-bit integers to represent the numbers stored in \( \texttt{dc} \):
dc = np.array(..., dtype=np.int64)
But because your objective function contains such small coefficients, you may still get some unexpected results from the solver. If this happens, you could try reformulating the model so it does not include such small objective coefficients. Alternatively, try using the ObjScale parameter to scale the objective function differently.
0 -
Hi Eli Towle,
After reading the introduction of tolerance, I think it is the reason why dc * * 4 can not obtain the model solution because it exceeds gurobi or machine accuracy in the calculation process. So I enlarged the calculation of dc by adding the following code.
dc[k, j] = np.linalg.norm(qc[j] - s[k]) / 100
Although I changed the original model, I found the optimal solution. Do you think changing only constants has a great impact on the actual meaning of the model or the whole optimization problem?
Best regards,
Yanbo
0 -
When you divide each \( \texttt{dc} \) value by \( 100 \), you are effectively multiplying the entire objective function by \( 10^8 \). Such a scaling does not change the optimal solution(s), though it may affect how reliably solvers like Gurobi can solve the model.
0 -
Hi Eli Towle,
Okey, I understand your explanation. The last problem, In the calculation, I calculate log (1 + A), A is controlled by the decision variable, and the value of A is bigger than zero and far less than 1, in other words, 0 < a < < 1.
Then, Gurobi will judge as 1 + A == 1. Facing this problem, how can I ensure the computational performance and obtain the optimal solution. The values corresponding to the relevant codes and variables are as follows.
#Term3 is much less than 1
model.addConstr(term3[k] >= grb.quicksum(zs[k, j] for j in range(K) if j != k))
model.addConstr(term4[k] == term3[k] + 1)#In fact, term4 is not equal to 1
model.addGenConstrLogA(term4[k], lv[k], 2, "log2")0 -
Hi Eli Towle,
When I set the parameter NumericFocus to 2, the above problem can be solved accurately. Maybe it only has some impact on the computational performance.
Best regards,
Yanbo
0
Post is closed for comments.
Comments
10 comments