JuMP macro @constraint where variable is in a finite set

Is it possible?

I’m trying to solve a very simple optimization problem with IPOPT where the variables are binary. But it seems that IPOPT doesn’t support Bin variables, only continuous ones.

Would it be possible to create a constraint to force my variables to be either in {0,1} or another finite set?

The code is

using LinearAlgebra, JuMP, Ipopt

V =[1, 2, 3]

m = Model(with_optimizer(Ipopt.Optimizer))

@variable(m, A[i=1:3], Bin)

@constraint(m, sum(A[i] for i=1:3) == 1 )

@objective(m, Max,
    sum(V[i]*A[i] for i=1:3)
)

@time begin
    @show JuMP.optimize!(m)
end

I get the error

MathOptInterface.UnsupportedConstraint{MathOptInterface.SingleVariable,MathOptInterface.ZeroOne}: `MathOptInterface.SingleVariable`-in-`MathOptInterface.ZeroOne` constraint is not supported by the model.
bridge_type(::MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer}, ::Type{MathOptInterface.SingleVariable}, ::Type{MathOptInterface.ZeroOne}) at lazy_bridge_optimizer.jl:437
concrete_bridge_type(::MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer}, ::Type{MathOptInterface.SingleVariable}, ::Type{MathOptInterface.ZeroOne}) at bridge.jl:110
add_constraint(::MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer}, ::MathOptInterface.SingleVariable, ::MathOptInterface.ZeroOne) at bridge_optimizer.jl:973
add_constrained_variable(::MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer}, ::MathOptInterface.ZeroOne) at bridge_optimizer.jl:1103
copy_single_variable(::MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, ::MathOptInterface.Utilities.IndexMap, ::Type{MathOptInterface.ZeroOne}) at copy.jl:203
(::getfield(MathOptInterface.Utilities, Symbol("##115#123")){MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer},MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}},MathOptInterface.Utilities.IndexMap})(::Type) at none:0
collect(::Base.Generator{Array{DataType,1},getfield(MathOptInterface.Utilities, Symbol("##115#123")){MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer},MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}},MathOptInterface.Utilities.IndexMap}}) at generator.jl:47
default_copy_to(::MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, ::Bool) at copy.jl:325
#automatic_copy_to#97 at copy.jl:15 [inlined]
#automatic_copy_to at none:0 [inlined]
#copy_to#1 at bridge_optimizer.jl:213 [inlined]
(::getfield(MathOptInterface, Symbol("#kw##copy_to")))(::NamedTuple{(:copy_names,),Tuple{Bool}}, ::typeof(MathOptInterface.copy_to), ::MathOptInterface.Bridges.LazyBridgeOptimizer{Ipopt.Optimizer}, ::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}) at none:0
attach_optimizer(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at cachingoptimizer.jl:149
optimize!(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at cachingoptimizer.jl:185
#optimize!#78(::Bool, ::Bool, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(optimize!), ::Model, ::Nothing) at optimizer_interface.jl:141
optimize! at optimizer_interface.jl:111 [inlined]
optimize!(::Model) at optimizer_interface.jl:111
top-level scope at show.jl:576
top-level scope at [Toy] Optimization with binary.jl:16
top-level scope at util.jl:156

Thank you all.

Ipopt does not support binary variables. Choose a solver that supports MILP in the solver table.

2 Likes