Problem with logical constraint using addGenConstrIndicator()
AnsweredHi,
I want the "finish" variable to be 1 when "beet_flow" is 0. However, when my checking output I get 0 for all values of finish. I should get values of 1 for the given time periods and i's. Below I post a test set to replicate the problem and I post my Python output. I appreciate any help. Thank you!
Code:
from gurobipy import Model, GRB
# Define the sets I and T
I = [1, 2]
T = [0, 1, 2, 3, 4]
# Create a new Gurobi model
model = Model("test_model")
# Define variables
beet_flow = model.addVars(I, range(1), range(1), T, vtype=GRB.CONTINUOUS, name="b")
finish = model.addVars(I, T, vtype=GRB.BINARY, name="finish")
# Set artificial beet values
model.addConstr(beet_flow[1, 0, 0, 0] == 1500)
model.addConstr(beet_flow[1, 0, 0, 1] == 500)
model.addConstr(beet_flow[1, 0, 0, 2] == 0)
model.addConstr(beet_flow[1, 0, 0, 3] == 0)
model.addConstr(beet_flow[1, 0, 0, 4] == 0)
model.addConstr(beet_flow[2, 0, 0, 0] == 1500)
model.addConstr(beet_flow[2, 0, 0, 1] == 500)
model.addConstr(beet_flow[2, 0, 0, 2] == 200)
model.addConstr(beet_flow[2, 0, 0, 3] == 0)
model.addConstr(beet_flow[2, 0, 0, 4] == 0)
# Ensure the 'finish' variable is 1 when beets are 0 using indicator constraints
for i in I:
for t in T:
model.addGenConstrIndicator(finish[i, t], 1, beet_flow[i, 0, 0, t] == 0)
# Optimize the model
model.optimize()
# Check and print the results
if model.status == GRB.OPTIMAL:
for i in I:
for t in T:
print(f"finish[{i},{t}] = {finish[i, t].x}")
print(f"Beets [{i}, {t}]: {beet_flow[i,0,0,t].x}")
Output:
Optimize a model with 10 rows, 30 columns and 10 nonzeros
Model fingerprint: 0xe8ba07b5
Model has 10 general constraints
Variable types: 10 continuous, 20 integer (20 binary)
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [0e+00, 0e+00]
Bounds range [1e+00, 1e+00]
RHS range [2e+02, 2e+03]
GenCon coe range [1e+00, 1e+00]
Presolve removed 10 rows and 30 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)
Thread count was 1 (of 8 available processors)
Solution count 1: 0
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%
finish[1,0] = 0.0
Beets [1, 0]: 1500.0
finish[1,1] = 0.0
Beets [1, 1]: 500.0
finish[1,2] = 0.0
Beets [1, 2]: 0.0
finish[1,3] = 0.0
Beets [1, 3]: 0.0
finish[1,4] = 0.0
Beets [1, 4]: 0.0
finish[2,0] = 0.0
Beets [2, 0]: 1500.0
finish[2,1] = 0.0
Beets [2, 1]: 500.0
finish[2,2] = 0.0
Beets [2, 2]: 200.0
finish[2,3] = 0.0
Beets [2, 3]: 0.0
finish[2,4] = 0.0
Beets [2, 4]: 0.0
Process finished with exit code 0
-
Hi Ludwig,
In your code, you have modeled
if "finish"=1 then "beet_flow"=0,
This relation does not restrict "beet_flow" in case "finish" has the value 0. So, you can have both 0.
You probably want to define the constraint asmodel.addGenConstrIndicator(finish[i, t], 0, beet_flow[i, 0, 0, t] >= 1e-7)
Here, the finish variable cannot take the value 0 if the beet_flow variable is 0 and must then be 1. Note that strict inequalities are not possible (Why doesn't Gurobi support strict inequality constraints like x < a?). That is why I used >= 1e-7 instead of >0. Furthermore, it is used that the LB of the beet_flow variables is 0.
Best regards,
Marika0 -
Hi Marika,
thank you very much for your response. It helped me fix the problem. Actually, I needed to add both constraints to create the correct indicator. Without the second other one I would get ones for all values.
for i in I:
for t in T:
model.addGenConstrIndicator(finish[i, t], 0, beet_flow[i, 0, 0, t] >= 1e-7)
for i in I:
for t in T:
model.addGenConstrIndicator(finish[i, t], 1, beet_flow[i, 0, 0, t] <= 1e-7)Thank you for your help!
Best regards,
Ludwig
0
Please sign in to leave a comment.
Comments
2 comments