Embedding Dual-Fixing into Probing - #3244
Conversation
Add two new presolve techniques in combining probing and dual fixing
|
@ZhaoWeiWang0319 feel like reviewing the code? I ended up changing a fair bit, but the core is the same. |
|
I clearly still have a bug given the failing tests..... Will fix that now Edit: @ZhaoWeiWang0319 should now be good to review |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## latest #3244 +/- ##
==========================================
+ Coverage 73.21% 73.26% +0.05%
==========================================
Files 445 445
Lines 107890 108385 +495
Branches 17278 17394 +116
==========================================
+ Hits 78990 79408 +418
- Misses 28624 28700 +76
- Partials 276 277 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Thanks for handling this @Opt-Mucca ! There are indeed many helpful modifications, and I will go through them carefully tomorrow! |
|
Hi @Opt-Mucca! Thank you very much for taking this forward and for the substantial cleanup and refactoring. I especially appreciate the work to separate the zero-cost fixings, rework how implications are handled, and resolve the merge, build, and test issues that came up along the way. I have gone through the current implementations. I may be overlooking some details, but I have three questions/observations:
In probing, HiGHS collect lifting opportunities for coefficients in inequalities. A row is recorded when it becomes redundant in probing, but the row slack used to form its lifting coefficient appears to be evaluated only at the end of the probing for a variable. By that point, the domain may already include disagreeing bound changes introduced by Would it make sense to invoke
Based our computational experiments while preparing the paper, dualfixProbing produced substantial presolve reductions on a nontrivial MIPLIB instance I looked around but still did not know why.
I may be missing a subtlety here, but I wonder whether the PS: I tried removing them locally so that more substitutions are allowed, but this alone did not recover the substantial reductions on These may simply be misunderstandings on my side, so please let me know if I have overlooked anything. Thanks again for all the work on this!!! |
|
@ZhaoWeiWang0319 Thank you so much for the review! Glad that you liked the the code-separation of the zero-cost fixings. Even if you're overlooking stuff this review was insanely helpful.
|
|
@ZhaoWeiWang0319 Found the reason for
I was not storing the first implication in Thank you for pointing out this instance! FYI: I'm 95% confident that all other solvers (including SCIP) solve this instance at the root node by replacing some of the knapsack rows by multiple setppc rows using information from the clique table. We've been unable to do this because of the presolve limitations on adding new rows, but this restriction has recently been lifted. It's cool that the instance is now "easily" solvable with a different technique (still takes a non-trivial amount of presolve time). |
@Opt-Mucca Glad that my observations are helpful !! I also noticed some of the other updates - for example, no longer checking The explanation for I think the code now is great, and I want to share more observations on In fact, this instance was a bit of a surprise for us while preparing the paper. When we looked into it, we found many constraints of the form
with all variables binary. In particular, fixing At the same time, this constraint can be disaggregated into so this seems closely related to the setppc/clique-table approach you mentioned. Being able to exploit this structure appears to be quite important for solving this instance effectively. Another interesting observation on As discussed in Section 2.3 of our paper, once dual fixing is embedded into probing, dual substitution is theoretically dominated by our approach. In practice, the situation is slightly less clear because dual substitution scans all rows (meaning that currently HiGHS captures all possibilities for applying dual substitution), whereas probing generally does not probe every binary variable. So - one possibility would be to disable dual substitution when this dual fixing is embedded into probing. Of course, whether that is beneficial overall would need to be evaluated on a larger test set. |
|
@fwesselm This should be ready for a review and for your larger testing framework. I'm getting a 1.5% improvement over three seeds. |
Description
This implement the technique from https://link.springer.com/article/10.1007/s12532-026-00336-z
Locally I've observed 1.5% time improvement and 8% node improvement across all-optimal. It affects roughly 50% of the instances that solve under both settings. That seems to be a bit better than the numbers that are reported in the paper, and I'd chalk it up to (1) I'm using a 30min time limit (2) I happen to have randomly dropped some unlucky MIPLIB instances (3) My implementation is more efficient (4) I fixed some errors in the reference implementation that were missing some fixings.
Edit: Forgot good old (5). I've written incorrect code.
It seems to affect sub-mips extremely heavily, so introduces a lot of noise on instances that are racing for a primal solution. I'd not trust my results without extra testing from @fwesselm (There's not that many instances where the size of the presolved problem changes, and even for those that do, it's usually only a minor reduction)
@fwesselm I tested this before the last commit, so there's a small chance I broke something (I will test it again over the weekend). I realised that copying the object each time a domain is copied doesn't make sense because it's only used in presolve, and now have tried to get a bit fancy with the copy constructors of
HighsDomain. Hopefully this shaves off another small time improvement.Checklist
latestbranch