From 1dd03052140615888ca1bb2c1d0ec6e11e74d3e0 Mon Sep 17 00:00:00 2001 From: adityasinghz Date: Mon, 24 Nov 2025 20:36:46 +0530 Subject: [PATCH] Fix lower bound calculation during ramp-up phase in parallel B&B During the ramp-up phase in parallel B&B, cuOpt was using the root objective as the global lower bound when the heap was empty. This is a pessimistic estimation that doesn't reflect the actual lower bounds calculated by active threads during ramp-up. Changes: - Use get_lower_bound() instead of root_objective_ fallback at end of solve() - Use get_lower_bound() in ramp-up logging instead of root_objective_ The get_lower_bound() function properly considers: - lower_bound_ceiling_ (updated during ramp-up) - Heap top (if heap is not empty) - All local_lower_bounds_ from active threads This ensures the lower bound accurately reflects the work done by active threads during ramp-up, not just the root objective. --- cpp/src/dual_simplex/branch_and_bound.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/src/dual_simplex/branch_and_bound.cpp b/cpp/src/dual_simplex/branch_and_bound.cpp index 9f207b6a6..06628cdb2 100644 --- a/cpp/src/dual_simplex/branch_and_bound.cpp +++ b/cpp/src/dual_simplex/branch_and_bound.cpp @@ -733,7 +733,7 @@ void branch_and_bound_t::exploration_ramp_up(search_tree_t* stats_.last_log = tic(); f_t obj = compute_user_objective(original_lp_, upper_bound); - f_t user_lower = compute_user_objective(original_lp_, root_objective_); + f_t user_lower = compute_user_objective(original_lp_, get_lower_bound()); std::string gap_user = user_mip_gap(obj, user_lower); settings_.log.printf(" %10d %10lu %+13.6e %+10.6e %6d %7.1e %s %9.2f\n", @@ -1226,7 +1226,7 @@ mip_status_t branch_and_bound_t::solve(mip_solution_t& solut } } - f_t lower_bound = heap_.size() > 0 ? heap_.top()->lower_bound : search_tree.root.lower_bound; + f_t lower_bound = get_lower_bound(); return set_final_solution(solution, lower_bound); }