@@ -458,6 +458,55 @@ void HighsMipSolver::run() {
458458 return false ;
459459 };
460460
461+ auto getSearchIndicesWithNoNodes = [&]() -> std::vector<HighsInt> {
462+ std::vector<HighsInt> search_indices;
463+ for (HighsInt i = 0 ; i < mip_search_concurrency; i++) {
464+ if (!mipdata_->workers [i].search_ptr_ ->hasNode ()) {
465+ search_indices.emplace_back (i);
466+ }
467+ }
468+ if (search_indices.size () > mipdata_->nodequeue .numActiveNodes ()) {
469+ search_indices.resize (mipdata_->nodequeue .numActiveNodes ());
470+ }
471+ return search_indices;
472+ };
473+
474+ auto installNodes = [&](std::vector<HighsInt>& search_indices,
475+ bool & limit_reached) -> void {
476+ for (HighsInt index : search_indices) {
477+ // TODO MT: Remove this dummy if statement
478+ if (index != 0 ) return ;
479+ if (numQueueLeaves - lastLbLeave >= 10 ) {
480+ mipdata_->workers [index].search_ptr_ ->installNode (
481+ mipdata_->nodequeue .popBestBoundNode ());
482+ lastLbLeave = numQueueLeaves;
483+ } else {
484+ HighsInt bestBoundNodeStackSize =
485+ mipdata_->nodequeue .getBestBoundDomchgStackSize ();
486+ double bestBoundNodeLb = mipdata_->nodequeue .getBestLowerBound ();
487+ HighsNodeQueue::OpenNode nextNode (mipdata_->nodequeue .popBestNode ());
488+ if (nextNode.lower_bound == bestBoundNodeLb &&
489+ (HighsInt)nextNode.domchgstack .size () == bestBoundNodeStackSize)
490+ lastLbLeave = numQueueLeaves;
491+ mipdata_->workers [index].search_ptr_ ->installNode (std::move (nextNode));
492+ }
493+
494+ ++numQueueLeaves;
495+
496+ if (mipdata_->workers [index].search_ptr_ ->getCurrentEstimate () >=
497+ mipdata_->upper_limit ) {
498+ ++numStallNodes;
499+ if (options_mip_->mip_max_stall_nodes != kHighsIInf &&
500+ numStallNodes >= options_mip_->mip_max_stall_nodes ) {
501+ limit_reached = true ;
502+ modelstatus_ = HighsModelStatus::kSolutionLimit ;
503+ break ;
504+ }
505+ } else
506+ numStallNodes = 0 ;
507+ }
508+ };
509+
461510 auto diveAllSearches = [&]() -> bool {
462511 std::vector<double > dive_times (mip_search_concurrency,
463512 -analysis_.mipTimerRead (kMipClockTheDive ));
@@ -802,36 +851,11 @@ void HighsMipSolver::run() {
802851 while (!mipdata_->nodequeue .empty ()) {
803852 // printf("popping node from nodequeue (length = %" HIGHSINT_FORMAT ")\n",
804853 // (HighsInt)nodequeue.size());
805- assert (!search.hasNode ());
806-
807- if (numQueueLeaves - lastLbLeave >= 10 ) {
808- search.installNode (mipdata_->nodequeue .popBestBoundNode ());
809- lastLbLeave = numQueueLeaves;
810- } else {
811- HighsInt bestBoundNodeStackSize =
812- mipdata_->nodequeue .getBestBoundDomchgStackSize ();
813- double bestBoundNodeLb = mipdata_->nodequeue .getBestLowerBound ();
814- HighsNodeQueue::OpenNode nextNode (mipdata_->nodequeue .popBestNode ());
815- if (nextNode.lower_bound == bestBoundNodeLb &&
816- (HighsInt)nextNode.domchgstack .size () == bestBoundNodeStackSize)
817- lastLbLeave = numQueueLeaves;
818- search.installNode (std::move (nextNode));
819- }
820-
821- ++numQueueLeaves;
822-
823- if (search.getCurrentEstimate () >= mipdata_->upper_limit ) {
824- ++numStallNodes;
825- if (options_mip_->mip_max_stall_nodes != kHighsIInf &&
826- numStallNodes >= options_mip_->mip_max_stall_nodes ) {
827- limit_reached = true ;
828- modelstatus_ = HighsModelStatus::kSolutionLimit ;
829- break ;
830- }
831- } else
832- numStallNodes = 0 ;
854+ std::vector<HighsInt> search_indices = getSearchIndicesWithNoNodes ();
855+ // if (search_indices.size() >= mip_search_concurrency) break;
833856
834- assert (search.hasNode ());
857+ installNodes (search_indices, limit_reached);
858+ if (limit_reached) break ;
835859
836860 // we evaluate the node directly here instead of performing a dive
837861 // because we first want to check if the node is not fathomed due to
0 commit comments