feat: CBC-style threaded branch & bound (-threads N)#25
Open
andig wants to merge 1 commit into
Open
Conversation
Opportunistic parallel tree search as CBC's: N workers over a shared node heap, incumbent and pseudocost arrays, each worker on its own problem copy + LP (reduced-cost fixing mutates column bounds, and a factor's solve scratch belongs to the LP that built it). Nodes crossing the shared heap carry a Portable() basis — status/values only, no factorization — and the receiving worker refactorizes, the same contract as CBC handing CoinWarmStartBasis between threads. Each worker re-applies reduced-cost fixing when another worker tightens the incumbent. In-tree cut generation stays serial-only (local cut rows would be dangling row indices in other workers' problems). Serial (Threads<=1) runs the same treeSearch code path with uncontended locks: 018/020/021 keep bit-identical nodes, pivots and objectives vs main (7/31746, 774/182619, 3/62278). Benchmarks: 90x30 multi-knapsack 1.58s -> 0.19s at 8 threads (8.4x, same optimum); 020 10.4s -> 7.8s at 4 threads (1.33x) with the same node-inflation pattern real CBC shows there (271 -> 832 nodes, 1.25x). Race detector clean over unit tests and a full threaded 020 solve. 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.
Adds
Model.Threads/ CLI-threads N: opportunistic parallel branch & bound modeled on CBC's.Design
State.Portable()carries status/basicOf/value only; the receiving worker'swarmSolverefactorizes on first use — the same contract as CBC handingCoinWarmStartBasisbetween threads. Within a plunge the full factorized state is kept as before.Threads<=1runs the identicaltreeSearchcode path with uncontended locks — 018/020/021 keep bit-identical nodes/pivots/objectives vs main (7/31746, 774/182619, 3/62278).Benchmarks
Real CBC on 020 shows the same shape: t=1→t=4 is 2.0s→1.6s (1.25×) with nodes inflating 271→832; opportunistic parallel B&B trades node count for wall clock, and dive-dominated trees gain little. Objectives across thread counts differ only within the configured gap (GapAbs 1e-5), as with real CBC.
Race detector clean over the unit tests and a full threaded 020 solve (96s under
-race, zero warnings).🤖 Generated with Claude Code