mirror of
https://github.com/ANL-CEEESA/MIPLearn.jl.git
synced 2025-12-06 00:18:51 -06:00
Initial version
This commit is contained in:
65
test/jump_solver_test.jl
Normal file
65
test/jump_solver_test.jl
Normal file
@@ -0,0 +1,65 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
|
||||
using Test
|
||||
using MIPLearn
|
||||
using CPLEX
|
||||
using Gurobi
|
||||
|
||||
@testset "varname_split" begin
|
||||
@test MIPLearn.varname_split("x[1]") == ("x", "1")
|
||||
end
|
||||
|
||||
|
||||
@testset "JuMPSolver" begin
|
||||
for optimizer in [CPLEX.Optimizer, Gurobi.Optimizer]
|
||||
instance = KnapsackInstance([23., 26., 20., 18.],
|
||||
[505., 352., 458., 220.],
|
||||
67.0)
|
||||
model = instance.to_model()
|
||||
|
||||
solver = JuMPSolver(optimizer=optimizer)
|
||||
solver.set_instance(instance, model)
|
||||
solver.set_time_limit(30)
|
||||
solver.set_warm_start(Dict("x" => Dict(
|
||||
"1" => 1.0,
|
||||
"2" => 0.0,
|
||||
"3" => 0.0,
|
||||
"4" => 1.0,
|
||||
)))
|
||||
stats = solver.solve()
|
||||
|
||||
@test stats["Lower bound"] == 1183.0
|
||||
@test stats["Upper bound"] == 1183.0
|
||||
@test stats["Sense"] == "max"
|
||||
@test stats["Wallclock time"] > 0
|
||||
@test length(stats["Log"]) > 100
|
||||
|
||||
solution = solver.get_solution()
|
||||
@test solution["x"]["1"] == 1.0
|
||||
@test solution["x"]["2"] == 0.0
|
||||
@test solution["x"]["3"] == 1.0
|
||||
@test solution["x"]["4"] == 1.0
|
||||
|
||||
stats = solver.solve_lp()
|
||||
@test round(stats["Optimal value"], digits=3) == 1287.923
|
||||
@test length(stats["Log"]) > 100
|
||||
|
||||
solution = solver.get_solution()
|
||||
@test round(solution["x"]["1"], digits=3) == 1.000
|
||||
@test round(solution["x"]["2"], digits=3) == 0.923
|
||||
@test round(solution["x"]["3"], digits=3) == 1.000
|
||||
@test round(solution["x"]["4"], digits=3) == 0.000
|
||||
|
||||
solver.fix(Dict("x" => Dict(
|
||||
"1" => 1.0,
|
||||
"2" => 0.0,
|
||||
"3" => 0.0,
|
||||
"4" => 1.0,
|
||||
)))
|
||||
stats = solver.solve()
|
||||
@test stats["Lower bound"] == 725.0
|
||||
@test stats["Upper bound"] == 725.0
|
||||
end
|
||||
end
|
||||
34
test/knapsack.jl
Normal file
34
test/knapsack.jl
Normal file
@@ -0,0 +1,34 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
|
||||
import MIPLearn: get_instance_features,
|
||||
get_variable_features
|
||||
find_violated_lazy_constraints
|
||||
using JuMP
|
||||
|
||||
struct KnapsackData
|
||||
weights
|
||||
prices
|
||||
capacity
|
||||
end
|
||||
|
||||
function to_model(data::KnapsackData)
|
||||
model = Model()
|
||||
n = length(data.weights)
|
||||
@variable(model, x[1:n], Bin)
|
||||
@objective(model, Max, sum(x[i] * data.prices[i] for i in 1:n))
|
||||
@constraint(model, sum(x[i] * data.weights[i] for i in 1:n) <= data.capacity)
|
||||
return model
|
||||
end
|
||||
|
||||
function get_instance_features(data::KnapsackData)
|
||||
return [0.]
|
||||
end
|
||||
|
||||
|
||||
function get_variable_features(data::KnapsackData, var, index)
|
||||
return [0.]
|
||||
end
|
||||
|
||||
KnapsackInstance = @Instance(KnapsackData)
|
||||
50
test/learning_solver_test.jl
Normal file
50
test/learning_solver_test.jl
Normal file
@@ -0,0 +1,50 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
|
||||
using Test
|
||||
using MIPLearn
|
||||
using CPLEX
|
||||
using Gurobi
|
||||
|
||||
|
||||
@testset "Instance" begin
|
||||
weights = [23., 26., 20., 18.]
|
||||
prices = [505., 352., 458., 220.]
|
||||
capacity = 67.0
|
||||
|
||||
instance = KnapsackInstance(weights, prices, capacity)
|
||||
dump(instance, "tmp/instance.json.gz")
|
||||
|
||||
instance = KnapsackInstance([0.0], [0.0], 0.0)
|
||||
load!(instance, "tmp/instance.json.gz")
|
||||
@test instance.data.weights == weights
|
||||
@test instance.data.prices == prices
|
||||
@test instance.data.capacity == capacity
|
||||
end
|
||||
|
||||
|
||||
@testset "LearningSolver" begin
|
||||
for optimizer in [CPLEX.Optimizer, Gurobi.Optimizer]
|
||||
instance = KnapsackInstance([23., 26., 20., 18.],
|
||||
[505., 352., 458., 220.],
|
||||
67.0)
|
||||
solver = LearningSolver(optimizer=optimizer,
|
||||
mode="heuristic",
|
||||
time_limit=90)
|
||||
stats = solve!(solver, instance)
|
||||
@test instance.solution["x"]["1"] == 1.0
|
||||
@test instance.solution["x"]["2"] == 0.0
|
||||
@test instance.solution["x"]["3"] == 1.0
|
||||
@test instance.solution["x"]["4"] == 1.0
|
||||
@test instance.lower_bound == 1183.0
|
||||
@test instance.upper_bound == 1183.0
|
||||
@test round(instance.lp_solution["x"]["1"], digits=3) == 1.000
|
||||
@test round(instance.lp_solution["x"]["2"], digits=3) == 0.923
|
||||
@test round(instance.lp_solution["x"]["3"], digits=3) == 1.000
|
||||
@test round(instance.lp_solution["x"]["4"], digits=3) == 0.000
|
||||
@test round(instance.lp_value, digits=3) == 1287.923
|
||||
fit!(solver, [instance])
|
||||
solve!(solver, instance)
|
||||
end
|
||||
end
|
||||
14
test/runtests.jl
Normal file
14
test/runtests.jl
Normal file
@@ -0,0 +1,14 @@
|
||||
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||
# Released under the modified BSD license. See COPYING.md for more details.
|
||||
|
||||
using Test
|
||||
using MIPLearn
|
||||
|
||||
MIPLearn.setup_logger()
|
||||
|
||||
@testset "MIPLearn" begin
|
||||
include("knapsack.jl")
|
||||
include("jump_solver_test.jl")
|
||||
include("learning_solver_test.jl")
|
||||
end
|
||||
Reference in New Issue
Block a user