Skip to main content

Conditional statement in Gurobi

Answered

Comments

3 comments

  • Eli Towle
    Gurobi Staff 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 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
  • Maryam Azani
    Gurobi-versary
    First Comment
    First Question

    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
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Continued in conditional constraint in Gurobi.

    0

Please sign in to leave a comment.