Syntax for indicator constraints

I have a model with two constraints. The first constraint is a big M constraint, which I am trying to reformulate as an indictor constraint. I have tried to follow the syntax given in the documentation, but I don’t get a correct answer when I use indicator constraints. How can I write this using indicator constraints?

model = Model()
@variable(model,x[b=1:4]>=0)
@variable(model,y[b=1:4],Bin)
@variable(model,a >= 0.0)
M = 1000
@constraint(model,constraint1[j in 1:4], M*y[j]-sum(l[j,i]*x[i] for i in 1:4) + a >= 0) # l is a matrix containing data
@constraint(model,constraint2, sum(y[j] for j in 1:4) <= 2)
# Attempt 1. Use variable y as indicator constraint in constraint1. No changes to constraint2
@constraint(model,constraint1[j in 1:4], y[j] => {- sum(l[j,i]*x[i] for i in 1:4) + a >= 0})
@constraint(model,constraint2, sum(y[j] for j in 1:4) <= 2)

# Attempt 2 Define another variable z for indicator. No changes to constraint2
@variable(model,z[b=1:4],Bin)
@constraint(model,constraint1[j in 1:4], z[j] => {y[j] - sum(l[j,i]*x[i] for i in 1:4) + a >= 0})
@constraint(model,constraint2, sum(y[j] for j in 1:4) <= 2)

Hi John, Can you be more specific about what is incorrect? Is there an error, or a result that doesn’t satisfy your requirements? What solver are you using?

1 Like

In your first model, the constraint is active when y[j] == 0, and ignored when y[j] == 1.

In contrast, your indicator constraints are active when y[j] == 1.

Per the documentation, Constraints · JuMP, use !y[j] => {} to activate the indicator constraint on y[j] == 0.

1 Like

I am using Cbc solver. The log shows the problem as unbounded.

I have tried that as well, but still it shows the problem unbounded. I have given a complete example below.

function run_func(n_x,num)
	l = -float(rand(30:100,num,n_x)) .+ float(rand(80:140,1,n_x))
    n_sim = size(l,1)
    n_x = size(l,2)
	M = 1000
    m = Model(Cbc.Optimizer)
    @variable(m,x[b=1:n_x]>=0)
    @variable(m,y[b=1:n_sim],Bin)
    @variable(m,a)
    @constraint(m,constraint,sum(x[i] for i =1:n_x) == 1)
	@constraint(m,constraint1[j in 1:n_sim], M*y[j]-sum(l[j,i]*x[i] for i in 1:n_x) + a >= 0)
#	@constraint(m,constraint1[j in 1:n_sim], !y[j] => {a  >= sum(l[j,i]*x[i] for i in 1:n_x)})

    @constraint(m,constraint2, sum(y[j] for j in 1:n_sim)<=0.05*num)
    @objective(m,Min,a)
	optimize!(m)
	
end


run_func(10,100)

Could it be related to this github issue?

Yes, Cbc has some issues with SOS constraints. Try a solver with native support for indicator constraints like Gurobi or CPLEX.