# Using logical constraints with gurobi

Hi,
I’m trying to use logical constraints on JuMP, ex:
x5 = x1 AND x3 AND x4

In the doc of gurobi, there is a function that directly construct this constraint without having to linearize it manually :

Is there an equivalent way when using Gurobi on JuMP ?
thank you

Welcome to the forum!

The general way to do this at the model level is described in the Mosek Cookbook (it’s just about the maths, not specific to the Mosek solver).

The JuMP model would look like

``````using JuMP
import Gurobi

n = 3  # number of "AND" terms

model = Model(Gurobi.Optimizer)
@variable(model, x[1:n], Bin)
@variable(model, z, Bin) # z is x[1] AND ... AND x[n]
@constraint(model, [i=1:n], x[i] >= z)
@constraint(model, z + (n-1)  >= sum(x))
``````

Test it with:

``````julia> @objective(model, Max, sum(x))
julia> optimize!(model)
julia> value.(x)
3-element Vector{Float64}:
1.0
1.0
1.0

julia> value.(z)
1.0

julia> fix(x[3], 0)

julia> value.(x)
3-element Vector{Float64}:
1.0
1.0
0.0

julia> @objective(model, Max, sum(x))
julia> value.(z)
0.0
``````

@raian you can also consider using DisjunctiveProgramming.jl:

``````using DisjunctiveProgramming
using Gurobi

model = GDPModel(Gurobi.Optimizer)
@variable(model, x[1:5], Logical)
@constraint(model, x[5] == (x[1] && x[3] && x[4]) := true)
optimize!(model)
print(model)

Feasibility
Subject to
x[4] - x[5] ≥ 0
x[3] - x[5] ≥ 0
-x[1] - x[3] - x[4] + x[5] ≥ -2
x[1] - x[5] ≥ 0
x[1] binary
x[2] binary
x[3] binary
x[4] binary
x[5] binary
``````

The way this works is:

• x[1:5] is a vector of `LogicalVariable`
• you can then define logical propositions using Boolean algebra (unicode operators supported too)
• you can then either call `reformulate_model` to transform the logical model into a MIP. Alternately, you can leave all the logical constraints and call `optimize!(model)`, the model will be reformulated in the background by transforming the logical constraints into algebraic constraints with binary variables.

Note, the transformation creates binary variables from the logical variables and adds the 3 algebraic constraints @jd-foster gave above. The extra constraint `x[1] + x[3] + x[4] - x[5] <= 2` forces the reverse implication on `x[5]`. Without it, the constraint being added is `x5 implies x1 AND x3 AND x4` (instead of `x5 iff x1 AND x3 AND x4`).

Note: the code above works on `master`.

1 Like

Hi @raian,

You can also use Gurobi’s C API for this: GitHub - jump-dev/Gurobi.jl: Julia interface for Gurobi Optimizer

I didn’t test, but something like this should work:

``````using JuMP, Gurobi
model = direct_model(Gurobi.Optimizer())
@variable(model, x[1:5])
grb = backend(model)
c_cols = Gurobi.c_column.(grb, index.(x))
GRBaddgenconstrAnd(grb, "andconstr", c_cols[5], 3, c_cols[[1, 3, 4]])
``````
2 Likes