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

ModelLike of type Alpine.Optimizer does not support accessing the attribute MathOptInterface.ResultCount() #162

Closed OliverEvans96 closed 3 years ago

OliverEvans96 commented 3 years ago

Hello,

I'm having trouble accessing the optimal variable value from an Alpine model. Possibly related to #101.

Minimal Example

using JuMP, Alpine, Ipopt, Cbc

m = Model()
set_optimizer(m, Alpine.Optimizer)
set_optimizer_attributes(m, "mip_solver"=>Cbc.Optimizer)
set_optimizer_attributes(m, "nlp_solver"=>Ipopt.Optimizer)
@variable(m, -1 <= x <= 1)
@NLobjective(m, Max, -x+1)
optimize!(m)

An optimal solution is reached:

Solver Output ``` PROBLEM STATISTICS Objective sense = Max #Variables = 1 #Bin-Int Variables = 0 #Constraints = 0 #NL Constraints = 0 #Linear Constraints = 0 #Detected convex constraints = 0 #Detected nonlinear terms = 0 #Variables involved in nonlinear terms = 0 #Potential variables for partitioning = 0 SUB-SOLVERS USED BY ALPINE NLP local solver = Ipopt MIP solver = Cbc ALPINE CONFIGURATION Maximum iterations = 99 Relative optimality gap criteria = 0.0100% Discretization ratio = 4 Bound-tightening (OBBT) presolve = true OBBT maximum iterations = 10 PRESOLVE Doing local search This is Ipopt version 3.13.2, running with linear solver mumps. NOTE: Other linear solvers might be more efficient (see Ipopt documentation). Number of nonzeros in equality constraint Jacobian...: 0 Number of nonzeros in inequality constraint Jacobian.: 0 Number of nonzeros in Lagrangian Hessian.............: 0 Total number of variables............................: 1 variables with only lower bounds: 0 variables with lower and upper bounds: 1 variables with only upper bounds: 0 Total number of equality constraints.................: 0 Total number of inequality constraints...............: 0 inequality constraints with only lower bounds: 0 inequality constraints with lower and upper bounds: 0 inequality constraints with only upper bounds: 0 iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls 0 1.0000000e+00 0.00e+00 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0 1 1.5000000e+00 0.00e+00 3.31e-01 -1.7 5.00e-01 - 6.69e-01 1.00e+00f 1 2 1.9950000e+00 0.00e+00 8.33e-17 -1.7 7.13e-01 - 1.00e+00 6.94e-01f 1 3 1.9998086e+00 0.00e+00 5.20e-18 -3.8 4.81e-03 - 1.00e+00 1.00e+00f 1 4 1.9999982e+00 0.00e+00 1.91e-17 -5.7 1.90e-04 - 1.00e+00 1.00e+00f 1 5 2.0000000e+00 0.00e+00 8.97e-17 -8.6 1.85e-06 - 1.00e+00 1.00e+00f 1 Number of Iterations....: 5 (scaled) (unscaled) Objective...............: -2.0000000074923991e+00 2.0000000074923991e+00 Dual infeasibility......: 8.9681201477325150e-17 8.9681201477325150e-17 Constraint violation....: 0.0000000000000000e+00 0.0000000000000000e+00 Complementarity.........: 2.5076007968172859e-09 -2.5076007968172859e-09 Overall NLP error.......: 2.5076007968172859e-09 8.9681201477325150e-17 Number of objective function evaluations = 6 Number of objective gradient evaluations = 6 Number of equality constraint evaluations = 0 Number of inequality constraint evaluations = 0 Number of equality constraint Jacobian evaluations = 0 Number of inequality constraint Jacobian evaluations = 0 Number of Lagrangian Hessian evaluations = 5 Total CPU secs in IPOPT (w/o function evaluations) = 0.002 Total CPU secs in NLP function evaluations = 0.000 EXIT: Optimal Solution Found. Local solver returns a feasible point Starting bound-tightening Welcome to the CBC MILP Solver Version: 2.10.3 Build Date: Oct 7 2019 command line - Cbc_C_Interface -seconds 999999.9961321354 -solve -quit (default strategy 1) seconds was changed from 1e+100 to 1e+06 Presolve determined that the problem was infeasible with tolerance of 1e-08 Analysis indicates model infeasible or unbounded 0 Obj -1 Primal inf 0.99999991 (1) Primal infeasible - objective value -1 PrimalInfeasible objective -1 - 0 iterations time 0.002 Result - Linear relaxation infeasible Enumerated nodes: 0 Total iterations: 0 Time (CPU seconds): 0.00 Time (Wallclock Seconds): 0.00 Total time (CPU seconds): 0.00 (Wallclock seconds): 0.00 !Welcome to the CBC MILP Solver Version: 2.10.3 Build Date: Oct 7 2019 command line - Cbc_C_Interface -seconds 999999.9936430454 -solve -quit (default strategy 1) seconds was changed from 1e+100 to 1e+06 Presolve determined that the problem was infeasible with tolerance of 1e-08 Analysis indicates model infeasible or unbounded 0 Obj -1 Primal inf 0.99999991 (1) Dual inf 0.9999999 (1) 1 Obj -2 Primal inf 0.99999991 (1) Primal infeasible - objective value -2 PrimalInfeasible objective -2.000000007 - 1 iterations time 0.002 Result - Linear relaxation infeasible Enumerated nodes: 0 Total iterations: 0 Time (CPU seconds): 0.00 Time (Wallclock Seconds): 0.00 Total time (CPU seconds): 0.00 (Wallclock seconds): 0.00 ! Completed presolve in 0.01s (1 iterations) UPPER-BOUNDING ITERATIONS ==================================================================================================== | Iter | Incumbent | Best Incumbent | Upper Bound | Gap (%) | Time Welcome to the CBC MILP Solver Version: 2.10.3 Build Date: Oct 7 2019 command line - Cbc_C_Interface -seconds 999999.9922780991 -solve -quit (default strategy 1) seconds was changed from 1e+100 to 1e+06 Empty problem - 0 rows, 1 columns and 0 elements Optimal - objective value 1 Optimal objective 1 - 0 iterations time 0.002 Total time (CPU seconds): 0.00 (Wallclock seconds): 0.00 | finish | 2.0 | 2.0 | 2.0 | 0.0 | 0.01s ==================================================================================================== *** Alpine ended with status OPTIMAL *** ```

Error Message

But when I try try to access the value, of x, I get the following error:

julia> value(x)
ERROR: ArgumentError: ModelLike of type Alpine.Optimizer does not support accessing the attribute MathOptInterface.ResultCount()
Stacktrace:
 [1] get_fallback(::Alpine.Optimizer, ::MathOptInterface.ResultCount) at /home/oliver/.julia/packages/MathOptInterface/ZJFKw/src/attributes.jl:274
 [2] get(::Alpine.Optimizer, ::MathOptInterface.ResultCount) at /home/oliver/.julia/packages/MathOptInterface/ZJFKw/src/attributes.jl:272
 [3] check_result_index_bounds(::Alpine.Optimizer, ::MathOptInterface.VariablePrimal) at /home/oliver/.julia/packages/MathOptInterface/ZJFKw/src/attributes.jl:131
 [4] get(::Alpine.Optimizer, ::MathOptInterface.VariablePrimal, ::MathOptInterface.VariableIndex) at /home/oliver/.julia/packages/Alpine/Z4PGO/src/solver.jl:583
 [5] get(::MathOptInterface.Bridges.LazyBridgeOptimizer{Alpine.Optimizer}, ::MathOptInterface.VariablePrimal, ::MathOptInterface.VariableIndex) at /home/oliver/.julia/packages/MathOptInterface/ZJFKw/src/Bridges/bridge_optimizer.jl:808
 [6] get(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, ::MathOptInterface.VariablePrimal, ::MathOptInterface.VariableIndex) at /home/oliver/.julia/packages/MathOptInterface/ZJFKw/src/Utilities/cachingoptimizer.jl:605
 [7] _moi_get_result(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, ::MathOptInterface.VariablePrimal, ::Vararg{Any,N} where N) at /home/oliver/.julia/packages/JuMP/qhoVb/src/JuMP.jl:848
 [8] get(::Model, ::MathOptInterface.VariablePrimal, ::VariableRef) at /home/oliver/.julia/packages/JuMP/qhoVb/src/JuMP.jl:878
 [9] value(::VariableRef; result::Int64) at /home/oliver/.julia/packages/JuMP/qhoVb/src/variables.jl:767
 [10] value(::VariableRef) at /home/oliver/.julia/packages/JuMP/qhoVb/src/variables.jl:767
 [11] top-level scope at REPL[76]:1

Relevant Package Versions

Using Julia v1.5.3 (2020-11-09)

  [07493b3f] Alpine v0.2.1
  [9961bab8] Cbc v0.6.7
  [b6b21f68] Ipopt v0.6.5
  [4076af6c] JuMP v0.21.5

Is there currently any way to get the variable value?

Thanks! Oliver

harshangrjn commented 3 years ago

@OliverEvans96 Are you getting this issue with other MILP solvers like CPLEX/Gurobi?

blegat commented 3 years ago

Looking at the code, value is indeed not going to work, A getter is needed for ResultCount here: https://github.com/lanl-ansi/Alpine.jl/blob/383bdbc0a97347e0e04633f25af95e430f1edc77/src/solver.jl#L583 A simple implementation is

MOI.get(model::Optimizer, ::MOI.ResultCount) = model.alpine_status == MOI.OPTIMIZE_NOT_CALLED ? 0 : 1

https://github.com/lanl-ansi/Alpine.jl/issues/152 should help catching these kind of issues

OliverEvans96 commented 3 years ago

@harshangrjn I don't have CPLEX/Gurobi.

@blegat when I define your MOI.get method before calling value(x), the first error is resolved, but I now get a new error:

julia> value(x)
ERROR: The index MathOptInterface.VariableIndex(1) is invalid. Note that an index becomes invalid after it has been deleted.
Stacktrace:
 [1] throw_if_not_valid(::Alpine.Optimizer, ::MathOptInterface.VariableIndex) at /home/oliver/.julia/packages/MathOptInterface/ZJFKw/src/indextypes.jl:75
 [2] get(::Alpine.Optimizer, ::MathOptInterface.VariablePrimal, ::MathOptInterface.VariableIndex) at /home/oliver/.julia/packages/Alpine/Z4PGO/src/solver.jl:584
 [3] get(::MathOptInterface.Bridges.LazyBridgeOptimizer{Alpine.Optimizer}, ::MathOptInterface.VariablePrimal, ::MathOptInterface.VariableIndex) at /home/oliver/.julia/packages/MathOptInterface/ZJFKw/src/Bridges/bridge_optimizer.jl:808
 [4] get(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, ::MathOptInterface.VariablePrimal, ::MathOptInterface.VariableIndex) at /home/oliver/.julia/packages/MathOptInterface/ZJFKw/src/Utilities/cachingoptimizer.jl:605
 [5] _moi_get_result(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, ::MathOptInterface.VariablePrimal, ::Vararg{Any,N} where N) at /home/oliver/.julia/packages/JuMP/qhoVb/src/JuMP.jl:848
 [6] get(::Model, ::MathOptInterface.VariablePrimal, ::VariableRef) at /home/oliver/.julia/packages/JuMP/qhoVb/src/JuMP.jl:878
 [7] value(::VariableRef; result::Int64) at /home/oliver/.julia/packages/JuMP/qhoVb/src/variables.jl:767
 [8] value(::VariableRef) at /home/oliver/.julia/packages/JuMP/qhoVb/src/variables.jl:767
 [9] top-level scope at REPL[11]:1
blegat commented 3 years ago

You should also add

MOI.is_valid(model::Optimizer, vi::MOI.VariableIndex) = 1 <= vi.value <= model.num_var_orig
OliverEvans96 commented 3 years ago

@blegat - that worked!

julia> value(x)
-1.0

Thanks and happy holidays! Oliver

harshangrjn commented 3 years ago

This issue has been fixed in v0.2.2.