FA-95126 / Warehouse slotting and bin packing / Open access
Re-slot plan: break-even move rejected · case 01
A move whose weekly saving exactly pays for the move labour is dropped.
ROOT CAUSE
The acceptance test requires benefit strictly greater than move cost.
VERIFIED REPAIR
Accept moves whose weekly benefit is at least the move cost.
Unsuccessful approach: Comparing the per-pick travel saving with the move cost ignores pick volume.
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()
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 = [[['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['generated mix 1', [[['K2', 'S4', 'S1', 40, 50, 5], ['K1', 'S6', 'S3', 40, 20, 40]], 50, 1], [['K2', 'S1', 1800]]], ['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]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['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 59', [[['K1', 'S3', 'S7', 40, 10, 30], ['K1', 'S2', 'S5', 40, 20, 20], ['K4', 'S2', 'S3', 10, 20, 10], ['K4', 'S3', 'S2', 10, 20, 40], ['K4', 'S5', 'S1', 40, 50, 30]], 0, 2], [['K4', 'S1', 800], ['K1', 'S5', 0]]], ['generated mix 13', [[['K2', 'S2', 'S1', 10, 10, 5], ['K4', 'S5', 'S6', 40, 20, 40], ['K2', 'S4', 'S2', 40, 30, 40], ['K3', 'S2', 'S6', 40, 50, 10]], 50, 2], [['K3', 'S6', 1600], ['K2', 'S1', 50]]], ['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 9', [[['K1', 'S6', 'S1', 20, 20, 20], ['K3', 'S5', 'S6', 40, 20, 20]], 0, 3], [['K1', 'S1', 0], ['K3', 'S6', 0]]], ['generated mix 18', [[['K1', 'S4', 'S3', 5, 50, 30], ['K3', 'S7', 'S3', 10, 20, 5]], 400, 2], []]], [['generated mix 53', [[['K1', 'S5', 'S2', 20, 30, 30], ['K3', 'S7', 'S1', 5, 10, 20], ['K1', 'S3', 'S6', 10, 20, 10], ['K2', 'S6', 'S5', 5, 20, 30], ['K4', 'S5', 'S3', 5, 50, 10]], 0, 2], [['K1', 'S2', 0]]], ['generated mix 23', [[['K2', 'S3', 'S7', 10, 10, 5], ['K1', 'S1', 'S3', 10, 10, 20], ['K1', 'S3', 'S4', 20, 10, 40]], 50, 3], [['K2', 'S7', 50]]], ['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 29', [[['K4', 'S6', 'S5', 40, 50, 20], ['K3', 'S6', 'S3', 20, 50, 40], ['K4', 'S6', 'S2', 20, 10, 40]], 200, 1], [['K4', 'S5', 1200]]]], [['generated mix 44', [[['K3', 'S5', 'S2', 40, 20, 30], ['K3', 'S6', 'S2', 5, 50, 5], ['K3', 'S2', 'S3', 10, 20, 20], ['K4', 'S3', 'S1', 20, 50, 20], ['K4', 'S7', 'S1', 10, 30, 5]], 0, 2], [['K4', 'S1', 600], ['K3', 'S3', 0]]], ['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]]], ['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 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]]], ['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], []], ['generated mix 59', [[['K1', 'S3', 'S7', 40, 10, 30], ['K1', 'S2', 'S5', 40, 20, 20], ['K4', 'S2', 'S3', 10, 20, 10], ['K4', 'S3', 'S2', 10, 20, 40], ['K4', 'S5', 'S1', 40, 50, 30]], 0, 2], [['K4', 'S1', 800], ['K1', 'S5', 0]]]]]
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 |
|---|---|---|---|
| threshold equal kept | [] | [['A', 'S9', 100]] | Failed |
| generated mix 1 | [['K2', 'S1', 1800]] | [['K2', 'S1', 1800]] | Passed |
| negative benefit | [] | [] | Passed |
| shared target | [['A', 'S9', 400]] | [['A', 'S9', 400]] | Passed |
| occupied target | [['A', 'S9', 200]] | [['A', 'S9', 200]] | Passed |
| limit | [['A', 'S8', 400]] | [['A', 'S8', 400]] | Passed |
| generated mix 7 | [] | [] | Passed |
| generated mix 15 | [] | [] | Passed |
SHA-256 / f097f13cad6aac0743a650248eb78a9490debb2d5a5342ce6865867997932514
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 tf - tt >= 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 = [[['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['generated mix 1', [[['K2', 'S4', 'S1', 40, 50, 5], ['K1', 'S6', 'S3', 40, 20, 40]], 50, 1], [['K2', 'S1', 1800]]], ['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]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['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 59', [[['K1', 'S3', 'S7', 40, 10, 30], ['K1', 'S2', 'S5', 40, 20, 20], ['K4', 'S2', 'S3', 10, 20, 10], ['K4', 'S3', 'S2', 10, 20, 40], ['K4', 'S5', 'S1', 40, 50, 30]], 0, 2], [['K4', 'S1', 800], ['K1', 'S5', 0]]], ['generated mix 13', [[['K2', 'S2', 'S1', 10, 10, 5], ['K4', 'S5', 'S6', 40, 20, 40], ['K2', 'S4', 'S2', 40, 30, 40], ['K3', 'S2', 'S6', 40, 50, 10]], 50, 2], [['K3', 'S6', 1600], ['K2', 'S1', 50]]], ['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 9', [[['K1', 'S6', 'S1', 20, 20, 20], ['K3', 'S5', 'S6', 40, 20, 20]], 0, 3], [['K1', 'S1', 0], ['K3', 'S6', 0]]], ['generated mix 18', [[['K1', 'S4', 'S3', 5, 50, 30], ['K3', 'S7', 'S3', 10, 20, 5]], 400, 2], []]], [['generated mix 53', [[['K1', 'S5', 'S2', 20, 30, 30], ['K3', 'S7', 'S1', 5, 10, 20], ['K1', 'S3', 'S6', 10, 20, 10], ['K2', 'S6', 'S5', 5, 20, 30], ['K4', 'S5', 'S3', 5, 50, 10]], 0, 2], [['K1', 'S2', 0]]], ['generated mix 23', [[['K2', 'S3', 'S7', 10, 10, 5], ['K1', 'S1', 'S3', 10, 10, 20], ['K1', 'S3', 'S4', 20, 10, 40]], 50, 3], [['K2', 'S7', 50]]], ['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 29', [[['K4', 'S6', 'S5', 40, 50, 20], ['K3', 'S6', 'S3', 20, 50, 40], ['K4', 'S6', 'S2', 20, 10, 40]], 200, 1], [['K4', 'S5', 1200]]]], [['generated mix 44', [[['K3', 'S5', 'S2', 40, 20, 30], ['K3', 'S6', 'S2', 5, 50, 5], ['K3', 'S2', 'S3', 10, 20, 20], ['K4', 'S3', 'S1', 20, 50, 20], ['K4', 'S7', 'S1', 10, 30, 5]], 0, 2], [['K4', 'S1', 600], ['K3', 'S3', 0]]], ['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]]], ['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 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]]], ['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], []], ['generated mix 59', [[['K1', 'S3', 'S7', 40, 10, 30], ['K1', 'S2', 'S5', 40, 20, 20], ['K4', 'S2', 'S3', 10, 20, 10], ['K4', 'S3', 'S2', 10, 20, 40], ['K4', 'S5', 'S1', 40, 50, 30]], 0, 2], [['K4', 'S1', 800], ['K1', 'S5', 0]]]]]
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 |
|---|---|---|---|
| threshold equal kept | [] | [['A', 'S9', 100]] | Failed |
| generated mix 1 | [] | [['K2', 'S1', 1800]] | Failed |
| negative benefit | [] | [] | Passed |
| shared target | [['A', 'S9', 400]] | [['A', 'S9', 400]] | Passed |
| occupied target | [['A', 'S9', 200]] | [['A', 'S9', 200]] | Passed |
| limit | [['A', 'S8', 400]] | [['A', 'S8', 400]] | Passed |
| generated mix 7 | [] | [] | Passed |
| generated mix 15 | [] | [] | Passed |
SHA-256 / 94f5a8fdabff7303728f2d8267dab930e5a9f1d6e4d75e51cae21dd679f1dfaf
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 = [[['threshold equal kept', [[['A', 'S1', 'S9', 10, 30, 20]], 100, 5], [['A', 'S9', 100]]], ['generated mix 1', [[['K2', 'S4', 'S1', 40, 50, 5], ['K1', 'S6', 'S3', 40, 20, 40]], 50, 1], [['K2', 'S1', 1800]]], ['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]]], ['limit', [[['A', 'S1', 'S8', 10, 50, 10], ['B', 'S2', 'S9', 10, 40, 10]], 0, 1], [['A', 'S8', 400]]], ['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 59', [[['K1', 'S3', 'S7', 40, 10, 30], ['K1', 'S2', 'S5', 40, 20, 20], ['K4', 'S2', 'S3', 10, 20, 10], ['K4', 'S3', 'S2', 10, 20, 40], ['K4', 'S5', 'S1', 40, 50, 30]], 0, 2], [['K4', 'S1', 800], ['K1', 'S5', 0]]], ['generated mix 13', [[['K2', 'S2', 'S1', 10, 10, 5], ['K4', 'S5', 'S6', 40, 20, 40], ['K2', 'S4', 'S2', 40, 30, 40], ['K3', 'S2', 'S6', 40, 50, 10]], 50, 2], [['K3', 'S6', 1600], ['K2', 'S1', 50]]], ['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 9', [[['K1', 'S6', 'S1', 20, 20, 20], ['K3', 'S5', 'S6', 40, 20, 20]], 0, 3], [['K1', 'S1', 0], ['K3', 'S6', 0]]], ['generated mix 18', [[['K1', 'S4', 'S3', 5, 50, 30], ['K3', 'S7', 'S3', 10, 20, 5]], 400, 2], []]], [['generated mix 53', [[['K1', 'S5', 'S2', 20, 30, 30], ['K3', 'S7', 'S1', 5, 10, 20], ['K1', 'S3', 'S6', 10, 20, 10], ['K2', 'S6', 'S5', 5, 20, 30], ['K4', 'S5', 'S3', 5, 50, 10]], 0, 2], [['K1', 'S2', 0]]], ['generated mix 23', [[['K2', 'S3', 'S7', 10, 10, 5], ['K1', 'S1', 'S3', 10, 10, 20], ['K1', 'S3', 'S4', 20, 10, 40]], 50, 3], [['K2', 'S7', 50]]], ['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 29', [[['K4', 'S6', 'S5', 40, 50, 20], ['K3', 'S6', 'S3', 20, 50, 40], ['K4', 'S6', 'S2', 20, 10, 40]], 200, 1], [['K4', 'S5', 1200]]]], [['generated mix 44', [[['K3', 'S5', 'S2', 40, 20, 30], ['K3', 'S6', 'S2', 5, 50, 5], ['K3', 'S2', 'S3', 10, 20, 20], ['K4', 'S3', 'S1', 20, 50, 20], ['K4', 'S7', 'S1', 10, 30, 5]], 0, 2], [['K4', 'S1', 600], ['K3', 'S3', 0]]], ['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]]], ['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 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]]], ['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], []], ['generated mix 59', [[['K1', 'S3', 'S7', 40, 10, 30], ['K1', 'S2', 'S5', 40, 20, 20], ['K4', 'S2', 'S3', 10, 20, 10], ['K4', 'S3', 'S2', 10, 20, 40], ['K4', 'S5', 'S1', 40, 50, 30]], 0, 2], [['K4', 'S1', 800], ['K1', 'S5', 0]]]]]
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 |
|---|---|---|---|
| threshold equal kept | [['A', 'S9', 100]] | [['A', 'S9', 100]] | Passed |
| generated mix 1 | [['K2', 'S1', 1800]] | [['K2', 'S1', 1800]] | Passed |
| negative benefit | [] | [] | Passed |
| shared target | [['A', 'S9', 400]] | [['A', 'S9', 400]] | Passed |
| occupied target | [['A', 'S9', 200]] | [['A', 'S9', 200]] | Passed |
| limit | [['A', 'S8', 400]] | [['A', 'S8', 400]] | Passed |
| generated mix 7 | [] | [] | Passed |
| generated mix 15 | [] | [] | Passed |
SHA-256 / 1f375f7777251564d192c3d60a2aa7cb246c01871cd9466e07b69d4121990297
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:10.790073+00:00.
Case digest / ce5b6f31b11e0065ca70cb2838bff452805e7fb24878ed70644f6d6c63580b60