diff --git a/src/bb/optimize.jl b/src/bb/optimize.jl index b81f40f..f87d793 100644 --- a/src/bb/optimize.jl +++ b/src/bb/optimize.jl @@ -58,6 +58,13 @@ function solve!( sleep(0.1) continue else + # Assert node is feasible + _set_node_bounds(node) + status, _ = solve_relaxation!(mip) + @assert status == :Optimal + _unset_node_bounds(node) + + # Find branching variable ids = generate_indices(pool, 2) branch_var = find_branching_var(branch_rule, node, pool) @@ -136,8 +143,7 @@ function _create_node( fractional_variables = Variable[] fractional_values = Float64[] end - n_branch = length(branch_vars) - set_bounds!(mip, branch_vars, zeros(n_branch), ones(n_branch)) + set_bounds!(mip, mip.int_vars, mip.int_vars_lb, mip.int_vars_ub) return Node( mip, index, @@ -197,3 +203,11 @@ function solve!( return pool end + +function _set_node_bounds(node::Node) + set_bounds!(node.mip, node.branch_vars, node.branch_lb, node.branch_ub) +end + +function _unset_node_bounds(node::Node) + set_bounds!(node.mip, node.mip.int_vars, node.mip.int_vars_lb, node.mip.int_vars_ub) +end diff --git a/src/bb/varbranch/reliability.jl b/src/bb/varbranch/reliability.jl index 838edb1..07a262d 100644 --- a/src/bb/varbranch/reliability.jl +++ b/src/bb/varbranch/reliability.jl @@ -34,7 +34,7 @@ function find_branching_var( ] σ = sortperm(pseudocost_scores, rev = true) sorted_vars = node.fractional_variables[σ] - _strong_branch_start(node) + _set_node_bounds(node) no_improv_count, n_sb_calls = 0, 0 max_score, max_var = pseudocost_scores[σ[1]], sorted_vars[1] for (i, var) in enumerate(sorted_vars) @@ -72,6 +72,6 @@ function find_branching_var( end no_improv_count <= rule.look_ahead || break end - _strong_branch_end(node) + _unset_node_bounds(node) return max_var end diff --git a/src/bb/varbranch/strong.jl b/src/bb/varbranch/strong.jl index ec31942..360c2f2 100644 --- a/src/bb/varbranch/strong.jl +++ b/src/bb/varbranch/strong.jl @@ -32,7 +32,7 @@ function find_branching_var(rule::StrongBranching, node::Node, pool::NodePool):: ] σ = sortperm(pseudocost_scores, rev = true) sorted_vars = node.fractional_variables[σ] - _strong_branch_start(node) + _set_node_bounds(node) no_improv_count, call_count = 0, 0 max_score, max_var = (-Inf, -Inf), sorted_vars[1] for (i, var) in enumerate(sorted_vars) @@ -55,7 +55,7 @@ function find_branching_var(rule::StrongBranching, node::Node, pool::NodePool):: no_improv_count <= rule.look_ahead || break call_count <= rule.max_calls || break end - _strong_branch_end(node) + _unset_node_bounds(node) return max_var end @@ -94,11 +94,3 @@ function _strong_branch_score(; end return (obj_change_up * obj_change_down, var.index) end - -function _strong_branch_start(node::Node) - set_bounds!(node.mip, node.branch_vars, node.branch_lb, node.branch_ub) -end - -function _strong_branch_end(node::Node) - set_bounds!(node.mip, node.mip.int_vars, node.mip.int_vars_lb, node.mip.int_vars_ub) -end diff --git a/test/bb/lp_test.jl b/test/bb/lp_test.jl index f3b01fe..3dad52f 100644 --- a/test/bb/lp_test.jl +++ b/test/bb/lp_test.jl @@ -6,6 +6,7 @@ using Clp using JuMP using Test using MIPLearn.BB +using MIPLearn basepath = @__DIR__ @@ -80,17 +81,25 @@ function runtests(optimizer_name, optimizer; large = true) BB.HybridBranching(), ] for branch_rule in branch_rules - filename = "$basepath/../fixtures/vpm2.mps.gz" - mip = BB.init(optimizer) - BB.read!(mip, filename) - @info optimizer_name, branch_rule - @time BB.solve!( - mip, - initial_primal_bound = 13.75, - print_interval = 10, - node_limit = 100, - branch_rule = branch_rule, - ) + for instance in ["bell5", "vpm2"] + h5 = Hdf5Sample("$basepath/../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 + h5.file.close() + + mip = BB.init(optimizer) + BB.read!(mip, "$basepath/../fixtures/$instance.mps.gz") + @info optimizer_name, branch_rule, instance + @time BB.solve!( + mip, + initial_primal_bound = mip_primal_bound, + print_interval = 10, + node_limit = 100, + branch_rule = branch_rule, + ) + end end end end diff --git a/test/fixtures/bell5.h5 b/test/fixtures/bell5.h5 new file mode 100644 index 0000000..24f990b Binary files /dev/null and b/test/fixtures/bell5.h5 differ diff --git a/test/fixtures/bell5.mps.gz b/test/fixtures/bell5.mps.gz new file mode 100644 index 0000000..63739d2 Binary files /dev/null and b/test/fixtures/bell5.mps.gz differ diff --git a/test/fixtures/vpm2.h5 b/test/fixtures/vpm2.h5 new file mode 100644 index 0000000..9481679 Binary files /dev/null and b/test/fixtures/vpm2.h5 differ