You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MIPLearn.jl/src/solvers/learning.jl

115 lines
3.2 KiB

# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using Distributed
struct LearningSolver
py::PyCall.PyObject
optimizer_factory
end
function LearningSolver(
optimizer_factory;
components = nothing,
mode::AbstractString = "exact",
simulate_perfect::Bool = false,
solve_lp::Bool = true,
)::LearningSolver
return LearningSolver(
miplearn.LearningSolver(
solver=JuMPSolver(optimizer_factory),
mode=mode,
solve_lp=solve_lp,
simulate_perfect=simulate_perfect,
components=components,
),
optimizer_factory,
)
end
function solve!(
solver::LearningSolver,
instance::Instance;
tee::Bool = false,
)
return @python_call solver.py.solve(instance.py, tee=tee)
end
function fit!(solver::LearningSolver, instances::Vector{<:Instance})
@python_call solver.py.fit([instance.py for instance in instances])
end
function parallel_solve!(solver::LearningSolver, instances::Vector{FileInstance})
filenames = [instance.filename for instance in instances]
solver_filename = tempname()
save(solver_filename, solver)
@sync @distributed for filename in filenames
s = load_solver(solver_filename)
solve!(s, FileInstance(filename))
nothing
end
end
function save(filename::AbstractString, solver::LearningSolver)
@info "Writing: $filename"
time = @elapsed begin
# Pickle solver.py
internal_solver = solver.py.internal_solver
internal_solver_prototype = solver.py.internal_solver_prototype
solver.py.internal_solver = nothing
solver.py.internal_solver_prototype = nothing
solver_py_filename = tempname()
miplearn.write_pickle_gz(solver.py, solver_py_filename, quiet=true)
solver_py = read(solver_py_filename)
solver.py.internal_solver = internal_solver
solver.py.internal_solver_prototype = internal_solver_prototype
jldsave(
filename;
miplearn_version="0.2",
solver_py=solver_py,
optimizer_factory=solver.optimizer_factory,
)
end
@info @sprintf("File written in %.2f seconds", time)
return
end
function load_solver(filename::AbstractString)::LearningSolver
@info "Reading: $filename"
solver = nothing
time = @elapsed begin
jldopen(filename, "r") do file
_check_miplearn_version(file)
solve_py_filename = tempname()
write(solve_py_filename, file["solver_py"])
solver_py = miplearn.read_pickle_gz(solve_py_filename, quiet=true)
internal_solver = JuMPSolver(file["optimizer_factory"])
solver_py.internal_solver_prototype = internal_solver
solver = LearningSolver(
solver_py,
file["optimizer_factory"],
)
end
end
@info @sprintf("File read in %.2f seconds", time)
return solver
end
export Instance,
LearningSolver,
solve!,
fit!,
parallel_solve!,
save,
load_solver