mirror of
https://github.com/ANL-CEEESA/MIPLearn.jl.git
synced 2025-12-06 00:18:51 -06:00
Implement lazy callbacks
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
[deps]
|
||||
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||
Cbc = "9961bab8-2fa3-5c5a-9d89-47fab24efd76"
|
||||
Clp = "e2554f3b-3117-50c0-817c-e040a3ddf72d"
|
||||
Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d"
|
||||
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
||||
Gurobi = "2e9cd046-0924-5485-92f1-d5272153d98b"
|
||||
JSON2 = "2535ab7d-5cd8-5a07-80ac-9b1792aadce3"
|
||||
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
|
||||
MIPLearn = "2b1277c3-b477-4c49-a15e-7ba350325c68"
|
||||
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
|
||||
MIPLearn = "2b1277c3-b477-4c49-a15e-7ba350325c68"
|
||||
PackageCompiler = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d"
|
||||
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||||
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
|
||||
|
||||
@@ -2,29 +2,62 @@
|
||||
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
|
||||
using Cbc
|
||||
using JuMP
|
||||
using MathOptInterface
|
||||
using MIPLearn
|
||||
const MOI = MathOptInterface
|
||||
|
||||
function find_lazy(model::Model, cb_data)::Vector{String}
|
||||
x = variable_by_name(model, "x")
|
||||
y = variable_by_name(model, "y")
|
||||
x_val = value(cb_data, x)
|
||||
y_val = value(cb_data, y)
|
||||
if x_val + y_val > 1 + 1e-6
|
||||
return ["con"]
|
||||
end
|
||||
return []
|
||||
end
|
||||
|
||||
@testset "JuMPInstance" begin
|
||||
@testset "Save and load" begin
|
||||
# Build instance and solve
|
||||
model = model = build_knapsack_model()
|
||||
function enforce_lazy(model::Model, cb_data, violation::String)::Nothing
|
||||
if violation == "con"
|
||||
x = variable_by_name(model, "x")
|
||||
y = variable_by_name(model, "y")
|
||||
con = @build_constraint(x + y <= 1)
|
||||
submit(cb_data, con)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
function build_model()
|
||||
model = Model()
|
||||
@variable(model, x, Bin)
|
||||
@variable(model, y, Bin)
|
||||
@objective(model, Max, 2 * x + y)
|
||||
@constraint(model, c1, x + y <= 2)
|
||||
@lazycb(model, find_lazy, enforce_lazy)
|
||||
return model
|
||||
end
|
||||
|
||||
@testset "Lazy callback" begin
|
||||
@testset "JuMPInstance" begin
|
||||
model = build_model()
|
||||
instance = JuMPInstance(model)
|
||||
solver = LearningSolver(Gurobi.Optimizer)
|
||||
stats = solve!(solver, instance)
|
||||
@test length(instance.py.samples) == 1
|
||||
solver = LearningSolver(Cbc.Optimizer)
|
||||
solve!(solver, instance)
|
||||
@test value(model[:x]) == 1.0
|
||||
@test value(model[:y]) == 0.0
|
||||
end
|
||||
|
||||
# Save model to file
|
||||
@testset "FileInstance" begin
|
||||
model = build_model()
|
||||
instance = JuMPInstance(model)
|
||||
filename = tempname()
|
||||
save(filename, instance)
|
||||
@test isfile(filename)
|
||||
|
||||
# Read model from file
|
||||
loaded = load_instance(filename)
|
||||
x = variable_by_name(loaded.model, "x")
|
||||
@test loaded.model.ext[:miplearn][:variable_features][x] == [1.0]
|
||||
@test loaded.model.ext[:miplearn][:variable_categories][x] == "cat1"
|
||||
@test loaded.model.ext[:miplearn][:instance_features] == [5.0]
|
||||
@test length(loaded.py.samples) == 1
|
||||
file_instance = FileInstance(filename, lazycb = (find_lazy, enforce_lazy))
|
||||
solver = LearningSolver(Cbc.Optimizer)
|
||||
solve!(solver, file_instance)
|
||||
h5 = MIPLearn.Hdf5Sample(filename)
|
||||
@test h5.get_array("mip_var_values") == [1.0, 0.0]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,6 +10,7 @@ MIPLearn.setup_logger()
|
||||
@testset "MIPLearn" begin
|
||||
include("fixtures/knapsack.jl")
|
||||
include("instance/file_test.jl")
|
||||
include("instance/jump_test.jl")
|
||||
include("solvers/jump_test.jl")
|
||||
include("solvers/learning_test.jl")
|
||||
include("utils/benchmark_test.jl")
|
||||
|
||||
Reference in New Issue
Block a user