PSORLab / EAGO.jl

A development environment for robust and global optimization
MIT License
140 stars 16 forks source link

Upper bound and binary variables #115

Closed javieravz closed 1 year ago

javieravz commented 1 year ago

I'm working on solving a MINLP problem but I'm getting this message: MathOptInterface.UpperBoundAlreadySet{MathOptInterface.Interval{Float64}, MathOptInterface.LessThan{Float64}}: Cannot add VariableIndex-in-MathOptInterface.LessThan{Float64} constraint for variable MOI.VariableIndex(6001) as a VariableIndex-in-MathOptInterface.Interval{Float64} constraint was already set for this variable and both constraints set an upper bound.

It appears any time I add binary variables. Does EAGO support binary variables in JuMP?

RXGottlieb commented 1 year ago

Hi @javieravz---EAGO does support binary and integer JuMP variables. Would you be able to post a minimum breaking example to help isolate where your issue is coming from?

javieravz commented 1 year ago

Here is the example

`using JuMP, EAGO

model = Model(EAGO.Optimizer)

M= v= [10.4, 10.25, 9.67, 9.12, 7.82, 7.35, 8.85, 9.7, 8.41, 6.66, 6.65, 6, 5.76, 5.44, 5.44, 3.38, 2.97, 6.31, 6.33, 7.07, 5.27, 4.82, 7.33, 8.99];

Sets

T=1:24
C=1:10
R=1:5 I=1:3

Variables

@variable(model, p_out[c in C, r in R, t in T]>=0) @variable(model, p_out_ac[c in C, r in R, t in T]>=0) @variable(model, N) #number of turbines @variable(model, f[i in I, c in C, r in R, t in T]>=0) @variable(model, ws[c in C, r in R, t in T]>=0) @variable(model, y>=0) @variable(model, x>=0)

Binary Variable

@variable(model, y_b[c in C, r in R], Bin) @variable(model, y_o[c in C, r in R, t in T] , Bin) @variable(model, z[i in I, c in C, r in R, t in T], Bin)

@constraint(model, y>=800) @constraint(model, x>=200)

@constraint(model,[c in C, t in T], ws[c,1,t]==v[t]) @NLconstraint(model,[c in C, r=1:4, t in T], ws[c,r+1,t]== ws[c,r,t]+ ws[c,r,t](sqrt(1-0.72)-1)(50/(50+0.075*y))^2)

@constraint(model, [c in C, r=1:4, t in T], y_o[c,r+1,t] <= y_o[c,r,t]) @constraint(model, [c=1:9, r in R, t in T], y_o[c+1,r,t] <= y_o[c,r,t])

@constraint(model, [c in C, r in R, t in T], y_o[c,r,t] <= y_b[c,r]) @constraint(model, [c in C, r in R, t in T], p_out_ac[c,r,t] <= 10^6 *y_o[c,r,t])

@constraint(model, [c in C, r in R, t in T], p_out_ac[c,r,t] <= p_out[c,r,t])

@constraint(model, [c in C, r in R, t in T], ws[c,r,t]== sum(f[i, c, r, t] for i in I)) @constraint(model, [c in C, r in R, t in T], sum(z[i, c, r, t] for i in I)==1) @constraint(model, [c in C, r in R, t in T], p_out[c,r,t] == 0.35f[2, c, r, t]-1.05z[2, c, r, t]+3.5z[3, c, r, t]) @constraint(model, [c in C, r in R, t in T], 0 <= f[1, c, r, t]) @constraint(model, [c in C, r in R, t in T], f[1, c, r, t] <= 3 z[1, c, r, t]) @constraint(model, [c in C, r in R, t in T], 3 z[2, c, r, t] <= f[2, c, r, t]) @constraint(model, [c in C, r in R, t in T], f[2, c, r, t]<= 13 z[2, c, r, t]) @constraint(model, [c in C, r in R, t in T], 13 z[3, c, r, t] <= f[3, c, r, t]) @constraint(model, [c in C, r in R, t in T], f[3, c, r, t]<= 25 z[3, c, r, t])

@constraint(model, 370000 <= sum(p_out_ac[c,r,t] for c in C, r in R, t in T)*365) #power_tot @constraint(model, N == sum(y_b[c,r] for c in C, r in R))

Objective function

@NLobjective(model, Min, N 1600 3.5 + 0.7413 x y * N) optimize!(model)
println() println(termination_status(model))`

And here is the output

MathOptInterface.UpperBoundAlreadySet{MathOptInterface.Interval{Float64}, MathOptInterface.LessThan{Float64}}: Cannot add VariableIndex-in-MathOptInterface.LessThan{Float64} constraint for variable MOI.VariableIndex(7204) as a VariableIndex-in-MathOptInterface.Interval{Float64} constraint was already set for this variable and both constraints set an upper bound.

Stacktrace: [1] _throw_if_upper_bound_set_inner(variable::MathOptInterface.VariableIndex, S2::Type, mask::UInt16, T::Type) @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/BlCD1/src/Utilities/variables_container.jl:138 [2] _throw_if_upper_bound_set @ ~/.julia/packages/MathOptInterface/BlCD1/src/Utilities/variables_container.jl:149 [inlined] [3] add_constraint @ ~/.julia/packages/MathOptInterface/BlCD1/src/Utilities/variables_container.jl:268 [inlined] [4] add_constraint @ ~/.julia/packages/MathOptInterface/BlCD1/src/Utilities/model.jl:371 [inlined] [5] add_constraint(m::MathOptInterface.Utilities.CachingOptimizer{Cbc.Optimizer, MathOptInterface.Utilities.Model{Float64}}, func::MathOptInterface.VariableIndex, set::MathOptInterface.LessThan{Float64}) @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/BlCD1/src/Utilities/cachingoptimizer.jl:546 [6] add_constraint(b::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{Cbc.Optimizer, MathOptInterface.Utilities.Model{Float64}}}, f::MathOptInterface.VariableIndex, s::MathOptInterface.LessThan{Float64}) @ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/BlCD1/src/Bridges/bridge_optimizer.jl:1750 [7] add_constraint @ ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/types/incremental.jl:86 [inlined] [8] update_relaxed_problem_box!(m::EAGO.GlobalOptimizer{EAGO.Incremental{Cbc.Optimizer}, EAGO.Incremental{Ipopt.Optimizer}, EAGO.DefaultExt}) @ EAGO ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/optimize/nonconvex/lower_problem.jl:91 [9] relax_problem!(m::EAGO.GlobalOptimizer{EAGO.Incremental{Cbc.Optimizer}, EAGO.Incremental{Ipopt.Optimizer}, EAGO.DefaultExt}) @ EAGO ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/optimize/nonconvex/lower_problem.jl:217 [10] obbt!(m::EAGO.GlobalOptimizer{EAGO.Incremental{Cbc.Optimizer}, EAGO.Incremental{Ipopt.Optimizer}, EAGO.DefaultExt}) @ EAGO ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/domain_reduction.jl:254 [11] preprocess!(t::EAGO.DefaultExt, m::EAGO.GlobalOptimizer{EAGO.Incremental{Cbc.Optimizer}, EAGO.Incremental{Ipopt.Optimizer}, EAGO.DefaultExt}) @ EAGO ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/optimize/nonconvex/lower_problem.jl:323 [12] preprocess! @ ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/optimize/nonconvex/lower_problem.jl:332 [inlined] [13] macro expansion @ ./timing.jl:382 [inlined] [14] global_solve!(m::EAGO.GlobalOptimizer{EAGO.Incremental{Cbc.Optimizer}, EAGO.Incremental{Ipopt.Optimizer}, EAGO.DefaultExt}) @ EAGO ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/optimize/optimize_nonconvex.jl:394 [15] optimize! @ ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/optimize/optimize_nonconvex.jl:491 [inlined] [16] optimize!(m::Optimizer{EAGO.Incremental{Cbc.Optimizer}, EAGO.Incremental{Ipopt.Optimizer}, EAGO.DefaultExt}) @ EAGO ~/.julia/packages/EAGO/bDYmz/src/eago_optimizer/optimize/optimize.jl:39 [17] optimize! @ ~/.julia/packages/MathOptInterface/BlCD1/src/Bridges/bridge_optimizer.jl:376 [inlined] [18] optimize! @ ~/.julia/packages/MathOptInterface/BlCD1/src/MathOptInterface.jl:85 [inlined] [19] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Optimizer{EAGO.Incremental{Cbc.Optimizer}, EAGO.Incremental{Ipopt.Optimizer}, EAGO.DefaultExt}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/BlCD1/src/Utilities/cachingoptimizer.jl:316 [20] optimize!(model::Model; ignore_optimize_hook::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}) @ JuMP ~/.julia/packages/JuMP/Y4piv/src/optimizer_interface.jl:161 [21] optimize!(model::Model) @ JuMP ~/.julia/packages/JuMP/Y4piv/src/optimizer_interface.jl:136 [22] top-level scope @ In[3]:57 (which is the line optimize!(model) )

RXGottlieb commented 1 year ago

We were able to isolate the issue. This and a couple other small changes will be pushed out in v0.8.1.

Your example shouldn't throw any errors with this fix, though I'll note that EAGO requires each variable to have a compact set as its domain. The continuous variables in your model are missing upper bounds, or both lower and upper bounds for N---this will cause problems for the global optimization routine since there is no well-defined branching rule for cases where the interval bounds contain -Inf or Inf. A check and warning for unbounded variables is one of the updates that we're adding in EAGO v0.8.1. This will set the missing bounds on your continuous variables to -1e10 (lower) or 1e10 (upper), though you may want to be more restrictive to improve performance.