diff --git a/cpp/src/branch_and_bound/branch_and_bound.cpp b/cpp/src/branch_and_bound/branch_and_bound.cpp index e8c0561e1f..5635ceda49 100644 --- a/cpp/src/branch_and_bound/branch_and_bound.cpp +++ b/cpp/src/branch_and_bound/branch_and_bound.cpp @@ -2691,6 +2691,9 @@ mip_status_t branch_and_bound_t::solve(mip_solution_t& solut if (settings_.deterministic) { queue_external_solution_deterministic(user_assignment, work_units); } else { + if (settings_.solution_callback != nullptr) { + settings_.solution_callback(user_assignment, obj); + } set_solution_from_heuristics(user_assignment); } }; diff --git a/cpp/src/mip_heuristics/solver.cu b/cpp/src/mip_heuristics/solver.cu index d932b1f845..5f136cbf43 100644 --- a/cpp/src/mip_heuristics/solver.cu +++ b/cpp/src/mip_heuristics/solver.cu @@ -507,6 +507,17 @@ solution_t mip_solver_t::run_solver() sol = dm.run_solver(); } // implicit barrier for all tasks created in B&B and heuristics + if (!context.settings.heuristics_only && branch_and_bound->has_solver_space_incumbent()) { + solution_t branch_and_bound_sol(*context.problem_ptr); + branch_and_bound_sol.copy_new_assignment(branch_and_bound_solution.x); + branch_and_bound_sol.compute_feasibility(); + + if (branch_and_bound_sol.get_feasible() && + (!sol.get_feasible() || branch_and_bound_sol.get_objective() < sol.get_objective())) { + sol = std::move(branch_and_bound_sol); + } + } + if (!context.settings.heuristics_only) { if (branch_and_bound_solution.lower_bound > -std::numeric_limits::infinity()) { context.stats.set_solution_bound(