Skip to content

Avoid fixing zero-cost singleton columns to infinite bounds in HPresolve::dualFixing#3046

Merged
jajhall merged 7 commits into
ERGO-Code:fix-3046from
fwesselm:zeroCostCol
Jun 14, 2026
Merged

Avoid fixing zero-cost singleton columns to infinite bounds in HPresolve::dualFixing#3046
jajhall merged 7 commits into
ERGO-Code:fix-3046from
fwesselm:zeroCostCol

Conversation

@fwesselm

@fwesselm fwesselm commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator
  1. Avoid fixing zero-cost singleton columns to infinite bounds in HPresolve::dualFixing.
  2. Add logic to HPresolve::singletonCol handling zero-cost singletons.
  3. Ran 850+ MIPs - HiGHS' behavior was not affected.

@fwesselm fwesselm requested a review from Opt-Mucca June 3, 2026 18:20
@codecov

codecov Bot commented Jun 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.94%. Comparing base (dd33e6e) to head (2de9763).
⚠️ Report is 1 commits behind head on latest.

Files with missing lines Patch % Lines
highs/presolve/HPresolve.cpp 66.66% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           latest    #3046      +/-   ##
==========================================
- Coverage   72.94%   72.94%   -0.01%     
==========================================
  Files         426      426              
  Lines      102185   102197      +12     
  Branches    16443    16452       +9     
==========================================
+ Hits        74540    74544       +4     
- Misses      27369    27377       +8     
  Partials      276      276              

☔ 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.

@Opt-Mucca

Copy link
Copy Markdown
Collaborator

@fwesselm It is a bit late and I'm quite tired, so may be missing something: Why do we want to do this? Aren't we now potentially missing some reductions that we were making before, e.g., an unbounded column with no locks on one-side that wouldn't appear as a singleton?

@jajhall

jajhall commented Jun 9, 2026

Copy link
Copy Markdown
Member

@Opt-Mucca : I'm guessing that fixing zero-cost singletons in this way is a special case (when there are no up/down locks) of #2962

Correct?

@Opt-Mucca

Copy link
Copy Markdown
Collaborator

@jajhall My confusion comes from columns that have multiple down (or up) locks, but zero in the other direction, and now aren't fixed to inf (or -inf). Wouldn't this fixing be useful and make the rows they feature in redundant after the fixing? (I have a feeling I may be missing something)

@Opt-Mucca

Copy link
Copy Markdown
Collaborator

@fwesselm After discussing with @jajhall : Was there any instance where this raised an error? It does look like it would require some conditional logic for the LP basis in postsolve.

@fwesselm

Copy link
Copy Markdown
Collaborator Author

@fwesselm After discussing with @jajhall : Was there any instance where this raised an error? It does look like it would require some conditional logic for the LP basis in postsolve.

@Opt-Mucca, yes, for a particular model (which I have to find again), dual fixing tries to fix a zero-cost column to an infinite bound. In this case, HPresolve::fixColToLower or HPresolve::fixColToUpper directly return Result::kDualInfeasible.

I agree that it may be possible to handle the case that a variable is fixed to +-kHighsInf, but postsolve does not currently (I think).

@jajhall

jajhall commented Jun 10, 2026

Copy link
Copy Markdown
Member

@Opt-Mucca, yes, for a particular model (which I have to find again), dual fixing tries to fix a zero-cost column to an infinite bound. In this case, HPresolve::fixColToLower or HPresolve::fixColToUpper directly return Result::kDualInfeasible.

I agree that it may be possible to handle the case that a variable is fixed to +-kHighsInf, but postsolve does not currently (I think).

I talked this through with @Opt-Mucca: no variable must ever be explicitly fixed to infinity.

The presolve reduction is achieved by removing the column with whatever bounds it has. The bounds on the corresponding rows are modified, possibly making a finite bound infinite if one/both of the column bounds are infinite.

Then, in postsolve, when the column is restored it is either

  • nonbasic at a finite bound if the corresponding constraints would then be satisfied
  • basic at a finite value so that all the corresponding constraints are satisfied - with at least one satisfied exactly. All the corresponding constraints would have been basic, so the binding constraint is made nonbasic at that bound, and the restored column becomes the basic variable.

The only safeguard that I see having to be added is that all the coefficients in the column must be sufficiently large, as they may become pivots when replacing the 1 of the slack variable in the binding row.

@jajhall jajhall changed the base branch from latest to fix-3052 June 14, 2026 14:55
@jajhall jajhall changed the base branch from fix-3052 to fix-3046 June 14, 2026 14:55
@jajhall

jajhall commented Jun 14, 2026

Copy link
Copy Markdown
Member

I need to test fwesselm:zeroCostCol and make sure there are no merge conflicts with zero-obj-singleton-double-sided-row

@jajhall jajhall merged commit 2f19954 into ERGO-Code:fix-3046 Jun 14, 2026
349 of 351 checks passed
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.

3 participants