FA-95146 / Warehouse slotting and bin packing / Open access
Re-slot plan: smallest savings accepted first · case 01
The move budget is consumed by the least valuable moves.
ROOT CAUSE
Candidates are sorted with reverse order on negated benefit, putting small benefits first.
VERIFIED REPAIR
Sort by benefit descending with sku, from and to as tie-breaks.
Unsuccessful approach: Leaving candidates in input order makes the plan depend on feed order.
Case contract
cands [[sku, from_slot, to_slot, weekly_picks, travel_from, travel_to]]. Weekly benefit = picks*(travel_from - travel_to); keep candidates with benefit >= move_cost; rank by benefit desc, sku, from, to. Greedily accept up to max_moves: each SKU moves once, each target is used once, and a target that is the from_slot of any candidate is occupied unless that slot was already vacated by an accepted move. Return [[sku, to_slot, benefit]].
Why this case matters
Periodic re-slotting moves SKUs whose velocity changed toward better locations.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(cands, move_cost, max_moves):
occupied = {c[1] for c in cands}
ranked = []
for sku, frm, to, picks, tf, tt in cands:
benefit = picks * (tf - tt)
if benefit >= move_cost:
ranked.append((-benefit, sku, frm, to))
ranked.sort(reverse=True)
plan = []
moved = set()
targets = set()
vacated = set()
for nb, sku, frm, to in ranked:
if len(plan) >= max_moves:
break
if sku in moved or to in targets:
continue
if to in occupied and to not in vacated:
continue
plan.append([sku, to, -nb])
moved.add(sku)
targets.add(to)
vacated.add(frm)
return plan
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['generated mix 4', [[['K3', 'S4', 'S3', 10, 50, 10], ['K4', 'S4', 'S3', 20, 20, 20], ['K3', 'S4', 'S6', 40, 20, 20], ['K4', 'S7', 'S3', 20, 20, 20], ['K4', 'S1', 'S6', 20, 50, 20]], 0, 1], [['K4', 'S6', 600]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['generated mix 7', [[['K1', 'S7', 'S4', 20, 10, 5], ['K4', 'S2', 'S4', 5, 20, 30], ['K4', 'S3', 'S4', 20, 30, 40], ['K1', 'S1', 'S7', 20, 20, 20]], 200, 2], []], ['generated mix 15', [[['K4', 'S4', 'S1', 10, 20, 20], ['K1', 'S2', 'S3', 10, 30, 5], ['K4', 'S4', 'S2', 20, 30, 20], ['K4', 'S1', 'S7', 40, 20, 20], ['K1', 'S3', 'S4', 5, 10, 30]], 200, 1], []]], [['generated mix 6', [[['K3', 'S1', 'S3', 20, 50, 10], ['K3', 'S4', 'S7', 40, 50, 40]], 400, 2], [['K3', 'S3', 800]]], ['generated mix 42', [[['K3', 'S7', 'S2', 10, 20, 40], ['K1', 'S6', 'S2', 10, 20, 20], ['K2', 'S5', 'S2', 20, 30, 20], ['K4', 'S7', 'S4', 40, 50, 30]], 200, 2], [['K4', 'S4', 800], ['K2', 'S2', 200]]], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['generated mix 10', [[['K3', 'S4', 'S3', 40, 10, 5], ['K4', 'S7', 'S3', 40, 10, 20], ['K4', 'S2', 'S7', 5, 30, 5], ['K3', 'S2', 'S5', 40, 10, 40], ['K3', 'S2', 'S7', 10, 50, 20]], 400, 3], []], ['generated mix 18', [[['K1', 'S4', 'S3', 5, 50, 30], ['K3', 'S7', 'S3', 10, 20, 5]], 400, 2], []]], [['generated mix 38', [[['K4', 'S1', 'S2', 5, 30, 30], ['K4', 'S3', 'S7', 5, 10, 5], ['K3', 'S3', 'S2', 5, 30, 20], ['K2', 'S7', 'S3', 5, 10, 5], ['K1', 'S6', 'S5', 10, 50, 20], ['K4', 'S7', 'S6', 10, 30, 20]], 0, 3], [['K1', 'S5', 300], ['K4', 'S6', 100], ['K3', 'S2', 50]]], ['generated mix 80', [[['K1', 'S4', 'S6', 20, 50, 10], ['K1', 'S5', 'S1', 40, 50, 10]], 100, 2], [['K1', 'S1', 1600]]], ['sku once', [[['A', 'S1', 'S8', 10, 50, 10], ['A', 'S1', 'S9', 10, 50, 20]], 0, 5], [['A', 'S8', 400]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['generated mix 20', [[['K1', 'S3', 'S7', 5, 50, 40], ['K3', 'S4', 'S5', 20, 10, 10], ['K2', 'S6', 'S5', 5, 30, 30], ['K3', 'S2', 'S5', 40, 50, 20], ['K4', 'S5', 'S7', 10, 10, 30], ['K2', 'S5', 'S4', 40, 30, 5]], 0, 1], [['K1', 'S7', 50]]], ['generated mix 28', [[['K3', 'S4', 'S2', 10, 50, 30], ['K2', 'S1', 'S3', 10, 50, 30], ['K4', 'S1', 'S2', 20, 50, 5]], 400, 2], [['K4', 'S2', 900]]]], [['generated mix 80', [[['K1', 'S4', 'S6', 20, 50, 10], ['K1', 'S5', 'S1', 40, 50, 10]], 100, 2], [['K1', 'S1', 1600]]], ['generated mix 30', [[['K2', 'S4', 'S5', 5, 30, 5], ['K4', 'S3', 'S1', 40, 50, 20], ['K2', 'S6', 'S1', 5, 20, 40]], 0, 1], [['K4', 'S1', 1200]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['chain into vacated', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 400], ['B', 'S1', 300]]], ['sku once', [[['A', 'S1', 'S8', 10, 50, 10], ['A', 'S1', 'S9', 10, 50, 20]], 0, 5], [['A', 'S8', 400]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['generated mix 32', [[['K2', 'S5', 'S1', 10, 30, 5], ['K2', 'S1', 'S3', 5, 10, 40], ['K3', 'S5', 'S4', 20, 10, 10], ['K4', 'S3', 'S5', 10, 50, 40], ['K2', 'S4', 'S6', 40, 10, 40]], 0, 3], []], ['generated mix 40', [[['K3', 'S5', 'S2', 40, 10, 10]], 200, 3], []]], [['generated mix 4', [[['K3', 'S4', 'S3', 10, 50, 10], ['K4', 'S4', 'S3', 20, 20, 20], ['K3', 'S4', 'S6', 40, 20, 20], ['K4', 'S7', 'S3', 20, 20, 20], ['K4', 'S1', 'S6', 20, 50, 20]], 0, 1], [['K4', 'S6', 600]]], ['generated mix 62', [[['K4', 'S4', 'S5', 10, 50, 5], ['K1', 'S3', 'S4', 40, 10, 20], ['K1', 'S5', 'S2', 20, 50, 30], ['K1', 'S7', 'S6', 10, 50, 20], ['K4', 'S3', 'S5', 40, 30, 40], ['K3', 'S4', 'S6', 20, 50, 10]], 200, 1], [['K3', 'S6', 800]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['chain into vacated', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 400], ['B', 'S1', 300]]], ['generated mix 43', [[['K2', 'S6', 'S5', 10, 20, 30]], 200, 2], []], ['generated mix 51', [[['K4', 'S4', 'S5', 10, 50, 5], ['K3', 'S4', 'S7', 10, 50, 40], ['K3', 'S5', 'S3', 10, 50, 40], ['K1', 'S6', 'S1', 40, 20, 30]], 200, 1], []]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| limit | [['B', 'S9', 300]] | [['A', 'S8', 400]] | Failed |
| generated mix 4 | [['K4', 'S3', 0]] | [['K4', 'S6', 600]] | Failed |
| threshold equal kept | [['A', 'S9', 100]] | [['A', 'S9', 100]] | Passed |
| shared target | [['B', 'S9', 300]] | [['A', 'S9', 400]] | Failed |
| occupied target | [['A', 'S9', 200], ['B', 'S1', 300]] | [['A', 'S9', 200]] | Failed |
| negative benefit | [] | [] | Passed |
| generated mix 7 | [] | [] | Passed |
| generated mix 15 | [] | [] | Passed |
SHA-256 / 7f49921024715d1105433dc4026f0c65a45b81cd2dc105f00f417767e5301abe
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(cands, move_cost, max_moves):
occupied = {c[1] for c in cands}
ranked = []
for sku, frm, to, picks, tf, tt in cands:
benefit = picks * (tf - tt)
if benefit >= move_cost:
ranked.append((-benefit, sku, frm, to))
plan = []
moved = set()
targets = set()
vacated = set()
for nb, sku, frm, to in ranked:
if len(plan) >= max_moves:
break
if sku in moved or to in targets:
continue
if to in occupied and to not in vacated:
continue
plan.append([sku, to, -nb])
moved.add(sku)
targets.add(to)
vacated.add(frm)
return plan
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['generated mix 4', [[['K3', 'S4', 'S3', 10, 50, 10], ['K4', 'S4', 'S3', 20, 20, 20], ['K3', 'S4', 'S6', 40, 20, 20], ['K4', 'S7', 'S3', 20, 20, 20], ['K4', 'S1', 'S6', 20, 50, 20]], 0, 1], [['K4', 'S6', 600]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['generated mix 7', [[['K1', 'S7', 'S4', 20, 10, 5], ['K4', 'S2', 'S4', 5, 20, 30], ['K4', 'S3', 'S4', 20, 30, 40], ['K1', 'S1', 'S7', 20, 20, 20]], 200, 2], []], ['generated mix 15', [[['K4', 'S4', 'S1', 10, 20, 20], ['K1', 'S2', 'S3', 10, 30, 5], ['K4', 'S4', 'S2', 20, 30, 20], ['K4', 'S1', 'S7', 40, 20, 20], ['K1', 'S3', 'S4', 5, 10, 30]], 200, 1], []]], [['generated mix 6', [[['K3', 'S1', 'S3', 20, 50, 10], ['K3', 'S4', 'S7', 40, 50, 40]], 400, 2], [['K3', 'S3', 800]]], ['generated mix 42', [[['K3', 'S7', 'S2', 10, 20, 40], ['K1', 'S6', 'S2', 10, 20, 20], ['K2', 'S5', 'S2', 20, 30, 20], ['K4', 'S7', 'S4', 40, 50, 30]], 200, 2], [['K4', 'S4', 800], ['K2', 'S2', 200]]], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['generated mix 10', [[['K3', 'S4', 'S3', 40, 10, 5], ['K4', 'S7', 'S3', 40, 10, 20], ['K4', 'S2', 'S7', 5, 30, 5], ['K3', 'S2', 'S5', 40, 10, 40], ['K3', 'S2', 'S7', 10, 50, 20]], 400, 3], []], ['generated mix 18', [[['K1', 'S4', 'S3', 5, 50, 30], ['K3', 'S7', 'S3', 10, 20, 5]], 400, 2], []]], [['generated mix 38', [[['K4', 'S1', 'S2', 5, 30, 30], ['K4', 'S3', 'S7', 5, 10, 5], ['K3', 'S3', 'S2', 5, 30, 20], ['K2', 'S7', 'S3', 5, 10, 5], ['K1', 'S6', 'S5', 10, 50, 20], ['K4', 'S7', 'S6', 10, 30, 20]], 0, 3], [['K1', 'S5', 300], ['K4', 'S6', 100], ['K3', 'S2', 50]]], ['generated mix 80', [[['K1', 'S4', 'S6', 20, 50, 10], ['K1', 'S5', 'S1', 40, 50, 10]], 100, 2], [['K1', 'S1', 1600]]], ['sku once', [[['A', 'S1', 'S8', 10, 50, 10], ['A', 'S1', 'S9', 10, 50, 20]], 0, 5], [['A', 'S8', 400]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['generated mix 20', [[['K1', 'S3', 'S7', 5, 50, 40], ['K3', 'S4', 'S5', 20, 10, 10], ['K2', 'S6', 'S5', 5, 30, 30], ['K3', 'S2', 'S5', 40, 50, 20], ['K4', 'S5', 'S7', 10, 10, 30], ['K2', 'S5', 'S4', 40, 30, 5]], 0, 1], [['K1', 'S7', 50]]], ['generated mix 28', [[['K3', 'S4', 'S2', 10, 50, 30], ['K2', 'S1', 'S3', 10, 50, 30], ['K4', 'S1', 'S2', 20, 50, 5]], 400, 2], [['K4', 'S2', 900]]]], [['generated mix 80', [[['K1', 'S4', 'S6', 20, 50, 10], ['K1', 'S5', 'S1', 40, 50, 10]], 100, 2], [['K1', 'S1', 1600]]], ['generated mix 30', [[['K2', 'S4', 'S5', 5, 30, 5], ['K4', 'S3', 'S1', 40, 50, 20], ['K2', 'S6', 'S1', 5, 20, 40]], 0, 1], [['K4', 'S1', 1200]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['chain into vacated', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 400], ['B', 'S1', 300]]], ['sku once', [[['A', 'S1', 'S8', 10, 50, 10], ['A', 'S1', 'S9', 10, 50, 20]], 0, 5], [['A', 'S8', 400]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['generated mix 32', [[['K2', 'S5', 'S1', 10, 30, 5], ['K2', 'S1', 'S3', 5, 10, 40], ['K3', 'S5', 'S4', 20, 10, 10], ['K4', 'S3', 'S5', 10, 50, 40], ['K2', 'S4', 'S6', 40, 10, 40]], 0, 3], []], ['generated mix 40', [[['K3', 'S5', 'S2', 40, 10, 10]], 200, 3], []]], [['generated mix 4', [[['K3', 'S4', 'S3', 10, 50, 10], ['K4', 'S4', 'S3', 20, 20, 20], ['K3', 'S4', 'S6', 40, 20, 20], ['K4', 'S7', 'S3', 20, 20, 20], ['K4', 'S1', 'S6', 20, 50, 20]], 0, 1], [['K4', 'S6', 600]]], ['generated mix 62', [[['K4', 'S4', 'S5', 10, 50, 5], ['K1', 'S3', 'S4', 40, 10, 20], ['K1', 'S5', 'S2', 20, 50, 30], ['K1', 'S7', 'S6', 10, 50, 20], ['K4', 'S3', 'S5', 40, 30, 40], ['K3', 'S4', 'S6', 20, 50, 10]], 200, 1], [['K3', 'S6', 800]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['chain into vacated', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 400], ['B', 'S1', 300]]], ['generated mix 43', [[['K2', 'S6', 'S5', 10, 20, 30]], 200, 2], []], ['generated mix 51', [[['K4', 'S4', 'S5', 10, 50, 5], ['K3', 'S4', 'S7', 10, 50, 40], ['K3', 'S5', 'S3', 10, 50, 40], ['K1', 'S6', 'S1', 40, 20, 30]], 200, 1], []]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| limit | [['A', 'S8', 400]] | [['A', 'S8', 400]] | Passed |
| generated mix 4 | [['K3', 'S3', 400]] | [['K4', 'S6', 600]] | Failed |
| threshold equal kept | [['A', 'S9', 100]] | [['A', 'S9', 100]] | Passed |
| shared target | [['A', 'S9', 400]] | [['A', 'S9', 400]] | Passed |
| occupied target | [['A', 'S9', 200], ['B', 'S1', 300]] | [['A', 'S9', 200]] | Failed |
| negative benefit | [] | [] | Passed |
| generated mix 7 | [] | [] | Passed |
| generated mix 15 | [] | [] | Passed |
SHA-256 / b7ffa94c17daf89e27a275feaf7369e472fba5ea0aa5dced5b344df8cf46ef46
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(cands, move_cost, max_moves):
occupied = {c[1] for c in cands}
ranked = []
for sku, frm, to, picks, tf, tt in cands:
benefit = picks * (tf - tt)
if benefit >= move_cost:
ranked.append((-benefit, sku, frm, to))
ranked.sort()
plan = []
moved = set()
targets = set()
vacated = set()
for nb, sku, frm, to in ranked:
if len(plan) >= max_moves:
break
if sku in moved or to in targets:
continue
if to in occupied and to not in vacated:
continue
plan.append([sku, to, -nb])
moved.add(sku)
targets.add(to)
vacated.add(frm)
return plan
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['generated mix 4', [[['K3', 'S4', 'S3', 10, 50, 10], ['K4', 'S4', 'S3', 20, 20, 20], ['K3', 'S4', 'S6', 40, 20, 20], ['K4', 'S7', 'S3', 20, 20, 20], ['K4', 'S1', 'S6', 20, 50, 20]], 0, 1], [['K4', 'S6', 600]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['generated mix 7', [[['K1', 'S7', 'S4', 20, 10, 5], ['K4', 'S2', 'S4', 5, 20, 30], ['K4', 'S3', 'S4', 20, 30, 40], ['K1', 'S1', 'S7', 20, 20, 20]], 200, 2], []], ['generated mix 15', [[['K4', 'S4', 'S1', 10, 20, 20], ['K1', 'S2', 'S3', 10, 30, 5], ['K4', 'S4', 'S2', 20, 30, 20], ['K4', 'S1', 'S7', 40, 20, 20], ['K1', 'S3', 'S4', 5, 10, 30]], 200, 1], []]], [['generated mix 6', [[['K3', 'S1', 'S3', 20, 50, 10], ['K3', 'S4', 'S7', 40, 50, 40]], 400, 2], [['K3', 'S3', 800]]], ['generated mix 42', [[['K3', 'S7', 'S2', 10, 20, 40], ['K1', 'S6', 'S2', 10, 20, 20], ['K2', 'S5', 'S2', 20, 30, 20], ['K4', 'S7', 'S4', 40, 50, 30]], 200, 2], [['K4', 'S4', 800], ['K2', 'S2', 200]]], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['generated mix 10', [[['K3', 'S4', 'S3', 40, 10, 5], ['K4', 'S7', 'S3', 40, 10, 20], ['K4', 'S2', 'S7', 5, 30, 5], ['K3', 'S2', 'S5', 40, 10, 40], ['K3', 'S2', 'S7', 10, 50, 20]], 400, 3], []], ['generated mix 18', [[['K1', 'S4', 'S3', 5, 50, 30], ['K3', 'S7', 'S3', 10, 20, 5]], 400, 2], []]], [['generated mix 38', [[['K4', 'S1', 'S2', 5, 30, 30], ['K4', 'S3', 'S7', 5, 10, 5], ['K3', 'S3', 'S2', 5, 30, 20], ['K2', 'S7', 'S3', 5, 10, 5], ['K1', 'S6', 'S5', 10, 50, 20], ['K4', 'S7', 'S6', 10, 30, 20]], 0, 3], [['K1', 'S5', 300], ['K4', 'S6', 100], ['K3', 'S2', 50]]], ['generated mix 80', [[['K1', 'S4', 'S6', 20, 50, 10], ['K1', 'S5', 'S1', 40, 50, 10]], 100, 2], [['K1', 'S1', 1600]]], ['sku once', [[['A', 'S1', 'S8', 10, 50, 10], ['A', 'S1', 'S9', 10, 50, 20]], 0, 5], [['A', 'S8', 400]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['shared target', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 5], [['A', 'S9', 400]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['generated mix 20', [[['K1', 'S3', 'S7', 5, 50, 40], ['K3', 'S4', 'S5', 20, 10, 10], ['K2', 'S6', 'S5', 5, 30, 30], ['K3', 'S2', 'S5', 40, 50, 20], ['K4', 'S5', 'S7', 10, 10, 30], ['K2', 'S5', 'S4', 40, 30, 5]], 0, 1], [['K1', 'S7', 50]]], ['generated mix 28', [[['K3', 'S4', 'S2', 10, 50, 30], ['K2', 'S1', 'S3', 10, 50, 30], ['K4', 'S1', 'S2', 20, 50, 5]], 400, 2], [['K4', 'S2', 900]]]], [['generated mix 80', [[['K1', 'S4', 'S6', 20, 50, 10], ['K1', 'S5', 'S1', 40, 50, 10]], 100, 2], [['K1', 'S1', 1600]]], ['generated mix 30', [[['K2', 'S4', 'S5', 5, 30, 5], ['K4', 'S3', 'S1', 40, 50, 20], ['K2', 'S6', 'S1', 5, 20, 40]], 0, 1], [['K4', 'S1', 1200]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['chain into vacated', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 400], ['B', 'S1', 300]]], ['sku once', [[['A', 'S1', 'S8', 10, 50, 10], ['A', 'S1', 'S9', 10, 50, 20]], 0, 5], [['A', 'S8', 400]]], ['negative benefit', [[['A', 'S1', 'S9', 10, 20, 30]], 0, 5], []], ['generated mix 32', [[['K2', 'S5', 'S1', 10, 30, 5], ['K2', 'S1', 'S3', 5, 10, 40], ['K3', 'S5', 'S4', 20, 10, 10], ['K4', 'S3', 'S5', 10, 50, 40], ['K2', 'S4', 'S6', 40, 10, 40]], 0, 3], []], ['generated mix 40', [[['K3', 'S5', 'S2', 40, 10, 10]], 200, 3], []]], [['generated mix 4', [[['K3', 'S4', 'S3', 10, 50, 10], ['K4', 'S4', 'S3', 20, 20, 20], ['K3', 'S4', 'S6', 40, 20, 20], ['K4', 'S7', 'S3', 20, 20, 20], ['K4', 'S1', 'S6', 20, 50, 20]], 0, 1], [['K4', 'S6', 600]]], ['generated mix 62', [[['K4', 'S4', 'S5', 10, 50, 5], ['K1', 'S3', 'S4', 40, 10, 20], ['K1', 'S5', 'S2', 20, 50, 30], ['K1', 'S7', 'S6', 10, 50, 20], ['K4', 'S3', 'S5', 40, 30, 40], ['K3', 'S4', 'S6', 20, 50, 10]], 200, 1], [['K3', 'S6', 800]]], ['occupied target', [[['A', 'S1', 'S9', 10, 30, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 200]]], ['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['chain into vacated', [[['A', 'S1', 'S9', 10, 50, 10], ['B', 'S2', 'S1', 10, 40, 10]], 0, 5], [['A', 'S9', 400], ['B', 'S1', 300]]], ['generated mix 43', [[['K2', 'S6', 'S5', 10, 20, 30]], 200, 2], []], ['generated mix 51', [[['K4', 'S4', 'S5', 10, 50, 5], ['K3', 'S4', 'S7', 10, 50, 40], ['K3', 'S5', 'S3', 10, 50, 40], ['K1', 'S6', 'S1', 40, 20, 30]], 200, 1], []]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| limit | [['A', 'S8', 400]] | [['A', 'S8', 400]] | Passed |
| generated mix 4 | [['K4', 'S6', 600]] | [['K4', 'S6', 600]] | Passed |
| threshold equal kept | [['A', 'S9', 100]] | [['A', 'S9', 100]] | Passed |
| shared target | [['A', 'S9', 400]] | [['A', 'S9', 400]] | Passed |
| occupied target | [['A', 'S9', 200]] | [['A', 'S9', 200]] | Passed |
| negative benefit | [] | [] | Passed |
| generated mix 7 | [] | [] | Passed |
| generated mix 15 | [] | [] | Passed |
SHA-256 / f57d610ed928ecd0b46dbae62b9d89d1b02cb1dc7c4fe689707dd00b5e30e83d
Verification & scope
Greedy stipulated planner; no swap sequencing or labour scheduling. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:52:11.076220+00:00.
Case digest / e6122790bf9bdccb0d87082b3bd6cb53416d61e298dc056b4017abef3b8d2dbd