Conditional statement in Gurobi
AnsweredSuppose I have four variables a,b,c,d with vtype = INTEGER
minimize: |a-15| + |b-16| + |c-18| + |d-17|
Constraint:
if c-d == -1, then b-a >= 1
some more constraints
Is it possible to model the conditional contraint in gurobi with python interface?
Thanks for any help
-
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?. -
Gurobi supports indicator constraints, which allow you to add constraints of the form
$$(\textrm{binary variable} = 0 \textrm{ or } 1) \implies (\textrm{some linear constraint}).$$
So, we only need to figure out how to rewrite the conditional constraint using constraints of this form. Our goal is to model:
$$c - d = -1 \implies b - a \geq 1.$$
We first introduce a binary variable \( z \). The above implication is equivalent to the following:
$$\begin{align*}c - d = -1 &\implies z = 1 \\ z = 1 &\implies b - a \geq 1\end{align*}$$
\( (z = 1) \implies (b - a \geq 1) \) matches the requisite indicator constraint form, but \( (c - d = -1) \implies (z = 1) \) does not. Let's try to rewrite the latter in Gurobi's indicator constraint form. The implication is logically equivalent to
$$z = 0 \implies c - d \neq -1.$$
Because \( c \) and \( d \) are integers, this is equivalent to
$$z = 0 \implies |c - d + 1| \geq 1,$$
or, after introducing auxiliary variables \( u \) and \( y \):
$$\begin{align*}u &= c - d + 1 \\ y &= |u| \\ z &= 0 \implies y \geq 1. \end{align*}$$
\( (z = 0) \implies (y \geq 1) \) matches the desired indicator constraint form. Altogether, we have shown the original conditional constraint is equivalent to the following:
$$\begin{align*}u &= c - d + 1 \\ y &= |u| \\ z &= 0 \implies y \geq 1 \\ z &= 1 \implies b - a \geq 1.\end{align*}$$
In Gurobi's Python interface, we can model these four constraints using the aforementioned indicator constraints and the absolute value helper function:
import gurobipy as gp
from gurobipy import GRB
# create model m and add variables a, b, c, and d here
# auxiliary variables
u = m.addVar(lb=-GRB.INFINITY, name='u')
y = m.addVar(name='y')
z = m.addVar(vtype=GRB.BINARY, name='z')
# y == |c - d + 1|
m.addConstr(u == c - d + 1)
m.addConstr(y == gp.abs_(u))
# (c - d == -1) => (b - a >= 1)
m.addConstr((z == 0) >> (y >= 1))
m.addConstr((z == 1) >> (b - a >= 1))1 -
Hi, I have the same problem but the logic is a bit different. I want to model:
if I - safety stock >= 0 then X = 1; otherwise X = 0
I have the code as follows but I am not sure if this is correct:
#variables
Z = LP.addVars(months, items, vtype = GRB.BINARY, name = "Z")
U = LP.addVars(months, items, lb = - GRB.INFINITY, name = "U")
L = LP.addVars(months, items, name = "L")
#constraints
Constraint4 = LP.addConstrs(U[months[a], item] == I[months[a], item] - safety_stock[item]
for item in items)
Constraint5 = LP.addConstrs(L[months[a],item] == gp.abs_(U[months[a],item]) for item in items)
Constraint6 = LP.addConstrs((Z[months[a],item] == 0) >> (L[months[a],item] >= 0) for item in items)
Constraint7 = LP.addConstrs((Z[months[a],item] == 1) >> (X[months[a],item] == 1) for item in items)0 -
Continued in conditional constraint in Gurobi.
0
Post is closed for comments.
Comments
4 comments