@@ -919,7 +919,7 @@ struct nondeterministic_policy_t : tree_update_policy_t<i_t, f_t> {
919919 {
920920 }
921921
922- f_t upper_bound () const override { return bnb.upper_bound_ . load (); }
922+ f_t upper_bound () const override { return bnb.get_cutoff (); }
923923
924924 void update_pseudo_costs (mip_node_t <i_t , f_t >* node, f_t leaf_obj) override
925925 {
@@ -1337,10 +1337,11 @@ dual::status_t branch_and_bound_t<i_t, f_t>::solve_node_lp(
13371337
13381338 simplex_solver_settings_t lp_settings = settings_;
13391339 lp_settings.set_log (false );
1340+ f_t cutoff = get_cutoff ();
13401341 if (original_lp_.objective_is_integral ) {
1341- lp_settings.cut_off = std::ceil (upper_bound_ - settings_.integer_tol ) + settings_.dual_tol ;
1342+ lp_settings.cut_off = std::ceil (cutoff - settings_.integer_tol ) + settings_.dual_tol ;
13421343 } else {
1343- lp_settings.cut_off = upper_bound_ + settings_.dual_tol ;
1344+ lp_settings.cut_off = cutoff + settings_.dual_tol ;
13441345 }
13451346 lp_settings.inside_mip = 2 ;
13461347 lp_settings.time_limit = settings_.time_limit - toc (exploration_stats_.start_time );
@@ -1447,7 +1448,7 @@ void branch_and_bound_t<i_t, f_t>::plunge_with(branch_and_bound_worker_t<i_t, f_
14471448 // - The lower bound of the parent is lower or equal to its children
14481449 worker->lower_bound = lower_bound;
14491450
1450- if (lower_bound > upper_bound ) {
1451+ if (lower_bound > get_cutoff () ) {
14511452 search_tree_.graphviz_node (settings_.log , node_ptr, " cutoff" , node_ptr->lower_bound );
14521453 search_tree_.update (node_ptr, node_status_t ::FATHOMED);
14531454 worker->recompute_basis = true ;
@@ -1557,7 +1558,7 @@ void branch_and_bound_t<i_t, f_t>::dive_with(branch_and_bound_worker_t<i_t, f_t>
15571558 f_t rel_gap = user_relative_gap (original_lp_, upper_bound, lower_bound);
15581559 worker->lower_bound = lower_bound;
15591560
1560- if (node_ptr->lower_bound > upper_bound ) {
1561+ if (node_ptr->lower_bound > get_cutoff () ) {
15611562 worker->recompute_basis = true ;
15621563 worker->recompute_bounds = true ;
15631564 continue ;
@@ -1696,7 +1697,7 @@ void branch_and_bound_t<i_t, f_t>::run_scheduler()
16961697 std::optional<mip_node_t <i_t , f_t >*> start_node = node_queue_.pop_best_first ();
16971698
16981699 if (!start_node.has_value ()) { continue ; }
1699- if (upper_bound_ < start_node.value ()->lower_bound ) {
1700+ if (get_cutoff () < start_node.value ()->lower_bound ) {
17001701 // This node was put on the heap earlier but its lower bound is now greater than the
17011702 // current upper bound
17021703 search_tree_.graphviz_node (
@@ -1720,7 +1721,7 @@ void branch_and_bound_t<i_t, f_t>::run_scheduler()
17201721 std::optional<mip_node_t <i_t , f_t >*> start_node = node_queue_.pop_diving ();
17211722
17221723 if (!start_node.has_value ()) { continue ; }
1723- if (upper_bound_ < start_node.value ()->lower_bound ||
1724+ if (get_cutoff () < start_node.value ()->lower_bound ||
17241725 start_node.value ()->depth < diving_settings.min_node_depth ) {
17251726 continue ;
17261727 }
@@ -1788,7 +1789,7 @@ void branch_and_bound_t<i_t, f_t>::single_threaded_solve()
17881789 std::optional<mip_node_t <i_t , f_t >*> start_node = node_queue_.pop_best_first ();
17891790
17901791 if (!start_node.has_value ()) { continue ; }
1791- if (upper_bound_ < start_node.value ()->lower_bound ) {
1792+ if (get_cutoff () < start_node.value ()->lower_bound ) {
17921793 // This node was put on the heap earlier but its lower bound is now greater than the
17931794 // current upper bound
17941795 search_tree_.graphviz_node (
@@ -2275,12 +2276,12 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
22752276 return mip_status_t ::NUMERICAL;
22762277 }
22772278
2278- if (settings_.reduced_cost_strengthening >= 1 && upper_bound_. load () < last_upper_bound) {
2279+ if (settings_.reduced_cost_strengthening >= 1 && get_cutoff () < last_upper_bound) {
22792280 mutex_upper_.lock ();
2280- last_upper_bound = upper_bound_. load ();
2281+ last_upper_bound = get_cutoff ();
22812282 std::vector<f_t > lower_bounds;
22822283 std::vector<f_t > upper_bounds;
2283- find_reduced_cost_fixings (upper_bound_. load (), lower_bounds, upper_bounds);
2284+ find_reduced_cost_fixings (get_cutoff (), lower_bounds, upper_bounds);
22842285 mutex_upper_.unlock ();
22852286 mutex_original_lp_.lock ();
22862287 original_lp_.lower = lower_bounds;
@@ -2467,10 +2468,10 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
24672468 return solver_status_;
24682469 }
24692470
2470- if (settings_.reduced_cost_strengthening >= 2 && upper_bound_. load () < last_upper_bound) {
2471+ if (settings_.reduced_cost_strengthening >= 2 && get_cutoff () < last_upper_bound) {
24712472 std::vector<f_t > lower_bounds;
24722473 std::vector<f_t > upper_bounds;
2473- i_t num_fixed = find_reduced_cost_fixings (upper_bound_. load (), lower_bounds, upper_bounds);
2474+ i_t num_fixed = find_reduced_cost_fixings (get_cutoff (), lower_bounds, upper_bounds);
24742475 if (num_fixed > 0 ) {
24752476 std::vector<bool > bounds_changed (original_lp_.num_cols , true );
24762477 std::vector<char > row_sense;
@@ -2574,7 +2575,7 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
25742575 std::optional<mip_node_t <i_t , f_t >*> start_node = node_queue_.pop_best_first ();
25752576
25762577 if (!start_node.has_value ()) { continue ; }
2577- if (upper_bound_ < start_node.value ()->lower_bound ) {
2578+ if (get_cutoff () < start_node.value ()->lower_bound ) {
25782579 // This node was put on the heap earlier but its lower bound is now greater than the
25792580 // current upper bound
25802581 search_tree_.graphviz_node (
@@ -3416,7 +3417,7 @@ void branch_and_bound_t<i_t, f_t>::deterministic_sort_replay_events(
34163417template <typename i_t , typename f_t >
34173418void branch_and_bound_t <i_t , f_t >::deterministic_prune_worker_nodes_vs_incumbent()
34183419{
3419- f_t upper_bound = upper_bound_. load ();
3420+ f_t upper_bound = get_cutoff ();
34203421
34213422 for (auto & worker : *deterministic_workers_) {
34223423 // Check nodes in plunge stack - filter in place
@@ -3552,14 +3553,14 @@ void branch_and_bound_t<i_t, f_t>::deterministic_populate_diving_heap()
35523553 const int num_diving = deterministic_diving_workers_->size ();
35533554 constexpr int target_nodes_per_worker = 10 ;
35543555 const int target_total = num_diving * target_nodes_per_worker;
3555- f_t upper_bound = upper_bound_. load ();
3556+ f_t cutoff = get_cutoff ();
35563557
35573558 // Collect candidate nodes from BFS worker backlog heaps
35583559 std::vector<std::pair<mip_node_t <i_t , f_t >*, f_t >> candidates;
35593560
35603561 for (auto & worker : *deterministic_workers_) {
35613562 for (auto * node : worker.backlog .data ()) {
3562- if (node->lower_bound < upper_bound ) {
3563+ if (node->lower_bound < cutoff ) {
35633564 f_t score = node->objective_estimate ;
35643565 if (score >= inf) { score = node->lower_bound ; }
35653566 candidates.push_back ({node, score});
0 commit comments