Got error when using the variable as the index for accessing another new variable
AnsweredIt seems that I use the variable as the index for accessing another new variable. But I don't know how to solve it. Thanks for your help.
import gurobipy as gb
MODEL = gb.Model()
e1 = MODEL.addVar(vtype=gb.GRB.BINARY, name="e_i_1")
e2 = MODEL.addVar(vtype=gb.GRB.BINARY, name="e_i_2")
e3 = MODEL.addVar(vtype=gb.GRB.BINARY, name="e_i_3")
e_i = MODEL.addVar(vtype=gb.GRB.INTEGER, name="e_i")
b = MODEL.addVars(8, vtype=gb.GRB.CONTINUOUS, name="b")
MODEL.addConstr(e1 + e2 + e3 == 1)
MODEL.addConstr(e_i == 2 * e1 + 4 * e2 + 7 * e3)
# e_i could be 2,4 or 7, by having e1=1, e2=1 or e3=1
# error when I put e_i as index of variable b
# gurobipy.GurobiError: Variable has not yet been added to the model
MODEL.addConstr(b[e_i] == gb.max_([b[k] for k in range(0, 8)]))
for m in range(0, 8):
MODEL.addConstr(b[m] == b[e_i] - 15 * gb.abs_(m - e_i))
-
Hi Qiru,
The error “gurobipy.GurobiError: Variable has not yet been added to the model” happens due to Gurobi’s lazy update approach, precisely when we try to access and use a variable before updating the model. In your case, this error is happening because you are trying to use the variable e_i before updating the model.
Please note that a variable cannot be used as an index for another variable or parameter in a gurobi model.
However, for your model, you can work around this by replacing the following constraints:
MODEL.addConstr(e_i == 2 * e1 + 4 * e2 + 7 * e3)
MODEL.addConstr(b[e_i] == gb.max_([b[k] for k in range(0, 8)]))
for m in range(0, 8):
MODEL.addConstr(b[m] == b[e_i] - 15 * gb.abs_(m - e_i))with the constraint:
MODEL.addConstr( b[2]*e1 + b[4]*e2 + b[7]*e3 == gb.max_([b[k] for k in range(0, 8)]) )
The above constraint captures the correct value of b[k] based on which of e1, e2, or e3 is non-zero, and sets it to the maximum of b[k] for k in range(0, 8). For example, if e1=1 and e2=e3=0, the above constraint will reduce to b[2] = gb.max_([b[k] for k in range(0, 8).
Regards,
Simran
0 -
Hi Simranjit,
Thanks for your reply. I consider this transformation brilliant. However, when I modify the code and rerun it, the following error occurs:
MODEL.addConstr(b[2]*e1 + b[4]*e2 + b[7]*e3 == gb.max_([b[k] for k in range(0, 8)]) )
File "src/gurobipy/model.pxi", line 3616, in gurobipy.Model.addConstr
gurobipy.GurobiError: General expressions can only be equal to a single varBelow is the modified code.
Could you please give a further suggestion?
import gurobipy as gb
MODEL = gb.Model()
e1 = MODEL.addVar(vtype=gb.GRB.BINARY, name="e_i_1")
e2 = MODEL.addVar(vtype=gb.GRB.BINARY, name="e_i_2")
e3 = MODEL.addVar(vtype=gb.GRB.BINARY, name="e_i_3")
e_i = MODEL.addVar(vtype=gb.GRB.INTEGER, name="e_i")
b = MODEL.addVars(8, vtype=gb.GRB.CONTINUOUS, name="b")
MODEL.addConstr(e_i == 2 * e1 + 4 * e2 + 7 * e3)
MODEL.addConstr(e1 + e2 + e3 == 1)
# e_i could be 2,4 or 7, by having e1=1, e2=1 or e3=1
MODEL.addConstr(b[2]*e1 + b[4]*e2 + b[7]*e3 == gb.max_([b[k] for k in range(0, 8)]) )
for m in range(0, 8):
MODEL.addConstr(b[m] == b[2]*e1 + b[4]*e2 + b[7]*e3 - 15 * gb.abs_(m - e_i))
MODEL.update()0 -
Hi Qiru,
Please introduce an auxiliary variable y, and replace the constraint
MODEL.addConstr(b[2]*e1 + b[4]*e2 + b[7]*e3 == gb.max_([b[k] for k in range(0, 8)]) )
with the following
y = MODEL.addVar(vtype=gb.GRB.CONTINUOUS, name="y")
MODEL.addConstr( y == b[2]*e1 + b[4]*e2 + b[7]*e3 )
MODEL.addConstr( y == gb.max_([b[k] for k in range(0, 8)]) )This should fix the error you mentioned.
Also, please note that the following constraints are redundant and can be removed from your model, as we have already stored the correct b[k] value in the "y" variable based on the non-zero value of e1, e2 and e3.
for m in range(0, 8): MODEL.addConstr(b[m] == b[2]*e1 + b[4]*e2 + b[7]*e3 - 15 * gb.abs_(m - e_i))
Regards,
Simran
0 -
Hi Simranjit,
Problem solved.
As a novice for Gurobi, I appreciate your help.
Best,
Qiru
0
Please sign in to leave a comment.
Comments
4 comments