• Gurobi Staff

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 gpfrom gurobipy import GRB# create model m and add variables a, b, c, and d here# auxiliary variablesu = 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))

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:

#variablesZ = 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")#constraintsConstraint4 = 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)

• Gurobi Staff

Continued in conditional constraint in Gurobi.