@@ -265,6 +265,51 @@ i_t branch_and_bound_t<i_t, f_t>::get_heap_size()
265265 return size;
266266}
267267
268+ template <typename i_t , typename f_t >
269+ void branch_and_bound_t <i_t , f_t >::report_heuristic(f_t obj)
270+ {
271+ if (solver_status_ == mip_exploration_status_t ::RUNNING) {
272+ f_t user_obj = compute_user_objective (original_lp_, obj);
273+ f_t user_lower = compute_user_objective (original_lp_, get_lower_bound ());
274+ std::string user_gap = user_mip_gap<f_t >(user_obj, user_lower);
275+
276+ settings_.log .printf (
277+ " H %+13.6e %+10.6e %s %9.2f\n " ,
278+ user_obj,
279+ user_lower,
280+ user_gap.c_str (),
281+ toc (exploration_stats_.start_time ));
282+ } else {
283+ settings_.log .printf (" New solution from primal heuristics. Objective %+.6e. Time %.2f\n " ,
284+ compute_user_objective (original_lp_, obj),
285+ toc (exploration_stats_.start_time ));
286+ }
287+ }
288+
289+ template <typename i_t , typename f_t >
290+ void branch_and_bound_t <i_t , f_t >::report(std::string symbol,
291+ f_t obj,
292+ f_t lower_bound,
293+ i_t node_depth)
294+ {
295+ i_t nodes_explored = exploration_stats_.nodes_explored ;
296+ i_t nodes_unexplored = exploration_stats_.nodes_unexplored ;
297+ f_t user_obj = compute_user_objective (original_lp_, obj);
298+ f_t user_lower = compute_user_objective (original_lp_, lower_bound);
299+ f_t iter_node = exploration_stats_.total_lp_iters / nodes_explored;
300+ std::string user_gap = user_mip_gap<f_t >(user_obj, user_lower);
301+ settings_.log .printf (" %s%10d %10lu %+13.6e %+10.6e %6d %7.1e %s %9.2f\n " ,
302+ symbol.c_str (),
303+ nodes_explored,
304+ nodes_unexplored,
305+ user_obj,
306+ user_lower,
307+ node_depth,
308+ iter_node,
309+ user_gap.c_str (),
310+ toc (exploration_stats_.start_time ));
311+ }
312+
268313template <typename i_t , typename f_t >
269314void branch_and_bound_t <i_t , f_t >::set_new_solution(const std::vector<f_t >& solution)
270315{
@@ -303,25 +348,7 @@ void branch_and_bound_t<i_t, f_t>::set_new_solution(const std::vector<f_t>& solu
303348 }
304349 mutex_upper_.unlock ();
305350
306- if (is_feasible) {
307- if (solver_status_ == mip_exploration_status_t ::RUNNING) {
308- f_t user_obj = compute_user_objective (original_lp_, obj);
309- f_t user_lower = compute_user_objective (original_lp_, get_lower_bound ());
310- std::string gap = user_mip_gap<f_t >(user_obj, user_lower);
311-
312- settings_.log .printf (
313- " H %+13.6e %+10.6e %s %9.2f\n " ,
314- user_obj,
315- user_lower,
316- gap.c_str (),
317- toc (exploration_stats_.start_time ));
318- } else {
319- settings_.log .printf (" New solution from primal heuristics. Objective %+.6e. Time %.2f\n " ,
320- compute_user_objective (original_lp_, obj),
321- toc (exploration_stats_.start_time ));
322- }
323- }
324-
351+ if (is_feasible) { report_heuristic (obj); }
325352 if (attempt_repair) {
326353 mutex_repair_.lock ();
327354 repair_queue_.push_back (crushed_solution);
@@ -417,17 +444,7 @@ void branch_and_bound_t<i_t, f_t>::repair_heuristic_solutions()
417444 if (repaired_obj < upper_bound_) {
418445 upper_bound_ = repaired_obj;
419446 incumbent_.set_incumbent_solution (repaired_obj, repaired_solution);
420-
421- f_t obj = compute_user_objective (original_lp_, repaired_obj);
422- f_t lower = compute_user_objective (original_lp_, get_lower_bound ());
423- std::string user_gap = user_mip_gap<f_t >(obj, lower);
424-
425- settings_.log .printf (
426- " H %+13.6e %+10.6e %s %9.2f\n " ,
427- obj,
428- lower,
429- user_gap.c_str (),
430- toc (exploration_stats_.start_time ));
447+ report_heuristic (repaired_obj);
431448
432449 if (settings_.solution_callback != nullptr ) {
433450 std::vector<f_t > original_x;
@@ -523,31 +540,13 @@ void branch_and_bound_t<i_t, f_t>::add_feasible_solution(f_t leaf_objective,
523540 i_t leaf_depth,
524541 thread_type_t thread_type)
525542{
526- bool send_solution = false ;
527- i_t nodes_explored = exploration_stats_.nodes_explored ;
528- i_t nodes_unexplored = exploration_stats_.nodes_unexplored ;
543+ bool send_solution = false ;
529544
530545 mutex_upper_.lock ();
531546 if (leaf_objective < upper_bound_) {
532547 incumbent_.set_incumbent_solution (leaf_objective, leaf_solution);
533- upper_bound_ = leaf_objective;
534- f_t lower_bound = get_lower_bound ();
535- f_t obj = compute_user_objective (original_lp_, upper_bound_);
536- f_t lower = compute_user_objective (original_lp_, lower_bound);
537- f_t iter_node = nodes_explored > 0 ? static_cast <f_t >(exploration_stats_.total_lp_iters ) /
538- static_cast <f_t >(nodes_explored)
539- : 0 ;
540- settings_.log .printf (" %s%10d %10lu %+13.6e %+10.6e %6d %7.1e %s %9.2f\n " ,
541- feasible_solution_symbol (thread_type),
542- nodes_explored,
543- nodes_unexplored,
544- obj,
545- lower,
546- leaf_depth,
547- iter_node,
548- user_mip_gap<f_t >(obj, lower).c_str (),
549- toc (exploration_stats_.start_time ));
550-
548+ upper_bound_ = leaf_objective;
549+ report (feasible_solution_symbol (thread_type), leaf_objective, get_lower_bound (), leaf_depth);
551550 send_solution = true ;
552551 }
553552
@@ -813,25 +812,7 @@ void branch_and_bound_t<i_t, f_t>::exploration_ramp_up(mip_node_t<i_t, f_t>* nod
813812 bool should_report = should_report_.exchange (false );
814813
815814 if (should_report) {
816- f_t obj = compute_user_objective (original_lp_, upper_bound);
817- f_t user_lower = compute_user_objective (original_lp_, root_objective_);
818- std::string gap_user = user_mip_gap<f_t >(obj, user_lower);
819- i_t nodes_explored = exploration_stats_.nodes_explored ;
820- i_t nodes_unexplored = exploration_stats_.nodes_unexplored ;
821- f_t iter_node = nodes_explored > 0 ? static_cast <f_t >(exploration_stats_.total_lp_iters ) /
822- static_cast <f_t >(nodes_explored)
823- : 0 ;
824-
825- settings_.log .printf (" %10d %10lu %+13.6e %+10.6e %6d %7.1e %s %9.2f\n " ,
826- nodes_explored,
827- nodes_unexplored,
828- obj,
829- user_lower,
830- node->depth ,
831- iter_node,
832- gap_user.c_str (),
833- now);
834-
815+ report (" " , upper_bound, root_objective_, node->depth );
835816 exploration_stats_.nodes_since_last_log = 0 ;
836817 exploration_stats_.last_log = tic ();
837818 should_report_ = true ;
@@ -946,24 +927,7 @@ void branch_and_bound_t<i_t, f_t>::explore_subtree(i_t task_id,
946927 abs_gap < 10 * settings_.absolute_mip_gap_tol ) &&
947928 time_since_last_log >= 1 ) ||
948929 (time_since_last_log > 30 ) || now > settings_.time_limit ) {
949- f_t obj = compute_user_objective (original_lp_, upper_bound);
950- f_t user_lower = compute_user_objective (original_lp_, get_lower_bound ());
951- std::string gap_user = user_mip_gap<f_t >(obj, user_lower);
952- i_t nodes_explored = exploration_stats_.nodes_explored ;
953- i_t nodes_unexplored = exploration_stats_.nodes_unexplored ;
954- f_t iter_node = nodes_explored > 0 ? static_cast <f_t >(exploration_stats_.total_lp_iters ) /
955- static_cast <f_t >(nodes_explored)
956- : 0 ;
957-
958- settings_.log .printf (" %10d %10lu %+13.6e %+10.6e %6d %7.1e %s %9.2f\n " ,
959- nodes_explored,
960- nodes_unexplored,
961- obj,
962- user_lower,
963- node_ptr->depth ,
964- iter_node,
965- gap_user.c_str (),
966- now);
930+ report (" " , upper_bound, get_lower_bound (), node_ptr->depth );
967931 exploration_stats_.last_log = tic ();
968932 exploration_stats_.nodes_since_last_log = 0 ;
969933 }
@@ -1462,7 +1426,7 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
14621426 " | Explored | Unexplored | Objective | Bound | Depth | Iter/Node | Gap "
14631427 " | Time |\n " );
14641428
1465- exploration_stats_.nodes_explored = 0 ;
1429+ exploration_stats_.nodes_explored = 1 ;
14661430 exploration_stats_.nodes_unexplored = 2 ;
14671431 exploration_stats_.nodes_since_last_log = 0 ;
14681432 exploration_stats_.last_log = tic ();
0 commit comments