Skip to content

Day 4: a dataset where greedy provably misses the optimum (closes #37) - #59

Merged
bgent19 merged 2 commits into
mainfrom
worktree-issue-37-day4-trap
Aug 14, 2026
Merged

Day 4: a dataset where greedy provably misses the optimum (closes #37)#59
bgent19 merged 2 commits into
mainfrom
worktree-issue-37-day4-trap

Conversation

@bgent19

@bgent19 bgent19 commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Closes #37.

Day 4 claims a budget interdictor who always takes the most damaging single lane can end up strictly worse than one that searches — but every shipped dataset agreed with greedy, so the claim had nothing on screen behind it. This adds data/greedy_trap.json, authored at the measured 6-node / 8-lane floor.

exhaustive, k=2:  140 -> 0    removing C->t, D->t
greedy,     k=2:  140 -> 30   removing s->A, s->B

The optimal blockade contains neither of the damage-80 lanes greedy reaches for — greedy fails when the best blockade isn't where the biggest single lane is.

Both load-bearing edge orderings are pinned

Verified by exhaustive sweep, not by assertion:

  • Day 2 (textbook_maxflow.json): of 5,040 orderings, exactly 1,260 (25%) demonstrate cancellation and 2,520 (50%) collapse to a two-iteration trace that silently restores the bug the dataset was replaced to fix. The pinned precedences (s->A before s->C, A->B before A->D) match the cancelling set on all 5,040 — zero disagreements.
  • Trap: of 40,320 orderings, exactly 26,880 (66.7%) preserve the divergence. The pinned condition selects that set exactly.

Both are silent if broken: the files still load and still draw.

Review follow-up

The review caught that the tie-break docstring claimed "first-in-file" while the solver iterated a set of indices — ascending only incidentally for small contiguous values. budget_interdiction now scans sorted(remaining), so file order is a guarantee rather than an accident, and the test asserts greedy's opening lane so the tie-break is pinned by behaviour.

Registry pickup and the data/-parameterised suites required no code or test edits. 216 tests pass.

The heuristic-vs-exact lesson had nothing on screen behind it: every
shipped dataset agrees with greedy. The theater cannot supply a
counterexample -- 0 of 240 single-capacity edits and 0 of 4,335 two-lane
interior edits diverge -- so this instance is authored at the measured
floor of 6 nodes and 8 lanes.

Baseline 140; exhaustive reaches 0 at k=2 by taking both lanes into t;
greedy opens with the damage-80 s->A and stalls at 30.

Both load-bearing JSON edge orderings are now pinned by tests. A sweep of
all 40,320 trap orderings confirms 66.7% preserve the divergence and that
the pinned condition selects exactly that set; a sweep of all 5,040 Day 2
orderings confirms the pinned precedences are exactly the 25% that
demonstrate cancellation.
Both review axes caught the same thing: the edge-order pin explained
greedy's tie-break as first-in-file, but the candidate scan iterated a
set of indices, which is ascending only incidentally for small contiguous
values. Sort the scan so the datasets' edge order is something the solver
guarantees, and assert greedy's opening lane so the tie-break is pinned by
behaviour rather than assumed.

Also pin that k=1 falls short at 60 (otherwise 'exhaustive reaches 0 at
k=2' says nothing), name the optimal pair C->t/D->t rather than counting
it, assert the lane count so a duplicate lane cannot hide in the capacity
map, and give the two datasets' edge-order reads a single home.
@bgent19
bgent19 merged commit 0389000 into main Aug 14, 2026
1 check passed
@bgent19
bgent19 deleted the worktree-issue-37-day4-trap branch August 14, 2026 22:14
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.

The Day 4 trap dataset, with both load-bearing edge orderings pinned

1 participant