lanl-ansi / Alpine.jl

A Julia/JuMP-based Global Optimization Solver for Non-convex Programs
https://lanl-ansi.github.io/Alpine.jl/latest/
Other
244 stars 39 forks source link

Alpine crashes when using @objective and not @NLobjective #179

Closed freemin7 closed 2 years ago

freemin7 commented 2 years ago
using JuMP
using Alpine
using Ipopt
using Cbc
using Juniper
using Gurobi

# MIP solver - open-source
function get_cbc()
    return optimizer_with_attributes(Cbc.Optimizer, 
                                     MOI.Silent() => true) 
end

# Local solver
function get_ipopt()
    return optimizer_with_attributes(Ipopt.Optimizer, 
                                    MOI.Silent() => true, 
                                    "sb" => "yes", 
                                    "max_iter" => Int(1E4))
end

#m = Model(optimizer_with_attributes(Gurobi.Optimizer, "NonConvex"=>2))

m = Model(optimizer_with_attributes(Alpine.Optimizer, "nlp_solver"=>get_ipopt(), "mip_solver"=>get_cbc(), "minlp_solver" =>optimizer_with_attributes(Juniper.Optimizer, MOI.Silent() => true, "mip_solver" => get_cbc(), "nl_solver" => get_ipopt())))

dim = 3;

xₘ = 5
yₘ = 6

room_count = 7

@variable(m, 0 <= x[1:room_count] <= xₘ)
@variable(m, 0 <= w[1:room_count] <= xₘ)

@variable(m, 0 <= y[1:room_count] <= yₘ)
@variable(m, 0 <= d[1:room_count] <= yₘ)

for i in 1:room_count
  @constraint(m, x[i] + w[i] <= xₘ)
  @constraint(m, y[i] + d[i] <= yₘ)
end

if dim == 3
  zₘ = 10
  zmin = 2.2
  @variable(m, 0 <= z[1:room_count] <= zₘ)
  @variable(m, zmin <= h[1:room_count] <= zₘ)
  for i in 1:room_count
    @constraint(m, z[i] + h[i] <= zₘ)
  end
end

@variable(m, δ[1:room_count,1:room_count,1:(2*dim)], Bin)

for i in 1:room_count
  for j in 1:room_count
    if i!=j 
      @constraint(m, sum(δ[i,j,k] for k in 1:(dim*2)) <= (2*dim -1))
      @constraint(m, x[i] + w[i] <= x[j] + xₘ*δ[i,j,1])
      @constraint(m, y[i] + d[i] <= y[j] + yₘ*δ[i,j,2])
      @constraint(m, x[j] + w[j] <= x[i] + xₘ*δ[i,j,3])
      @constraint(m, y[j] + d[j] <= y[i] + yₘ*δ[i,j,4])
    end
  end
end

if dim == 3
for i in 1:room_count
  for j in 1:room_count
    if i!=j 
      @constraint(m, z[i] + h[i] <= z[j] + zₘ*δ[i,j,5])
      @constraint(m, z[j] + h[j] <= z[i] + zₘ*δ[i,j,6])
    end
  end
end
end

@objective(m, Max, sum(w[i]*d[i] for i in 1:room_count))

JuMP.optimize!(m)

which raises that issue:

ERROR: MethodError: no method matching initialize(::Nothing, ::Vector{Symbol})
Closest candidates are:
  initialize(::MathOptInterface.Test.HS071, ::Vector{Symbol}) at /home/joto/.julia/packages/MathOptInterface/YDdD3/src/Test/nlp.jl:22
  initialize(::MathOptInterface.Test.FeasibilitySenseEvaluator, ::Vector{Symbol}) at /home/joto/.julia/packages/MathOptInterface/YDdD3/src/Test/nlp.jl:280
  initialize(::NLPEvaluator, ::Vector{Symbol}) at /home/joto/.julia/packages/JuMP/klrjG/src/nlp.jl:411
  ...
Stacktrace:
 [1] load!(m::Alpine.Optimizer)
   @ Alpine ~/.julia/packages/Alpine/0w1zg/src/solver.jl:486
 [2] optimize!(m::Alpine.Optimizer)
   @ Alpine ~/.julia/packages/Alpine/0w1zg/src/algorithm.jl:17
 [3] optimize!(b::MathOptInterface.Bridges.LazyBridgeOptimizer{Alpine.Optimizer})
   @ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/YDdD3/src/Bridges/bridge_optimizer.jl:319
 [4] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ModelFunctionConstraints{Float64}}}})
   @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/YDdD3/src/Utilities/cachingoptimizer.jl:252
 [5] optimize!(model::Model, optimizer_factory::Nothing; bridge_constraints::Bool, ignore_optimize_hook::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ JuMP ~/.julia/packages/JuMP/klrjG/src/optimizer_interface.jl:185
 [6] optimize! (repeats 2 times)
   @ ~/.julia/packages/JuMP/klrjG/src/optimizer_interface.jl:157 [inlined]
 [7] top-level scope
   @ REPL[25]:1

Unrelated to that issue Juniper get's stuck when i use @NLobjective but maybe my problem is just to big and just repeats:

┌ Warning: Only almost solved
└ @ Juniper ~/.julia/packages/Juniper/8wso7/src/BnBTree.jl:89
mzagorowska commented 2 years ago

I got a similar issue with Alpine. The problem seems to be with Juniper rather than with Alpine. From the docs for Juniper: This solver is a NLP solver therefore you should have at least one NLconstraint or NLobjective.

ccoffrin commented 2 years ago

Juniper should work without any "NL" macros, I think that doc is out of date with respect to the latest version.

CC @Wikunia

harshangrjn commented 2 years ago

@freemin7 Since your problem has all linear constraints, and the nonlinearity is only in the objective, mentioning it as @NLobjective is necessary for Alpine. This may be something which needs to be made clearer in the Documentation. By making it @NLobjective, it seems to run fine in Juniper and Alpine.

On a side note, your problem as it is seems to be quite large, and Juniper doesn't seem to converge for room_count >= 5. However, reducing the room_count parameter to 4 (from 7) seems to converge in Juniper and also in Alpine (in a single iteration). Both Gurobi and Cbc as the MIP solver seem to converge without issues. Alpine's setting for this run is same as this: https://github.com/lanl-ansi/Alpine.jl/blob/65c75f39cdbdd7ccad08f72dc8e2face5d5d9052/examples/run_examples.jl#L20