In JuMP, is there a way to programmatically fix the variables, that have zero or near-zero multiplicative coefficients, to zero? A simple toy example (where it is very easy to compute the coefficients) that shows what I want to do would be:
n = 10
m = Model(Gurobi.Optimizer)
coeff = [rand(0:1) for i in 1:n]
@variable(m, x[1:n] >= 0)
@objective(m, Max, sum(x[i] for i in 1:n))
@constraint(m, sum(x[i] * coeff[i] for i in 1:n) <= 1)
# fix the x[i] which have coefficient zero or near 0
for i in 1:n
if abs(coeff[i]) <= 1e-6
@info "Fixing x[$i] to 0"
fix(x[i], 0.0; force = true)
end
end
optimize!(m)
@show value.(x)
I have an optimization problem, where the model has many constraints and the model is fairly complex. I would like fix the variables, which have zero or near-zero multiplicative coefficients to zero in the final JuMP model, to 0, e.g.,
fix(x[i], 0.0; force = true) # x[i] has coefficient 0 or near-zero in all the constraints
before optimizing the objective. Is there a way to do it programmatically in JuMP?
using JuMP
function fix_if_small_coefficient(model; atol)
to_check = Set(all_variables(model))
for (F, S) in list_of_constraint_types(model)
if F != AffExpr
continue # Check only the affine constraints
end
for ci in all_constraints(model, F, S)
object = constraint_object(ci)
for xi in to_check
if abs(coefficient(object.func, xi)) >= atol
pop!(to_check, xi)
end
end
end
end
for xi in to_check
println("Fixing $xi")
fix(xi, 0.0; force = true)
end
return
end
n = 10
coeff = rand(n)
model = Model()
@variable(model, x[1:n] >= 0)
@objective(model, Max, sum(x))
@constraint(model, coeff' * x <= 1)
fix_if_small_coefficient(model; atol = 0.2)
Thanks @odow! Essentially, what I want is to fix those variables which have near-zero coefficients in all the constraints (loosely speaking, fix those variables to zero that do not participate in the model), but it seems that the code sometimes also sets variables that do not have zero coefficients in all the constraint to zero as well. Working example:
Fixing x[1]
Fixing x[7]
Fixing x[10]
Fixing y
Fixing x[3]
Note that, x[1] has coefficients 1 in the second constraints, so it should not be fixed to 0. Same goes for y, it has coefficient 0 in the first constraint but coefficient 1 in the second constraint, so should not be fixed to 0. Please let me know how to get the intended behavior, where only the variables that have near-zero coefficients over all the constraints are fixed to 0.