Implement lazy callbacks

This commit is contained in:
2021-08-18 17:02:16 -05:00
parent 39072a6290
commit af3a5a69f0
8 changed files with 162 additions and 34 deletions

View File

@@ -9,6 +9,8 @@ using MathOptInterface
using TimerOutputs
const MOI = MathOptInterface
import JuMP: value
mutable struct JuMPSolverData
optimizer_factory::Any
varname_to_var::Dict{String,VariableRef}
@@ -19,6 +21,7 @@ mutable struct JuMPSolverData
solution::Dict{JuMP.VariableRef,Float64}
reduced_costs::Vector{Float64}
dual_values::Dict{JuMP.ConstraintRef,Float64}
cb_data::Any
end
@@ -175,10 +178,25 @@ function remove_constraints(data::JuMPSolverData, names::Vector{String})::Nothin
end
function solve(data::JuMPSolverData; tee::Bool = false, iteration_cb = nothing)
function solve(
data::JuMPSolverData;
tee::Bool = false,
iteration_cb = nothing,
lazy_cb = nothing,
)
model = data.model
wallclock_time = 0
log = ""
if lazy_cb !== nothing
function lazy_cb_wrapper(cb_data)
data.cb_data = cb_data
lazy_cb(nothing, nothing)
data.cb_data = nothing
end
MOI.set(model, MOI.LazyConstraintCallback(), lazy_cb_wrapper)
end
while true
wallclock_time += @elapsed begin
log *= _optimize_and_capture_output!(model, tee = tee)
@@ -189,6 +207,7 @@ function solve(data::JuMPSolverData; tee::Bool = false, iteration_cb = nothing)
break
end
end
if is_infeasible(data)
data.solution = Dict()
primal_bound = nothing
@@ -452,6 +471,7 @@ function __init_JuMPSolver__()
Dict(), # solution
[], # reduced_costs
Dict(), # dual_values
nothing, # cb_data
)
end
@@ -555,12 +575,27 @@ function __init_JuMPSolver__()
iteration_cb = nothing,
lazy_cb = nothing,
user_cut_cb = nothing,
) = solve(self.data, tee = tee, iteration_cb = iteration_cb)
) = solve(self.data, tee = tee, iteration_cb = iteration_cb, lazy_cb = lazy_cb)
solve_lp(self; tee = false) = solve_lp(self.data, tee = tee)
end
copy!(JuMPSolver, Class)
end
function value(solver::JuMPSolverData, var::VariableRef)
if solver.cb_data !== nothing
return JuMP.callback_value(solver.cb_data, var)
else
return JuMP.value(var)
end
end
export JuMPSolver
function submit(solver::JuMPSolverData, con::AbstractConstraint, name::String = "")
if solver.cb_data !== nothing
MOI.submit(solver.model, MOI.LazyConstraint(solver.cb_data), con)
else
JuMP.add_constraint(solver.model, con, name)
end
end
export JuMPSolver, submit

View File

@@ -53,6 +53,13 @@ function set_category!(c::ConstraintRef, category::String)::Nothing
return
end
function set_lazy_callback!(model::Model, find_cb::Function, enforce_cb::Function)::Nothing
ext = init_miplearn_ext(model)
ext["lazy_find_cb"] = find_cb
ext["lazy_enforce_cb"] = enforce_cb
return
end
macro feature(obj, features)
quote
@@ -67,6 +74,12 @@ macro category(obj, category)
end
end
macro lazycb(obj, find_cb, enforce_cb)
quote
set_lazy_callback!($(esc(obj)), $(esc(find_cb)), $(esc(enforce_cb)))
end
end
function _get_and_check_name(obj)
n = name(obj)
length(n) > 0 || error(
@@ -77,4 +90,4 @@ function _get_and_check_name(obj)
end
export @feature, @category
export @feature, @category, @lazycb