@@ -292,8 +292,6 @@ void HighsMipSolver::run() {
292292 double lowerBoundLastCheck = mipdata_->lower_bound ;
293293 analysis_.mipTimerStart (kMipClockSearch );
294294
295- int k = 0 ;
296-
297295 // Initialize worker relaxations and mipworkers
298296 // todo lps and workers are still empty right now
299297
@@ -303,7 +301,11 @@ void HighsMipSolver::run() {
303301 mipdata_->workers .emplace_back (*this , mipdata_->lps .back ());
304302 }
305303
304+ int k = 0 ;
305+
306306 while (search.hasNode ()) {
307+
308+ if (k % 2 == 0 ) {
307309
308310
309311 // Possibly look for primal solution from the user
@@ -764,10 +766,185 @@ void HighsMipSolver::run() {
764766 analysis_.node_search_time .push_back (this_node_search_time);
765767 }
766768 if (limit_reached) break ;
769+
770+ } else {
771+ {
772+
773+ HighsMipWorker& worker = mipdata_->workers .at (1 );
774+ HighsSearch& worker_search = *worker.search_ptr_ .get ();
775+ HighsLpRelaxation& worker_lp_relax = worker.lprelaxation_ ;
776+
777+ analysis_.mipTimerStart (kMipClockPerformAging1 );
778+ worker.conflictpool_ .performAging ();
779+ // mipdata_.conflictPool_.performAging();
780+ analysis_.mipTimerStop (kMipClockPerformAging1 );
781+ // set iteration limit for each lp solve during the dive to 10 times the
782+ // average nodes
783+
784+ HighsInt iterlimit = 10 * std::max (mipdata_->lp .getAvgSolveIters (),
785+ mipdata_->avgrootlpiters );
786+ iterlimit = std::max ({HighsInt{10000 }, iterlimit,
787+ HighsInt ((3 * mipdata_->firstrootlpiters ) / 2 )});
788+
789+ // mipdata_->lp.setIterationLimit(iterlimit);
790+ worker_lp_relax.setIterationLimit (iterlimit);
791+
792+
793+ // perform the dive and put the open nodes to the queue
794+ size_t plungestart = mipdata_->num_nodes ;
795+ bool limit_reached = false ;
796+
797+ // atm heuristics in the dive break lseu debug64
798+ // bool considerHeuristics = true;
799+ bool considerHeuristics = false ;
800+
801+ analysis_.mipTimerStart (kMipClockDive );
802+ while (true ) {
803+ // Possibly apply primal heuristics
804+ // if (considerHeuristics && mipdata_->moreHeuristicsAllowed()) {
805+ // analysis_.mipTimerStart(kMipClockDiveEvaluateNode);
806+ // const HighsSearch::NodeResult evaluate_node_result =
807+ // search.evaluateNode();
808+ // analysis_.mipTimerStop(kMipClockDiveEvaluateNode);
809+
810+ // if (evaluate_node_result == HighsSearch::NodeResult::kSubOptimal) break;
811+
812+ // if (search.currentNodePruned()) {
813+ // // ig: do we update num_leaves here?
814+ // ++mipdata_->num_leaves;
815+ // search.flushStatistics();
816+ // } else {
817+ // analysis_.mipTimerStart(kMipClockDivePrimalHeuristics);
818+ // if (mipdata_->incumbent.empty()) {
819+ // analysis_.mipTimerStart(kMipClockDiveRandomizedRounding);
820+ // mipdata_->heuristics.randomizedRounding(
821+ // master_worker,
822+ // mipdata_->lp.getLpSolver().getSolution().col_value);
823+ // analysis_.mipTimerStop(kMipClockDiveRandomizedRounding);
824+ // }
825+
826+ // if (mipdata_->incumbent.empty()) {
827+ // if (options_mip_->mip_heuristic_run_rens) {
828+ // analysis_.mipTimerStart(kMipClockDiveRens);
829+ // mipdata_->heuristics.RENS(
830+ // master_worker,
831+ // mipdata_->lp.getLpSolver().getSolution().col_value);
832+ // analysis_.mipTimerStop(kMipClockDiveRens);
833+ // }
834+ // } else {
835+ // if (options_mip_->mip_heuristic_run_rins) {
836+ // analysis_.mipTimerStart(kMipClockDiveRins);
837+ // mipdata_->heuristics.RINS(
838+ // master_worker,
839+ // mipdata_->lp.getLpSolver().getSolution().col_value);
840+ // analysis_.mipTimerStop(kMipClockDiveRins);
841+ // }
842+ // }
843+
844+ // mipdata_->heuristics.flushStatistics(master_worker);
845+ // analysis_.mipTimerStop(kMipClockDivePrimalHeuristics);
846+ // }
847+ // }
848+
849+ considerHeuristics = false ;
850+
851+ if (mipdata_->domain .infeasible ()) break ;
852+
853+ if (worker_search.getDomain ().infeasible ()) continue ;
854+
855+
856+ // install node here?
857+ search.installNode (mipdata_->nodequeue .popBestBoundNode ());
858+
859+
860+ if (!worker_search.currentNodePruned ()) {
861+ double this_dive_time = -analysis_.mipTimerRead (kMipClockTheDive );
862+ analysis_.mipTimerStart (kMipClockTheDive );
863+ const HighsSearch::NodeResult search_dive_result = worker_search.dive ();
864+ analysis_.mipTimerStop (kMipClockTheDive );
865+ if (analysis_.analyse_mip_time ) {
866+ this_dive_time += analysis_.mipTimerRead (kMipClockNodeSearch );
867+ analysis_.dive_time .push_back (this_dive_time);
868+ }
869+ if (search_dive_result == HighsSearch::NodeResult::kSubOptimal ) break ;
870+
871+ ++mipdata_->num_leaves ;
872+
873+ worker_search.flushStatistics ();
874+ }
875+
876+ if (mipdata_->checkLimits ()) {
877+ limit_reached = true ;
878+ break ;
879+ }
880+
881+ // disable because it needs nodequeue
882+ // HighsInt numPlungeNodes = mipdata_->num_nodes - plungestart;
883+ // if (numPlungeNodes >= 100) break;
884+
885+ // analysis_.mipTimerStart(kMipClockBacktrackPlunge);
886+ // const bool backtrack_plunge = search.backtrackPlunge(mipdata_->nodequeue);
887+ // analysis_.mipTimerStop(kMipClockBacktrackPlunge);
888+ // if (!backtrack_plunge) break;
889+
890+
891+ assert (worker_search.hasNode ());
892+
893+ // if (mipdata_->conflictPool.getNumConflicts() >
894+ if (worker.conflictpool_ .getNumConflicts () >
895+ options_mip_->mip_pool_soft_limit ) {
896+ analysis_.mipTimerStart (kMipClockPerformAging2 );
897+ worker.conflictpool_ .performAging ();
898+ // mipdata_->conflictPool.performAging();
899+ analysis_.mipTimerStop (kMipClockPerformAging2 );
900+ }
901+
902+ worker_search.flushStatistics ();
903+ mipdata_->printDisplayLine ();
904+ // printf("continue plunging due to good estimate\n");
905+ } // while (true)
906+ analysis_.mipTimerStop (kMipClockDive );
907+
908+ analysis_.mipTimerStart (kMipClockOpenNodesToQueue0 );
909+
910+ // needs sync
911+ // maybe there should be a nodequeue in the search after all
912+ worker.syncNodeQueue (mipdata_->nodequeue );
913+
914+ // search.openNodesToQueue(mipdata_->nodequeue);
915+ analysis_.mipTimerStop (kMipClockOpenNodesToQueue0 );
916+
917+ worker_search.flushStatistics ();
918+
919+ // if (limit_reached) {
920+ // double prev_lower_bound = mipdata_->lower_bound;
921+
922+ // mipdata_->lower_bound = std::min(mipdata_->upper_bound,
923+ // mipdata_->nodequeue.getBestLowerBound());
924+
925+ // bool bound_change = mipdata_->lower_bound != prev_lower_bound;
926+ // if (!submip && bound_change)
927+ // mipdata_->updatePrimalDualIntegral(
928+ // prev_lower_bound, mipdata_->lower_bound, mipdata_->upper_bound,
929+ // mipdata_->upper_bound);
930+ // mipdata_->printDisplayLine();
931+ // break;
932+ // }
933+
934+ // the search datastructure should have no installed node now
935+ assert (!worker_search.hasNode ());
936+
937+ if (limit_reached) break ;
938+
939+ }
940+
941+ }
942+
767943 } // while(search.hasNode())
768944 analysis_.mipTimerStop (kMipClockSearch );
769945
770946 cleanupSolve ();
947+
771948}
772949
773950void HighsMipSolver::cleanupSolve () {
0 commit comments