diff --git a/src/MOI/MOI_callbacks.jl b/src/MOI/MOI_callbacks.jl index 2a9b9e40..126fe7a9 100644 --- a/src/MOI/MOI_callbacks.jl +++ b/src/MOI/MOI_callbacks.jl @@ -131,15 +131,17 @@ function MOI.get( end # ============================================================================== -# MOI.UserCutCallback & MOI.LazyConstraint +# MOI.UserCutCallback & MOI.LazyConstraint # ============================================================================== function MOI.set(model::Optimizer, ::MOI.UserCutCallback, cb::Function) + MOI.set(model, MOI.RawOptimizerAttribute("MIPDUALREDUCTIONS"), 0) model.user_cut_callback = cb return end function MOI.set(model::Optimizer, ::MOI.LazyConstraintCallback, cb::Function) + MOI.set(model, MOI.RawOptimizerAttribute("MIPDUALREDUCTIONS"), 0) model.lazy_callback = cb return end @@ -253,4 +255,4 @@ MOI.supports(::Optimizer, ::MOI.HeuristicSolution{CallbackData}) = true function cache_exception(model::Optimizer, e::Exception) model.cb_exception = e return -end \ No newline at end of file +end diff --git a/test/MathOptInterface/MOI_callbacks.jl b/test/MathOptInterface/MOI_callbacks.jl index 730196f1..e4d0921e 100644 --- a/test/MathOptInterface/MOI_callbacks.jl +++ b/test/MathOptInterface/MOI_callbacks.jl @@ -323,7 +323,7 @@ end cb_calls = Int32[] MOI.set(model, Xpress.CallbackFunction(), (cb_data) -> begin push!(cb_calls) - + if Xpress.get_control_or_attribute(cb_data.model, Xpress.Lib.XPRS_CALLBACKCOUNT_OPTNODE) > 1 return end @@ -385,3 +385,41 @@ end MOI.optimize!(model) @test unknown_reached end + +function test_lazy_constraint_dual_reductions() + model = Xpress.Optimizer() + MOI.set(model, MOI.Silent(), true) + x = MOI.add_variables(model, 3) + MOI.add_constraint.(model, x, MOI.GreaterThan(0.0)) + MOI.add_constraint.(model, x[1:2], MOI.Integer()) + MOI.add_constraint( + model, + 1.0 * x[1] + 1.0 * x[2] - 1.0 * x[3], + MOI.EqualTo(0.0), + ) + MOI.add_constraint(model, 1.0 * x[1] + 1.0 * x[2], MOI.LessThan(220.0)) + MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) + f = 1.0 * x[3] + MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f) + function lazy_flow_constraints(cb_data) + x_val = MOI.get.(model, MOI.CallbackVariablePrimal(cb_data), x) + if x_val[1] + x_val[2] > 10 + MOI.submit( + model, + MOI.LazyConstraint(cb_data), + 1.0 * x[1] + 1.0 * x[2], + MOI.LessThan(10.0), + ) + end + end + MOI.set(model, MOI.LazyConstraintCallback(), lazy_flow_constraints) + MOI.optimize!(model) + x_val = MOI.get(model, MOI.VariablePrimal(), x) + @test x_val[1] + x_val[2] <= 10.0 + 1e-4 + @test x_val[1] + x_val[2] ≈ x_val[3] + return +end + +@testset "Xpress.test_lazy_constraint_dual_reductions" begin + test_lazy_constraint_dual_reductions() +end