@@ -1317,7 +1317,7 @@ dual::status_t branch_and_bound_t<i_t, f_t>::solve_node_lp(
13171317 simplex_solver_settings_t lp_settings = settings_;
13181318 lp_settings.set_log (false );
13191319 if (original_lp_.objective_is_integral ) {
1320- lp_settings.cut_off = std::ceil (upper_bound_ - settings_.integer_tol ) - 1 + settings_.dual_tol ;
1320+ lp_settings.cut_off = std::ceil (upper_bound_ - settings_.integer_tol ) + settings_.dual_tol ;
13211321 } else {
13221322 lp_settings.cut_off = upper_bound_ + settings_.dual_tol ;
13231323 }
@@ -1426,7 +1426,7 @@ void branch_and_bound_t<i_t, f_t>::plunge_with(branch_and_bound_worker_t<i_t, f_
14261426 // - The lower bound of the parent is lower or equal to its children
14271427 worker->lower_bound = lower_bound;
14281428
1429- if (lower_bound > upper_bound || rel_gap < settings_. relative_mip_gap_tol ) {
1429+ if (lower_bound > upper_bound) {
14301430 search_tree_.graphviz_node (settings_.log , node_ptr, " cutoff" , node_ptr->lower_bound );
14311431 search_tree_.update (node_ptr, node_status_t ::FATHOMED);
14321432 worker->recompute_basis = true ;
@@ -1536,7 +1536,7 @@ void branch_and_bound_t<i_t, f_t>::dive_with(branch_and_bound_worker_t<i_t, f_t>
15361536 f_t rel_gap = user_relative_gap (original_lp_, upper_bound, lower_bound);
15371537 worker->lower_bound = lower_bound;
15381538
1539- if (node_ptr->lower_bound > upper_bound || rel_gap < settings_. relative_mip_gap_tol ) {
1539+ if (node_ptr->lower_bound > upper_bound) {
15401540 worker->recompute_basis = true ;
15411541 worker->recompute_bounds = true ;
15421542 continue ;
@@ -2471,8 +2471,30 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
24712471 lower_bound = deterministic_compute_lower_bound ();
24722472 solver_status_ = deterministic_global_termination_status_;
24732473 } else {
2474- lower_bound = node_queue_.best_first_queue_size () > 0 ? node_queue_.get_lower_bound ()
2475- : search_tree_.root .lower_bound ;
2474+ if (node_queue_.best_first_queue_size () > 0 ) {
2475+ // We need to clear the queue and use the info in the search tree for the lower bound
2476+ while (node_queue_.best_first_queue_size () > 0 ) {
2477+ std::optional<mip_node_t <i_t , f_t >*> start_node = node_queue_.pop_best_first ();
2478+
2479+ if (!start_node.has_value ()) { continue ; }
2480+ if (upper_bound_ < start_node.value ()->lower_bound ) {
2481+ // This node was put on the heap earlier but its lower bound is now greater than the
2482+ // current upper bound
2483+ search_tree_.graphviz_node (
2484+ settings_.log , start_node.value (), " cutoff" , start_node.value ()->lower_bound );
2485+ search_tree_.update (start_node.value (), node_status_t ::FATHOMED);
2486+ continue ;
2487+ } else {
2488+ node_queue_.push (
2489+ start_node.value ()); // Needed to ensure we don't lose the correct lower bound
2490+ break ;
2491+ }
2492+ }
2493+ lower_bound = node_queue_.best_first_queue_size () > 0 ? node_queue_.get_lower_bound ()
2494+ : search_tree_.root .lower_bound ;
2495+ } else {
2496+ lower_bound = search_tree_.root .lower_bound ;
2497+ }
24762498 }
24772499 set_final_solution (solution, lower_bound);
24782500 return solver_status_;
@@ -2781,7 +2803,7 @@ void branch_and_bound_t<i_t, f_t>::run_deterministic_bfs_loop(
27812803
27822804 f_t upper_bound = worker.local_upper_bound ;
27832805 f_t rel_gap = user_relative_gap (original_lp_, upper_bound, node->lower_bound );
2784- if (node->lower_bound > upper_bound || rel_gap < settings_. relative_mip_gap_tol ) {
2806+ if (node->lower_bound > upper_bound) {
27852807 worker.current_node = nullptr ;
27862808 worker.record_fathomed (node, node->lower_bound );
27872809 search_tree.update (node, node_status_t ::FATHOMED);
@@ -3570,8 +3592,7 @@ void branch_and_bound_t<i_t, f_t>::deterministic_dive(
35703592
35713593 // Prune check using snapshot upper bound
35723594 f_t rel_gap = user_relative_gap (original_lp_, worker.local_upper_bound , node_ptr->lower_bound );
3573- if (node_ptr->lower_bound > worker.local_upper_bound ||
3574- rel_gap < settings_.relative_mip_gap_tol ) {
3595+ if (node_ptr->lower_bound > worker.local_upper_bound ) {
35753596 worker.recompute_bounds_and_basis = true ;
35763597 continue ;
35773598 }
0 commit comments