diff --git a/src/Cuts/Cuts.jl b/src/Cuts/Cuts.jl index b2a4254..afa60c7 100644 --- a/src/Cuts/Cuts.jl +++ b/src/Cuts/Cuts.jl @@ -10,7 +10,6 @@ include("tableau/structs.jl") # include("blackbox/cplex.jl") include("tableau/numerics.jl") -include("tableau/collect.jl") include("tableau/gmi.jl") include("tableau/moi.jl") include("tableau/tableau.jl") diff --git a/src/Cuts/tableau/gmi.jl b/src/Cuts/tableau/gmi.jl index fd04b36..14febbb 100644 --- a/src/Cuts/tableau/gmi.jl +++ b/src/Cuts/tableau/gmi.jl @@ -154,7 +154,7 @@ function collect_gmi( else all_cuts.lhs = [all_cuts.lhs; cuts.lhs[keep, :]] all_cuts.lb = [all_cuts.lb; cuts.lb[keep]] - all_cuts.lb = [all_cuts.lb; cuts.lb[keep]] + all_cuts.ub = [all_cuts.ub; cuts.ub[keep]] end push!(stats_ncuts, length(all_cuts.lb)) diff --git a/test/Project.toml b/test/Project.toml index e5abcbf..ce8384e 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -17,6 +17,7 @@ MIPLearn = "2b1277c3-b477-4c49-a15e-7ba350325c68" PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" SCIP = "82193955-e24f-5292-bf16-6f2c5261a85f" +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] diff --git a/test/fixtures/bell5.h5 b/test/fixtures/bell5.h5 index afff1ab..541b0a6 100644 Binary files a/test/fixtures/bell5.h5 and b/test/fixtures/bell5.h5 differ diff --git a/test/fixtures/vpm2.h5 b/test/fixtures/vpm2.h5 index 9481679..fc4a159 100644 Binary files a/test/fixtures/vpm2.h5 and b/test/fixtures/vpm2.h5 differ diff --git a/test/src/BB/test_bb.jl b/test/src/BB/test_bb.jl index cf51bc7..62a7eab 100644 --- a/test/src/BB/test_bb.jl +++ b/test/src/BB/test_bb.jl @@ -86,11 +86,7 @@ function bb_run(optimizer_name, optimizer; large = true) BB.ReliabilityBranching(aggregation = :min, collect = true), ] h5 = H5File("$FIXTURES/$instance.h5") - mip_lower_bound = h5.get_scalar("mip_lower_bound") - mip_upper_bound = h5.get_scalar("mip_upper_bound") - mip_sense = h5.get_scalar("mip_sense") - mip_primal_bound = - mip_sense == "min" ? mip_upper_bound : mip_lower_bound + mip_obj_bound = h5.get_scalar("mip_obj_bound") h5.file.close() mip = BB.init(optimizer) @@ -98,7 +94,7 @@ function bb_run(optimizer_name, optimizer; large = true) @info optimizer_name, branch_rule, instance @time BB.solve!( mip, - initial_primal_bound = mip_primal_bound, + initial_primal_bound = mip_obj_bound, print_interval = 1, node_limit = 25, branch_rule = branch_rule, diff --git a/test/src/Cuts/tableau/test_gmi.jl b/test/src/Cuts/tableau/test_gmi.jl new file mode 100644 index 0000000..af286c7 --- /dev/null +++ b/test/src/Cuts/tableau/test_gmi.jl @@ -0,0 +1,23 @@ +# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization +# Copyright (C) 2020-2024, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +using HiGHS + +function test_cuts_tableau_gmi() + mps_filename = "$BASEDIR/../fixtures/bell5.mps.gz" + h5_filename = "$BASEDIR/../fixtures/bell5.h5" + collect_gmi(mps_filename, optimizer = HiGHS.Optimizer) + h5 = H5File(h5_filename, "r") + try + cuts_lb = h5.get_array("cuts_lb") + cuts_ub = h5.get_array("cuts_ub") + cuts_lhs = h5.get_sparse("cuts_lhs") + n_cuts = length(cuts_lb) + @test n_cuts > 0 + @test n_cuts == length(cuts_ub) + @test cuts_lhs.shape[1] == n_cuts + finally + h5.close() + end +end diff --git a/test/src/MIPLearnT.jl b/test/src/MIPLearnT.jl index c783574..f91d315 100644 --- a/test/src/MIPLearnT.jl +++ b/test/src/MIPLearnT.jl @@ -19,6 +19,7 @@ include("BB/test_bb.jl") include("components/test_cuts.jl") include("components/test_lazy.jl") include("Cuts/BlackBox/test_cplex.jl") +include("Cuts/tableau/test_gmi.jl") include("problems/test_setcover.jl") include("problems/test_stab.jl") include("problems/test_tsp.jl") diff --git a/test/src/test_io.jl b/test/src/test_io.jl index 95c0087..88745f9 100644 --- a/test/src/test_io.jl +++ b/test/src/test_io.jl @@ -4,6 +4,7 @@ using MIPLearn using JLD2 +using SparseArrays struct _TestStruct n::Int @@ -35,6 +36,8 @@ function test_h5() _test_roundtrip_array(h5, [1, 2, 3]) _test_roundtrip_array(h5, [1.0, 2.0, 3.0]) _test_roundtrip_str_array(h5, ["A", "BB", "CCC"]) + _test_roundtrip_sparse(h5, sparse([1; 2; 3], [1; 2; 3], [1; 2; 3])) + # _test_roundtrip_sparse(h5, sparse([1; 2; 3], [1; 2; 3], [1; 2; 3], 4, 4)) @test h5.get_array("unknown-key") === nothing h5.close() end @@ -79,3 +82,11 @@ function _test_roundtrip_str_array(h5, original) @test recovered !== nothing @test all(original .== recovered) end + +function _test_roundtrip_sparse(h5, original) + h5.put_sparse("key", original) + recovered = MIPLearn.convert(SparseMatrixCSC, h5.get_sparse("key")) + @test recovered !== nothing + @test size(original) == size(recovered) + @test all(original .== recovered) +end