Juniper.jl
Juniper.jl copied to clipboard
Support for Indicator Constraints
Is it possible to add support for Indicator constraints: https://jump.dev/JuMP.jl/dev/constraints/#Indicator-constraints ?
I have tried myself to add support for them, but I continue to not have any luck getting it to work.
I started with
function MOI.supports_constraint(
::Optimizer,
func::Type{MOI.VectorAfflineFunction{T}},
set::Type{IS},
) where {A, T<:Real, ASS<:MOI.AbstractScalarSet, IS<:MOI.IndicatorSet{A, ASS}}
return A == MOI.ACTIVATE_ON_ONE || A == MOI.ACTIVATE_ON_ZERO
end
and have attempted to use @define_add_constraint
, and write my own MOI.add_constraint
, but am getting lost in where to go with this.
In my experience very few solvers support Indicator Constraints. CPlex and Gurobi are the only ones that come to my mind and that is partly because it is not easy to generalize by linear programming models. In the case of Juniper it is not clear to be how we could support these in a mathematically robust way but @hhijazi or @harshangrjn might have an idea.
Unless there is a nice mathematical insight that I am not aware of my recommendation would be to avoiding using these types of constraints in non-linear models.
@ccoffrin I discussed about this issue briefly with @pseudocubic. As you mentioned it, and from my little experience in Gurobi, indicator constraints, directly in solvers, work on very simple cases. For these cases, it may be even simpler to directly model the big-M form of the constraint assuming the variables have decent bounds. If the constraints are linear, it may be better to directly represent the indicator constraints in the algebraic form instead of going through the JuMP's indicator syntax. But it gets trickier with nonlinear indicator constraints, about which @hhijazi can comment better. This is also why Alpine doesn't support the indicator constraints syntax.
@blegat, any chance your MOI-only version of Juniper will resolve this point?
Yes, now Juniper will accept the indicator constraints but it will pass it to the continuous solver which does not support them. We should filter them out in the IntegralRelaxation but then we should check that they are satisfied when we check that a solution is integer feasible and add it to subproblems when the binary variables is fixed to true. Another approach is to reformulate it with bigM in the continuous problem, hoping the variables have bounds
I suppose my feeling is that the big-M formulation should be added by a bridge but maybe it is best to have that discussion on then next JuMP call.
After a brief discussion on the JuMP-dev call it is best that Juniper handle this internally and not through a bridge. But I don't expect we will be able to support it any time soon. So I'll revert back to my original suggestion of avoiding the use of these types of constraints.
Would it be enough at the beginning to just add the right hand side to the underlying NL model once the indicator is fixed to being fulfilled? Unfortunately I had to drop out of the call earlier.
Yes, one correct implementation is to add the constraint during the search, once the binary variable becomes true. However, this is not really in the sprit of "bound" in branch-and-bound because the relaxation won't know about the constraint until it is magically appears mid-search.
I think that it would be better if we require the modelers think carefully about how to link their binary variable to the constraint.
Yeah that makes sense it also would introduce too much hope for the user even though we wouldn't fully support it then.