CBC-drawn performance stack: factorized basis, presolve, GMI cuts, heuristics#11
Merged
Conversation
Replaces the dense-inverse simplex core: - two-phase singleton triangularization with a sparse-LU kernel and product-form eta updates (O(nnz) pivots, periodic refactorization), property-tested against a dense reference on random bases - dual simplex for warm re-solves after bound changes: incremental duals (y absorbs each pivot row), lazily materialized reduced costs, long-step bound flips, a sparse pivot row via a row-wise mirror of A, and a pivot cap that bails degenerate runs to the primal - EXPAND anti-degeneracy (Gill et al.): working bounds widen per pivot with a guaranteed minimum step, exact snap-back at refactorization, and a cleanup re-price before concluding Optimal/Infeasible - full Bland's rule (entering and leaving) after degenerate streaks, Clp-style bound perturbation in cold solves with clean-bound restore Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Iterated activity-based bound tightening and big-M coefficient tightening, plus CglProbing-style binary probing: infeasible sides fix the binary, merged implied bounds apply to integer columns only (continuous merges compound outward-rounding drift along equality chains into bound collapse), and derived bounds round outward by the row's error scale. Probing is time-boxed and skipped on restart passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Gomory mixed-integer cuts from fractional basic integers with support/dynamism hygiene and normalization; probing implication cuts (CglProbing as a cut generator) whose implied bounds are slackened against propagation drift, gated to large instances; TwoMIR-lite pairwise tableau aggregations through the shared MIR derivation; poison batches retract with retries and slack cuts drop before the tree so only root-active rows ride into node re-solves. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Best-first search with depth-first plunging, warm-started child bases, wall-clock deadlines (Limits.MaxTime becomes a time.Duration; the CLI flag converts), node-level bound propagation at branching, monotone bounds, a bound-based optimality proof at exit, reduced-cost fixing re-run on every improving incumbent, SOS1/SOS2 via Beale-Tomlin splitting, and a same-model restart that inherits cuts, fixings and probe facts (bound continuity across passes). Branching: strong branching to depth 6 on large instances (16 otherwise) with 80ms probes — shorter probes leave most unresolved and branching blind; a probe side that is infeasible or cannot beat the incumbent fixes the variable at the node without spending a branch (CBC strong-branch fixing); pseudocosts select deeper. Heuristics, all time-boxed (root burst MaxTime/3, deeper MaxTime/8): completed MIP start, face walk (least-degradation dive holding the LP on its optimal face at a fixed LP-noise tolerance — proves degenerate alternate-optima instances outright at the root), 1-opt incumbent polish via single-bound warm dual re-solves (CbcHeuristicLocal), RENS with single-shot rounding, batch rounding dive, feasibility pump, and RINS with exponential failure backoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Marchand-Wolsey c-MIR over aggregated equality chains: maximal-path walk of the EQ multigraph, exact variable-bound substitution (x = M*z - slack, the slack carried through MIR as the continuous negative part and re-substituted afterwards), divisor/complement search, violation-based separation. The sound derivation separates zero violated cuts at the golden-case roots — GMI plus probing cuts dominate this cut space — so the generator stays unwired, with a property test that brute-forces feasible points of random chain MIPs against every generated cut (it caught an unsound earlier draft that substituted the VUB as an inequality and cut off optima). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MIP performance: CBC/Clp-drawn optimizations for the optimizer golden cases
Goal: all 13 optimizer golden cases (
optimizer/test_cases/*.json) passingTestGoldenCaseswithin a 30s solver budget. Techniques drawn from COIN-OR CBC/Clp, validated against real CBC (bundled PuLP binary,msg=1logs, incl. a preprocess-off control run).Scoreboard (30s budget)
12/13 pass (009–019 in 0.3–5.2s, 021 in 11s).
What's in this PR
Simplex / LP
Presolve / cuts
Branch & bound
Primal heuristics
Case 020 — final ledger
Models verified identical to the Python reference; real CBC needs 1–2s. cbcgo now finds an incumbent inside the tests' economics tolerance at node 1 (0.36158 vs optimum 0.36146) and proves a bound of 0.347–0.357 vs the 0.361 needed — 94% of the original bound distance closed. A 60s budget does not close the rest: the residual is structural. Scoped follow-ups: multi-row aggregation cuts (pairwise TwoMIR is in; full c-MIR needs more), CglPreProcess-style row/column elimination (CBC works on a 4× reduced model), dual-EXPAND (cap 2048 helps 020 but perturbs 021's face-walk trajectory).
🤖 Generated with Claude Code