From 02a376e4cce40c1436f6f9196e4446af25acf61a Mon Sep 17 00:00:00 2001 From: dhendryc <92737336+dhendryc@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:39:06 +0200 Subject: [PATCH] Do not create child node if the start point is not domain feasible. (#199) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don't create child node if the domain oracle is infeasible. * Set version up after bug fix. * Apply suggestions from code review * Print statement in case assert fails. * Print logs for better bug hunting. * Another try to reproduce error. * Test lower bound against tree.incumbent plus current fw_epsilon. * Have the same seed as in runtests.jl. --------- Co-authored-by: Hendrych Co-authored-by: Mathieu Besançon --- Project.toml | 2 +- src/interface.jl | 3 ++- src/node.jl | 11 +++++++---- test/heuristics.jl | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Project.toml b/Project.toml index 710426c03..6e1fb7f06 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Boscia" uuid = "36b166db-dac5-4d05-b36a-e6c4cef071c9" authors = ["ZIB IOL"] -version = "0.1.27" +version = "0.1.28" [deps] Bonobo = "f7b14807-3d4d-461a-888a-05dd4bca8bc3" diff --git a/src/interface.jl b/src/interface.jl index b496a1ea8..74d0f30fe 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -642,7 +642,8 @@ function postsolve(tree, result, time_ref, verbose, max_iteration_post) else @info "primal >= tree.incumbent" @assert primal <= tree.incumbent + 1e-3 || - isapprox(primal, tree.incumbent, atol=1e-6, rtol=1e-2) + isapprox(primal, tree.incumbent, atol=1e-6, rtol=1e-2) "primal <= tree.incumbent + 1e-3 || + isapprox(primal, tree.incumbent, atol=1e-6, rtol=1e-2): primal=$(primal) and tree.incumbent=$(tree.incumbent)" end @info "postsolve did not improve the solution" primal = tree.incumbent_solution.objective = tree.solutions[1].objective diff --git a/src/node.jl b/src/node.jl index c8af87ac3..170960ebd 100644 --- a/src/node.jl +++ b/src/node.jl @@ -161,15 +161,18 @@ function Bonobo.get_branching_nodes_info(tree::Bonobo.BnBTree, node::FrankWolfeN x_right = FrankWolfe.compute_active_set_iterate!(active_set_right) domain_oracle = tree.root.options[:domain_oracle] - nodes = if !prune_left && !prune_right + domain_right = domain_oracle(x_right) + domain_left = domain_oracle(x_left) + + nodes = if !prune_left && !prune_right && domain_right && domain_left [node_info_left, node_info_right] elseif prune_left [node_info_right] elseif prune_right [node_info_left] - elseif domain_oracle(x_right) + elseif domain_right # x_right in domain [node_info_right] - elseif domain_oracle(x_left) + elseif domain_left # x_left in domain [node_info_left] else warn("No childern nodes can be created.") @@ -320,7 +323,7 @@ function Bonobo.evaluate_node!(tree::Bonobo.BnBTree, node::FrankWolfeNode) elseif node.id == 1 @debug "Lower bound of root node: $(lower_bound)" @debug "Current incumbent: $(tree.incumbent)" - @assert lower_bound <= tree.incumbent + 1e-5 "lower_bound <= tree.incumbent + 1e-5 : $(lower_bound) <= $(tree.incumbent + 1e-5)" + @assert lower_bound <= tree.incumbent + node.fw_dual_gap_limit "lower_bound <= tree.incumbent + node.fw_dual_gap_limit : $(lower_bound) <= $(tree.incumbent + node.fw_dual_gap_limit)" end # Call heuristic diff --git a/test/heuristics.jl b/test/heuristics.jl index 6005832c3..e2422c402 100644 --- a/test/heuristics.jl +++ b/test/heuristics.jl @@ -159,7 +159,7 @@ diffi = x_sol + 0.3 * dir heu = Boscia.Heuristic(Boscia.probability_rounding, 0.6, :probability_rounding) x, _, result = - Boscia.solve(f, grad!, sblmo, fill(0.0, m), fill(1.0, m), int_vars, n, custom_heuristics=[heu], rounding_prob=0.0) + Boscia.solve(f, grad!, sblmo, fill(0.0, m), fill(1.0, m), int_vars, n, custom_heuristics=[heu], rounding_prob=0.0, verbose=false) @test f(x) ≥ f(x_sol) if isapprox(sum(x_sol), N)