Good morning community,
I’m trying to use lazy constraints, but I’m finding some issues. I would like to solve a problem iterative
(benders decomposition) where in each iteration an additional constraint is added as lazy constraint. The issue that I’m facing is that in the first iteration the PRESOLVE is eliminating some variables that in the next iteration are going to be used in the lazy constraint.
I attached a dummy example where I got the same problem, It only works if the PRESOLVE is deactivated.
Any idea how to solve this issue? Maybe by telling the PRESOLVE not to eliminate a specific variable?
Thanks for everything.
model = Model(()->Xpress.Optimizer())
@variable(model, x >= 0)
@variable(model, y >= 0)
@variable(model, v >= 0)
@variable(model, z >= 0,Int)
@constraint(model, x+y >= 2)
@objective(model, Min, x+y+z+v)
set_optimizer_attributes(model, "HEURSTRATEGY" => 0)
#set_optimizer_attributes(model, "PRESOLVE" => 0)
optimize!(model);
println(" Execution is " * string(termination_status(model)))
println("x: ",JuMP.value(x), " y: ",JuMP.value(y)," z: ",JuMP.value(z)," v: ",JuMP.value(v))
function good_callback_function(cb_data)
v_val = callback_value(cb_data,v)
if v_val < 10
con = @build_constraint(v >= 10 )
MOI.submit(model, MOI.LazyConstraint(cb_data), con)
end
end
MOI.set(model, MOI.LazyConstraintCallback(), good_callback_function)
optimize!(model);
println(" Execution is " * string(termination_status(model)))
println("x: ",JuMP.value(x), " y: ",JuMP.value(y)," z: ",JuMP.value(z)," v: ",JuMP.value(v))
The logs:
FICO Xpress v8.8.0, Hyper, solve started 11:01:41, Feb 20, 2024
Heap usage: 2389KB (peak 2847KB, 5348KB system)
Minimizing MILP
Original problem has:
1 rows 4 cols 2 elements 1 globals
Presolved problem has:
0 rows 0 cols 0 elements 0 globals
LP relaxation tightened
Presolve finished in 0 seconds
Heap usage: 2391KB (peak 2847KB, 5348KB system)
Will try to keep branch and bound tree memory usage below 11.0GB
Starting concurrent solve with dual
Concurrent-Solve, 0s
Dual
objective dual inf
D 2.0000000 .0000000
------- optimal --------
Concurrent statistics:
Dual: 0 simplex iterations, 0.00s
Optimal solution found
Its Obj Value S Ninf Nneg Sum Dual Inf Time
0 2.000000 D 0 0 .000000 0
Dual solved problem
0 simplex iterations in 0s
Final objective : 2.000000000000000e+00
Max primal violation (abs/rel) : 0.0 / 0.0
Max dual violation (abs/rel) : 0.0 / 0.0
Max complementarity viol. (abs/rel) : 0.0 / 0.0
All values within tolerances
Starting root cutting & heuristics
Its Type BestSoln BestBound Sols Add Del Gap GInf Time
*** Search unfinished *** Time: 0 Nodes: 0
Number of integer feasible solutions found is 0
Best bound is 2.000000
Uncrunching matrix
ERROR: XpressError(32): Subroutine not completed successfully, possibly due to invalid argument. Xpress internal error:
405 Error: Invalid column number passed to XPRSstorecuts.
Column number 2 is invalid.
Stacktrace:
[1] _check(prob::Xpress.XpressProblem, val::Int32)
@ Xpress ~/.julia/packages/Xpress/IPJtC/src/utils.jl:144
[2] macro expansion
@ ~/.julia/packages/Xpress/IPJtC/src/utils.jl:137 [inlined]
[3] optimize!(model::Xpress.Optimizer)
@ Xpress ~/.julia/packages/Xpress/IPJtC/src/MOI/MOI_wrapper.jl:2742
[4] optimize!
@ ~/.julia/packages/MathOptInterface/tWT4o/src/Bridges/bridge_optimizer.jl:376 [inlined]
[5] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Xpress.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
@ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/tWT4o/src/Utilities/cachingoptimizer.jl:325
[6] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ JuMP ~/.julia/packages/JuMP/KiENn/src/optimizer_interface.jl:439
[7] optimize!(model::Model)
@ JuMP ~/.julia/packages/JuMP/KiENn/src/optimizer_interface.jl:409
[8] top-level scope
@ REPL[151]:1