Skip to content

Add logging and time budget for probing in presolve, and increase visibility of presolve rule switch-off#2865

Merged
jajhall merged 10 commits intolatestfrom
fix-2860
Feb 24, 2026
Merged

Add logging and time budget for probing in presolve, and increase visibility of presolve rule switch-off#2865
jajhall merged 10 commits intolatestfrom
fix-2860

Conversation

@jajhall
Copy link
Member

@jajhall jajhall commented Feb 21, 2026

The potentially prohibitive high cost of probing means that there should be some logging so that HiGHS doesn't go "quiet", and this has been added.

The high cost is mitigated by giving probing a budget of 10% of time_limit. It may make the MIP solver non-deterministic if time_limit is finite, but that's better than it "never" returning.

Since this may lead users to want to switch off probing, the ability to switch off more advanced/expensive presolve rules is now visible.

@codecov
Copy link

codecov bot commented Feb 21, 2026

Codecov Report

❌ Patch coverage is 81.25000% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.37%. Comparing base (1df4aa5) to head (06309ae).
⚠️ Report is 18 commits behind head on latest.

Files with missing lines Patch % Lines
highs/presolve/HPresolve.cpp 63.63% 20 Missing ⚠️
highs/presolve/HPresolveAnalysis.cpp 96.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           latest    #2865      +/-   ##
==========================================
+ Coverage   80.35%   80.37%   +0.02%     
==========================================
  Files         348      348              
  Lines       86522    86600      +78     
==========================================
+ Hits        69527    69609      +82     
+ Misses      16995    16991       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jajhall jajhall changed the title Increase visibility of presolve rule switch-off Add logging and time budget for probing in presolve, and increase visibility of presolve rule switch-off Feb 21, 2026
@jajhall jajhall requested a review from fwesselm February 21, 2026 18:36
@jajhall
Copy link
Member Author

jajhall commented Feb 22, 2026

Closes #2860

Copy link
Collaborator

@fwesselm fwesselm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to understand why this particular model is so slow in probing. I think @Opt-Mucca has made some improvements to make probing stop earlier recently. Also, I think I should run the MIP suite to see how this affects performance.


iBin_probed++;
double tt = this->timer->read();
if (tt > log_tt + log_tt_interval && iBin_probed > log_iBin_probed) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that nothing in this if block is done when silent = true, so maybe the outer if-check could look like this:

if (!silent && tt > log_tt + log_tt_interval && iBin_probed > log_iBin_probed)

and then the other checks for !silent could be removed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the block contains the return with Result::kStopped; if the probing time limit is reached. Since that is "lost" in what appears to be just logging tells me that I should refactor this section!

double log_tt = tt0;
HighsInt log_iBin_probed = iBin_probed;
double time_remaining = options->time_limit - tt0;
double probing_time_limit = 0.1 * time_remaining;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that a time limit may be needed, but I also do not really like hard-coding things. However, having an option may also be too much.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, but I felt that something was needed so that users for whom probing is very expensive could get some advantage from it.

Maybe it's better to let probing run to options->time_limit and print a message suggesting that probing in presolve is switched off.

}

const bool silent = mipsolver && mipsolver->mipdata_->numRestarts > 0;
if (options->presolve != kHighsOffString) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!silent && options->presolve != kHighsOffString) ?

if (cliquetable.getSubstitution(i) != nullptr || !domain.isBinary(i))
continue;

iBin_probed++;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth putting the new code that checks the time limit into a lambda? This could also be done later - it would make reading the probing code easier for me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

highsLogUser(options->log_options, HighsLogType::kInfo,
"%" HIGHSINT_FORMAT " rows, %" HIGHSINT_FORMAT
" cols, %" HIGHSINT_FORMAT " nonzeros %s\n",
" cols, %" HIGHSINT_FORMAT " nonzeros %s\n",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the extra space needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't know how that's crept in

model->sense_ = ObjSense::kMinimize;
}

const bool silent = mipsolver && mipsolver->mipdata_->numRestarts > 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth making this a method in HPresolve.h? Maybe not, but anyway:

bool isLogSilent() const {
  return mipsolver && mipsolver->mipdata_->numRestarts > 0;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be more elegant

@jajhall
Copy link
Member Author

jajhall commented Feb 22, 2026

Thanks @fwesselm !

@jajhall jajhall merged commit b174cc9 into latest Feb 24, 2026
366 checks passed
@jajhall jajhall deleted the fix-2860 branch February 24, 2026 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants