fix(presolve): clamp singleton row bound tolerance to machine epsilon - #3204
fix(presolve): clamp singleton row bound tolerance to machine epsilon#3204HuAliAsu wants to merge 2 commits into
Conversation
|
Thanks for these @HuAliAsu Although we'll accept clamping values to avoid underflow, based on the reproducible LP example, your problems are so badly scaled that HiGHS (and other solvers) are likely to have numerical issues (or fail) when trying to solve them. I've tried the reproducible LP example, and HiGHS (without presolve) finds the origin to be optimal - as does a commercial solver. Both solvers give strong warnings about the large values, and recommending that the model be reformulated. Specifically, for the reproducible LP example,
Ideally all variables should have an optimal value of order 1 - or zero - and all binding constraints should have a RHS of order 1. Not only will this improve solver robustness, the solver is likely to run faster. To learn more, look at this JuMP tutorial. |
Problem
When presolving MILP models with large matrix coefficients, HiGHS can erroneously over-tighten integer variable bounds in singleton rows, cutting off valid optimal integer solutions.
Technical Root Cause
In
HPresolve.cpp::removeRowSingletons(line 3273), the bound tolerance for singleton rows is calculated as:When a singleton row has a large matrix coefficient (
val = 10^12),boundTolunderflows to1e-19, which is far below IEEE 754 machine epsilon (2.22e-16).This causes over-rounding during integer bound tightening:
if (isIntegral) newColLower = std::ceil(newColLower - boundTol);If floating-point division noise leaves
newColLowerat3.0000000000000004(instead of3.0), subtracting1e-19has no effect because1e-19is smaller than machine epsilon. Consequently,std::ceil(3.0000000000000004)rounds up to4.0instead of3.0, cutting off valid integer solutions.The Fix
Clamp
boundTolto a minimum threshold of1e-15(IEEE 754 machine epsilon safeguard):