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?
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)