@@ -1683,12 +1683,74 @@ HPresolve::Result HPresolve::runProbing(HighsPostsolveStack& postsolve_stack) {
16831683 };
16841684 }
16851685
1686+ // Set up logging for probing
1687+ const bool silent = silentLog ();
1688+ HighsInt iBin = -1 ;
1689+ HighsInt iBin_probed = -1 ;
1690+ HighsInt num_binary = binaries.size ();
1691+ double tt = this ->timer ->read ();
1692+ double tt0 = tt;
1693+ double log_tt = tt0;
1694+ HighsInt log_iBin_probed = iBin_probed;
1695+ auto probingLog = [&]() {
1696+ if (silent || options->timeless_log ) return ;
1697+ // Ensure that enough time has elapsed, and at least on binary
1698+ // has been probed
1699+ const double log_tt_interval = 5.0 ;
1700+ if (tt > log_tt + log_tt_interval && iBin_probed > log_iBin_probed) {
1701+ // Get the average rate from the start of probing
1702+ assert (iBin_probed > 0 );
1703+ double rate0 = (tt - tt0) / double (iBin_probed);
1704+ // Get the average rate since last logging
1705+ HighsInt dl_iBin_probed = iBin_probed - log_iBin_probed;
1706+ assert (dl_iBin_probed > 0 );
1707+ double rate1 = (tt - log_tt) / double (dl_iBin_probed);
1708+ // Assess the time for probing based on the greater rate
1709+ double rate = std::max (rate0, rate1);
1710+ std::string rate_str =
1711+ " (rate " + highsTimeToString (1e3 * rate) + " /ms" ;
1712+ double expected_probing_finish_time =
1713+ tt + rate * (num_binary - iBin_probed);
1714+ std::string expected_probing_finish_time_str =
1715+ " => expected probing finish time " +
1716+ highsTimeSecondToString (expected_probing_finish_time) + " )" ;
1717+ std::string time_str = highsTimeSecondToString (tt);
1718+ highsLogUser (options->log_options , HighsLogType::kInfo ,
1719+ " Considered %d / %d binaries; %d probed %s%s %s\n " ,
1720+ int (iBin), int (num_binary), int (iBin_probed),
1721+ rate_str.c_str (), expected_probing_finish_time_str.c_str (),
1722+ time_str.c_str ());
1723+ log_tt = tt;
1724+ log_iBin_probed = iBin_probed;
1725+ }
1726+ };
1727+
16861728 for (const auto & binvar : binaries) {
1687- HighsInt i = std::get<3 >(binvar);
1729+ // Count the binaries considered
1730+ iBin++;
16881731
1732+ HighsInt i = std::get<3 >(binvar);
16891733 if (cliquetable.getSubstitution (i) != nullptr || !domain.isBinary (i))
16901734 continue ;
16911735
1736+ // Count the binaries probed
1737+ iBin_probed++;
1738+
1739+ // Check for timeout
1740+ tt = this ->timer ->read ();
1741+ if (tt > options->time_limit ) {
1742+ highsLogUser (options->log_options , HighsLogType::kInfo ,
1743+ " Time limit reached in probing: "
1744+ " consider not using probing by setting option "
1745+ " presolve_rule_off to 2^%-d = %d\n " ,
1746+ int (kPresolveRuleProbing ),
1747+ int (std::pow (int (2 ), int (kPresolveRuleProbing ))));
1748+ return Result::kStopped ;
1749+ }
1750+
1751+ // Possibly log probing
1752+ probingLog ();
1753+
16921754 bool tightenLimits = (numProbed - oldNumProbed) >= 2500 ;
16931755
16941756 // when a large percentage of columns have been deleted, stop this round
@@ -1761,9 +1823,6 @@ HPresolve::Result HPresolve::runProbing(HighsPostsolveStack& postsolve_stack) {
17611823 if (numLiftOpps >= maxNumLiftOpps)
17621824 implications.storeLiftingOpportunity = nullptr ;
17631825
1764- // printf("nprobed: %" HIGHSINT_FORMAT ", numCliques: %" HIGHSINT_FORMAT
1765- // "\n", nprobed,
1766- // cliquetable.numCliques());
17671826 if (domain.infeasible ()) {
17681827 mipsolver->analysis_ .mipTimerStop (kMipClockProbingPresolve );
17691828 return Result::kPrimalInfeasible ;
@@ -5468,31 +5527,29 @@ HPresolve::Result HPresolve::presolve(HighsPostsolveStack& postsolve_stack) {
54685527 model->sense_ = ObjSense::kMinimize ;
54695528 }
54705529
5530+ const bool silent = silentLog ();
5531+ if (options->presolve != kHighsOffString ) {
5532+ if (!silent)
5533+ highsLogUser (options->log_options , HighsLogType::kInfo ,
5534+ " Presolving model\n " );
5535+ }
54715536 // Set up the logic to allow presolve rules, and logging for their
54725537 // effectiveness
54735538 analysis_.setup (this ->model , this ->options , this ->numDeletedRows ,
5474- this ->numDeletedCols );
5539+ this ->numDeletedCols , silent );
54755540
54765541 if (options->presolve != kHighsOffString ) {
54775542 if (mipsolver) mipsolver->mipdata_ ->cliquetable .setPresolveFlag (true );
5478- if (!mipsolver || mipsolver->mipdata_ ->numRestarts == 0 )
5479- highsLogUser (options->log_options , HighsLogType::kInfo ,
5480- " Presolving model\n " );
54815543
54825544 auto report = [&]() {
5483- if (!mipsolver || mipsolver-> mipdata_ -> numRestarts == 0 ) {
5545+ if (!silent ) {
54845546 HighsInt numCol = model->num_col_ - numDeletedCols;
54855547 HighsInt numRow = model->num_row_ - numDeletedRows;
54865548 HighsInt numNonz =
54875549 static_cast <HighsInt>(Avalue.size () - freeslots.size ());
54885550 // Only read the run time if it's to be printed
54895551 const double run_time = options->output_flag ? this ->timer ->read () : 0 ;
5490- #ifndef NDEBUG
5491- std::string time_str = " " + std::to_string (run_time) + " s" ;
5492- #else
5493- std::string time_str =
5494- " " + std::to_string (static_cast <int >(run_time)) + " s" ;
5495- #endif
5552+ std::string time_str = highsTimeSecondToString (run_time);
54965553 if (options->timeless_log ) time_str = " " ;
54975554 highsLogUser (options->log_options , HighsLogType::kInfo ,
54985555 " %" HIGHSINT_FORMAT " rows, %" HIGHSINT_FORMAT
@@ -5972,6 +6029,10 @@ HighsCDouble HPresolve::computeDynamism(
59726029 static_cast <HighsCDouble>(minAbsCoef);
59736030}
59746031
6032+ bool HPresolve::silentLog () const {
6033+ return mipsolver && mipsolver->mipdata_ ->numRestarts > 0 ;
6034+ }
6035+
59756036HighsModelStatus HPresolve::run (HighsPostsolveStack& postsolve_stack) {
59766037 presolve_status_ = HighsPresolveStatus::kNotSet ;
59776038 shrinkProblemEnabled = true ;
@@ -6171,28 +6232,31 @@ HPresolve::Result HPresolve::removeDependentEquations(
61716232 const double time_limit =
61726233 std::max (1.0 , std::min (0.01 * options->time_limit , 1000.0 ));
61736234 factor.setTimeLimit (time_limit);
6235+ const bool silent = silentLog ();
61746236 // Determine rank deficiency of the equations
6175- highsLogUser (options->log_options , HighsLogType::kInfo ,
6176- " Dependent equations search running on %d equations with time "
6177- " limit of %.2fs\n " ,
6178- static_cast <int >(matrix.num_col_ ), time_limit);
6237+ if (!silent)
6238+ highsLogUser (options->log_options , HighsLogType::kInfo ,
6239+ " Dependent equations search running on %d equations with time "
6240+ " limit of %.2fs\n " ,
6241+ static_cast <int >(matrix.num_col_ ), time_limit);
61796242 double time_taken = -this ->timer ->read ();
61806243 HighsInt build_return = factor.build ();
61816244 time_taken += this ->timer ->read ();
61826245 if (build_return == kBuildKernelReturnTimeout ) {
61836246 // HFactor::build has timed out, so just return
6184- highsLogUser (options->log_options , HighsLogType::kInfo ,
6185- " Dependent equations search terminated after %.3gs due to "
6186- " expected time exceeding limit\n " ,
6187- time_taken);
6247+ if (!silent)
6248+ highsLogUser (options->log_options , HighsLogType::kInfo ,
6249+ " Dependent equations search terminated after %.3gs due to "
6250+ " expected time exceeding limit\n " ,
6251+ time_taken);
61886252 analysis_.logging_on_ = logging_on;
61896253 if (logging_on)
61906254 analysis_.stopPresolveRuleLog (kPresolveRuleDependentFreeCols );
61916255 return Result::kOk ;
61926256 } else {
61936257 double pct_off_timeout =
61946258 1e2 * std::fabs (time_taken - time_limit) / time_limit;
6195- if (pct_off_timeout < 1.0 )
6259+ if (!silent && pct_off_timeout < 1.0 )
61966260 highsLogUser (options->log_options , HighsLogType::kWarning ,
61976261 " Dependent equations search finished within %.2f%% of limit "
61986262 " of %.2fs: "
@@ -6217,11 +6281,12 @@ HPresolve::Result HPresolve::removeDependentEquations(
62176281 num_fictitious_rows_skipped++;
62186282 }
62196283 }
6220- highsLogUser (options->log_options , HighsLogType::kInfo ,
6221- " Dependent equations search removed %d rows and %d nonzeros "
6222- " in %.2fs (limit = %.2fs)\n " ,
6223- static_cast <int >(num_removed_row),
6224- static_cast <int >(num_removed_nz), time_taken, time_limit);
6284+ if (!silent)
6285+ highsLogUser (options->log_options , HighsLogType::kInfo ,
6286+ " Dependent equations search removed %d rows and %d nonzeros "
6287+ " in %.2fs (limit = %.2fs)\n " ,
6288+ static_cast <int >(num_removed_row),
6289+ static_cast <int >(num_removed_nz), time_taken, time_limit);
62256290 if (num_fictitious_rows_skipped)
62266291 highsLogDev (options->log_options , HighsLogType::kInfo ,
62276292 " , avoiding %d fictitious rows" ,
0 commit comments