Tasks/Optimization, Planning & Control

Defect-Aware Guillotine Glass Cutting Optimization

Pack glass orders into minimum stock plates under staged cuts, defects, and stack-sequence constraints

Optimization, Planning & Controlcutting stockcombinatorial optimization
Background

Cutting and packing, the operations-research field that plans how sheet stock is carved into ordered rectangles, admits no certified optimum once edge-to-edge saw cuts, material defects, and production-order constraints combine. The starting system is a crude planner giving each glass piece its own full-height strip clear of flaws, and emitting a valid cut tree. The work is to redesign it so orders fit into far fewer plates. Every pattern must honour the saw's limits and per-stack delivery order, on orders never seen, within seconds.

instruction.mdthis is what the agent is given

You run the cutting floor of a flat-glass plant. Orders arrive as a batch of rectangular glass items, and you cut them out of large rectangular stock plates (6000 x 3210 mm) on a guillotine cutting line. Every cut runs edge to edge, so each plate is carved by a strict pattern of guillotine cuts; the glass also carries defects (bubbles, scratches) that no delivered item may cover. Stock is expensive and the leftover glass you cannot reuse is pure loss, so the whole game is packing the order into the fewest plates with the least wasted area — while honouring the saw's mechanical rules and the order in which finished pieces must come off the line.

Hard Constraints

Each stock plate is W x H = 6000 x 3210 mm. A solution cuts a sequence of plates with an exact 3-staged guillotine pattern (plus an optional 4th trim stage):

  • stage 1 — vertical cuts split a plate into full-height columns ("1-cuts");
  • stage 2 — horizontal cuts split a column into rows ("2-cuts");
  • stage 3 — vertical cuts split a row into items / waste ("3-cuts");
  • stage 4 — an optional final vertical/horizontal trim.

Enforced by the bundled checker (parameters in global_param.csv):

  • items may be rotated 90 degrees; each placed item must fit inside the plate (H = 3210) and avoid every defect rectangle (no overlap at all);
  • 1-cuts are >= 100 and <= 3500 mm apart (min/max column width);
  • 2-cuts are >= 100 mm apart;
  • any waste piece must be >= 20 mm in the cut dimension (minWaste);
  • items belonging to the same stack must be produced in their given sequence order (cross-stack order is free);
  • the rightmost leftover strip of the last plate may be declared a reusable residual and is not counted as waste.

Beyond the cutting rules:

  • Submit an algorithm, not precomputed answers — the grader re-runs your code on instances you have never seen. Do not key on instance names.
  • /app/methods/main/ is what gets graded. Keep the run.sh contract below.
  • Each sealed case runs your run.sh under a wall-clock cap of 40 s. A crash, timeout, malformed output, or a checker-rejected solution forfeits that case entirely.
  • There is no network at run time, on the workbench or in the grader. Python 3 and g++ are available in both; anything else you have to write yourself.

What You Have

  • tools/instances/ — 10 visible instances plus global_param.csv. The sealed instances are different draws from the same distribution.
  • ./checker <idx> — the checker, compiled into the workbench, the same one the grader uses. With <idx>_batch.csv, <idx>_defects.csv, <idx>_solution.csv and global_param.csv in an instances_checker/ subdir it validates the solution and writes logs/<idx>_statistics.csv (validSolution, nPlates, totalGeoLoss, widthResidual). Its error messages pinpoint any violation.
  • python3 selfcheck.py [N] — free and unlimited: runs your run.sh on the first N visible cases, validates and measures each with that same checker, and prints the raw waste per case.
  • methods/main/solution.py — a valid but crude emitter, useful as a reference for the exact tree grammar. It is yours to rewrite or delete.

An instance is three semicolon-separated CSVs. <idx>_batch.csv:

ITEM_ID;LENGTH_ITEM;WIDTH_ITEM;STACK;SEQUENCE
0;234;1827;0;1

<idx>_defects.csv:

DEFECT_ID;PLATE_ID;X;Y;WIDTH;HEIGHT
0;0;2159.0;2893.0;2.0;3.0

global_param.csv gives widthPlates=6000, heightPlates=3210, min1Cut=100, max1Cut=3500, min2Cut=100, minWaste=20, nPlates=100.

What You Submit

Leave your best solver in methods/main/:

  • run.sh (required): invoked once per case as bash run.sh <batch.csv> <defects.csv> <global_param.csv> <out.csv>. Read the three instance CSVs, write your cutting-tree solution to <out.csv>. Any language.
  • build.sh (optional): if present, run once before grading (e.g. to compile a C++ solver). Have run.sh exec the built binary.

The output is the cutting-tree solution.csv: one row per node of the guillotine cut tree, in production order.

PLATE_ID;NODE_ID;X;Y;WIDTH;HEIGHT;TYPE;CUT;PARENT

TYPE is the item id (>= 0) for an item leaf, -1 for waste, -2 for a branch (internal) node, -3 for the final residual. CUT is the stage (0=plate .. 4). PARENT is the parent NODE_ID.

There is no submit step and no per-attempt feedback. Work and self-check for as long as your run window allows, then leave your best run.sh in place.

How It Is Judged

The grader reruns your run.sh on 10 sealed instances you never see — same distribution, held out — and validates and measures every solution with the same checker. The absolute objective for one instance is the wasted area

waste = (used_plate_area) - (total_item_area) - (last-plate residual area)

Lower is better. A checker-rejected, incomplete, or timed-out case is forfeited, so produce a valid solution for every case first, then minimise waste. Scoring is per case and then aggregated, so a case you ignore cannot be carried by a case you optimise.

How the raw waste maps to the final reward is deliberately not disclosed — optimise the waste itself. The starter as shipped is the zero of that scale: submitted unchanged it scores 0.

Rollouts

223 minWall clock
$75.11Spend
118.7MTokens
61Versions, 35 kept

On the visible set

20M 40M 60M 80M 100M 0 200 400 600 800 Agent step Visible mean waste ↓ v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v16 v17 v18 v19 v21 v23 v31 v33 v40 v41 v42 v43 v45 v48 v51 v53 v55 v58
keptrolled backsubmitted
  1. v0The agent started from the shipped one-item-per-column baseline.100,235,034.91 min · $0.16
  2. v1The agent built a defect-aware column packer that respects stack order.58,018,398.99 min · $1.25
  3. v2The agent chased pathological wide columns and let plates split instead.28,030,899.913 min · $2.17
  4. v3The agent packed real multi-item shelves straight against each plate's defects.19,185,744.930 min · $5.90
  5. v4The agent turned on the two row policies it had been holding back.18,897,486.932 min · $6.43
  6. v5The agent swept every column split instead of five fixed choices.17,852,631.934 min · $7.15
  7. v6The agent halved the split spacing and started watching the clock.17,454,591.937 min · $8.19
  8. v7The agent turned two useless row policies into ones that earned their place.17,273,226.941 min · $9.23
  9. v8The agent refined widths only for the policy that kept winning.17,084,799.943 min · $10.07
  10. v9The agent let each plate pick its own split instead of one global choice.14,532,207.947 min · $11.37
  11. v10The agent halved the per-plate split spacing, at the cost of its time margin.13,446,585.950 min · $12.36
  12. v11The agent dropped a policy that never won and rationed the coarse grid.13,405,818.954 min · $13.76
  13. v12The agent pruned the right redundant policy and won back its runtime margin.13,385,595.957 min · $14.95
  14. v13The agent kept a second plate state alive in case it unlocked later plates.13,277,418.963 min · $16.71
  15. v14The agent widened that plate beam to three states, and it bought nothing.13,277,418.965 min · $17.67
  16. v15The agent tried ranking the spare beam state by item count, and lost ground.31,299,738 (A14)66 min · $18.13
  17. v16The agent added three- and four-column schemes snapped around defects.13,238,577.969 min · $19.09
  18. v17The agent let the per-plate search choose those three-column schemes too.12,437,040.972 min · $20.20
  19. v18The agent broadened the schemes to lopsided column widths.12,112,509.975 min · $21.41
  20. v19The agent extended the richer schemes to much larger batches.11,801,460.979 min · $23.00
  21. v20The agent fed three-column transitions to the plate beam, to no effect.15,221,569 (A11)80 min · $23.50
  22. v21The agent let a plate pool all four row heuristics at once.11,782,842.985 min · $25.56
  23. v22The agent tried ranking plates by item count first, and nothing moved.15,035,389 (A11)88 min · $26.57
  24. v23The agent went back and repacked the last two plates together.11,755,878.997 min · $30.00
  25. v24The agent kept more penultimate states in the tail repack, and gained nothing.23,177,054 (A8)99 min · $32.45
  26. v25The agent refined the tail repack's split grid, and gained nothing.23,177,054 (A8)101 min · $33.17
  27. v26The agent tried a beam inside every row, and it cost far too much time.15,035,389 (A11)104 min · $34.57
  28. v28The agent tried caching column transitions, and copying cost more than it saved.15,035,389 (A11)108 min · $36.33
  29. v29The agent retried the cache with cheaper copies, and it still did not pay.15,035,389 (A11)111 min · $38.53
  30. v30The agent tried squeezing the last two plates into one, and none ever fit.11,755,878.9119 min · $41.98
  31. v31The agent used a fourth-stage cut to pair two ordered items in one slot.11,741,112.9130 min · $47.13
  32. v32The agent widened the paired path's structures, and the greedy path got worse.6,943,206 (A9)131 min · $47.66
  33. v33The agent let every column pick its own row heuristic.11,374,530.9142 min · $49.19
  34. v34The agent pruned policy trials by a column's role and halved the runtime.11,374,530.9150 min · $49.99
  35. v35The agent retired fixed layouts the adaptive search already subsumed.27,784,788 (A14)153 min · $50.63
  36. v36The agent tried richer endgame grammars, and the tail was not the bottleneck.27,784,788 (A14)162 min · $52.38
  37. v37The agent tried advancing plates by item count, and the tail came out worse.27,784,788 (A14)164 min · $52.66
  38. v38The agent tried paired stage-4 cuts on bigger batches, for no gain.14,289,408 (A18)166 min · $53.17
  39. v39The agent offset the width grid by 50mm, and every alternative was dominated.23,671 (A18 cost)167 min · $53.55
  40. v40The agent gave tiny batches the full structure set with mixed policies.11,251,587.9172 min · $54.55
  41. v41The agent raised that cutoff and the held-out cases improved too.11,167,806.9174 min · $55.12
  42. v42The agent kept several plate frontiers alive for the mixed-policy search.11,145,978.9177 min · $55.90
  43. v43The agent stretched the mixed beam to larger batches while guarding the clock.11,136,348.9180 min · $56.90
  44. v44The agent stretched it further still, and the extra search bought nothing.22,339,244 (A8)181 min · $57.22
  45. v45The agent kept a fourth frontier state and one case gained a lot.11,090,445.9183 min · $57.93
  46. v46The agent tried six frontier states, and the beam had already saturated.13,772,598 (A18)184 min · $58.32
  47. v47The agent swapped a frontier state for a more diverse one, and it hurt.23,213 (A18 cost)186 min · $58.76
  48. v48The agent put a plate beam around the paired stage-4 packer too.11,070,543.9188 min · $59.43
  49. v49The agent widened that paired beam, and nothing improved.7,042,321 (A17)189 min · $59.91
  50. v50The agent gave the paired beam every structure, and it was dominated.7,042,321 (A17)191 min · $60.66
  51. v51The agent solved tiny one-stack orders exactly instead of heuristically.11,038,443.9193 min · $61.88
  52. v52The agent tried the exact shelf solver on any small tail, and pairs still won.7,042,321 (A17)195 min · $62.66
  53. v53The agent let every column try all four policies in a wider beam.11,031,381.9198 min · $64.35
  54. v54The agent widened that all-policy beam, and it stopped paying.7,874,550 (A4)200 min · $64.94
  55. v55The agent gave the large-batch beam a handful of high-yield structures.11,015,331.9201 min · $65.58
  56. v56The agent tried a wider large-batch beam, and the clock said no.79,248 (A14 cost)204 min · $66.63
  57. v57The agent retried it without the dead fallbacks, and it was still too slow.27,595,398 (A14)205 min · $67.17
  58. v58The agent solved the final few items exactly, across every legal order.10,904,586.9216 min · $71.61
  59. v59The agent tried exact tails of up to ten items with the order frozen.7,874,550 (A4)218 min · $72.46
  60. v60The agent cut the exact tail's kept states to two, and lost a case's gain.6,895,283 (A16)219 min · $72.96
  61. v61The agent settled on three kept states, same quality with more time to spare.10,904,586.9221 min · $73.95

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (GPT-5.6-sol)0.34710.3908
720 minWall clock
$78.98Spend
125.5MTokens
18Versions, 17 kept

On the visible set

0 25M 50M 75M 100M 0 4 8 12 16 Agent step Visible mean waste ↓ v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16
keptrolled backsubmitted
  1. v0The agent started from the shipped one-item-per-column baseline100,235,03510 min · $1.89
  2. v1The agent rewrote the packer in C++, drawing items only from stack headsDraw every item from a stack head so the sequence constraint costs nothing, then randomise restarts.10,061,64122 min · $4.44
  3. v2The agent added a plate-level beam and an exact Pareto DP per bandBound the search on both levels: an admissible plate ranking outside, lossless dominance pruning inside.8,001,78491 min · $14.18
  4. v3The agent ranked plates by an assumed density instead of a weak bound7,460,899102 min · $15.39
  5. v4The agent added ruin-and-recreate restarts and forked across the CPU quota7,260,595124 min · $18.33
  6. v5The agent fixed near-greedy columns by bucketing bands by heightEffective branching had collapsed to one; bucket bands by the dimension that decides how the rest of the column fills.6,187,813162 min · $22.21
  7. v6The agent diversified column candidates across both width and height bins5,947,384186 min · $24.18
  8. v7The agent fuzzed itself against the real checker and fixed the crashes227,209254 min · $31.67
  9. v8The agent built an order-fixed DP and proved its packing already optimal5,978,521290 min · $35.70
  10. v9The agent confined the robustness hack to emergency realisation passes226,964301 min · $36.60
  11. v10The agent built a held-out instance set to confirm its gains generalised226,584350 min · $42.98
  12. v11The agent capped a runaway cache and cut worker memory tenfold5,929,729365 min · $45.43
  13. v12The agent opened up few-stack instances with a per-stack take limit226,825437 min · $54.42
  14. v13The agent let band heights come from deeper stack items, not heads226,661484 min · $58.87
  15. v14The agent removed dead code and swept the effort-growth knob5,840,812554 min · $65.14
  16. v15The agent proved most band-height candidates useless and dropped them5,573,740636 min · $68.82
  17. v16The agent polished the build and audited its gap to the optimum5,594,926659 min · $72.76
  18. v17The agent bounded the wait on forked workers and stress-tested odd parametersno number logged$75.87

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (Opus 5)0.79060.5535
39 minWall clock
$5.86Spend
34.4MTokens
5Versions, 4 kept

On the visible set

0 20M 40M 60M 80M 100M 0 1 2 3 4 Agent step Visible mean waste ↓ v0 v1 v2 v3 v4
keptrolled backsubmitted
  1. v0The agent started from the shipped one-item-per-column baseline100,235,034.9
  2. v1The agent rewrote the packer in C++ so items stacked inside columns44,847,447.9
  3. v2The agent added multi-item rows and a multi-tier beam search16,792,047.9
  4. v3The agent packed rows tighter and swept the beam's parameters10,296,933.9
  5. v4The agent ran several beam configurations and stopped columns early8,928,510.9

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (Gemini 3.7 Flash)0.52040.4708
336 minWall clock
$17.96Spend
46.2MTokens
15Versions, 14 kept

On the visible set

0 20M 40M 60M 80M 100M 0 3 6 9 12 Agent step Visible mean waste ↓ v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v14
keptrolled backsubmitted
  1. v0The agent started from the shipped one-item-per-column baseline100,235,035$0.55
  2. v1The agent built a randomized greedy C++ packer with defect-safe cutsRestart one cheap greedy pass many times, with every cut checked against defects in absolute plate coordinates.15,427,156$1.10
  3. v2The agent added beam search inside columns and on the final plateReplace greedy column fill with a beam, and mirror the checker in-process so an invalid plan never ships.13,902,727$3.76
  4. v3The agent retuned the beam and scored columns by density13,243,072$4.34
  5. v4The agent optimized the last few plates jointly as an endgame12,661,420$7.14
  6. v5The agent added noise to its width estimates to widen the search11,158,498$7.95
  7. v6The agent spent more of the budget on estimates and retries10,371,406$8.56
  8. v7The agent picked candidate widths by density as well as area10,211,548$9.16
  9. v8The agent stopped abandoning plates when a defect blocked every row startA defect blocking every row start at a column edge was leaving near-empty plates, the largest source of variance.8,082,034$11.47
  10. v9The agent rewarded rows that filled a column's width exactly8,106,430$12.53
  11. v10The agent enabled that exact-fill bonus only on large instances7,950,424$13.04
  12. v11The agent moved budget from the endgame back to global restarts7,844,494$13.76
  13. v12The agent added a hard wall-clock abort so no case timed out7,844,494$15.02
  14. v13The agent fixed a relative-path bug that broke run.sh outside selfchecksame as v12$15.89
  15. v14The agent tightened the time guard and verified every fallback path7,853,803$17.42

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (Kimi K3)0.57540.4907
66 minWall clock
$16.54Spend
28.8MTokens
5Versions, 3 kept

On the visible set

20M 40M 60M 80M 100M 0 30 60 90 120 Agent step Visible mean waste ↓ v1 v3 v4 v5
keptrolled backsubmitted
  1. v1The agent started from the shipped one-item-per-column baseline100,235,034.9
  2. v2The agent tried a three-stage shelf packer that broke the cut rules7/10 valid, reverted
  3. v3The agent isolated defects and flushed items so fourth cuts stayed legalGet the 3-stage geometry legal first: keep every cut clear of defects and let shelves take exact widths.15,440,959
  4. v4The agent searched shelf orders and shrank columns only when legalSearch the order the shelves are built in, restart-heavy, instead of packing them in one fixed pass.12,666,555.9
  5. v5The agent added early random restarts that found a four-plate packing12,602,676.9

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (Grok 4.6)0.43950.4374
38 minWall clock
$1.09Spend
6.5MTokens
2Versions, 1 kept

On the visible set

45M 60M 75M 90M 105M 120M 0 20 40 60 80 Agent step Visible mean waste ↓ v0 v1
keptrolled backsubmitted
  1. v0The agent started from the shipped one-item-per-column baseline113,500,00013 min · $0.30
  2. v1The agent mirrored the checker's rules to build a dense legal layout42,500,00038 min · $1.05

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (DeepSeek V4 Pro)0.14480.2180
209 minWall clock
$17.75Spend
60.3MTokens
6Versions, 4 kept

On the visible set

98.25M 99.00M 99.75M 100.50M 101.25M 0 2 3 4 Agent step Visible mean waste ↓ v0 v1 v2 v3
keptrolled backsubmitted
  1. v0The agent started from the shipped one-item-per-column baseline100,235,03517 min · $0.95
  2. v1The agent grouped same-width items into columns and repaired defects with spacers98,231,35355 min · $4.81
  3. v2The agent annealed item orders, and rigid width classes invalidated two cases101,600,00058 min · $5.11
  4. v3The agent annealed the layout structure itself, gaining only on small cases98,200,000144 min · $17.75
  5. v3.1The agent added ruin-and-recreate moves and an internal output verifiersame scores as v3$17.75
  6. v3.2The agent fixed the greedy initializer its own evaluator always rejectedA14 135.9M, no suite$17.75

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (Qwen3.8 Max)0.24830.3245
150 minWall clock
$8.01Spend
24.9MTokens
4Versions, 3 kept

On the visible set

50M 60M 70M 80M 90M 100M 0 1 2 2 3 Agent step Visible mean waste ↓ v0 v1 v2 v3
keptrolled backsubmitted
  1. v0The agent started from the shipped one-item-per-column baseline100,200,000$3.45
  2. v1The agent built a C++ three-stage packer and searched a config grid79,400,000138 min · $6.90
  3. v2The agent made column creation order match cut order so sequences held52,900,000141 min · $7.20
  4. v3The agent charged non-final plates their full width in the objective52,000,000147 min · $7.79

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (GLM 5.3)0.13270.2007
65 minWall clock
$12.77Spend
18.7MTokens
19Versions, 15 kept

On the visible set

30M 45M 60M 75M 90M 105M 0 40 80 120 160 Agent step Visible mean waste ↓ v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18
keptrolled backsubmitted
  1. v0The agent started from the shipped one-item-per-column baseline100,235,034.92 min · $0.55
  2. v1The agent tried an online shelf packer that packed worse than baseline102,791,478.97 min · $1.41
  3. v2The agent capped shelf width to pair columns, and one case turned invalid85,010,267.678 min · $1.67
  4. v3The agent added a defect validator and fell back when layouts broke it84,218,418.99 min · $1.97
  5. v4The agent limited column height to leave slack for dodging defects72,846,351.910 min · $2.32
  6. v5The agent grid-tuned the width and height caps together64,545,291.910 min · $2.62
  7. v6The agent tried thirty cap pairs per instance and kept the best valid51,099,564.912 min · $2.91
  8. v7The agent added five row-selection modes and searched 150 layouts per case45,368,109.913 min · $3.30
  9. v8The agent densified the cap grid to 455 layouts per case42,732,057.915 min · $3.82
  10. v9The agent padded rows so defects could hide above or below items42,314,115.918 min · $4.30
  11. v10The agent gated that padding to small batches to save runtime42,314,115.920 min · $4.74
  12. v11The agent offered small batches a richer set of row paddings41,874,024.924 min · $5.37
  13. v12The agent extended the caps to much narrower columns and shorter heights33,213,765.928 min · $6.04
  14. v13The agent pushed widths to 1000mm for four-to-six column plates30,053,520.933 min · $6.83
  15. v14The agent added two stack-biased row modes and paid too much runtime29,773,929.943 min · $8.39
  16. v15The agent kept those stack-biased modes only for large batches29,773,929.949 min · $9.32
  17. v16The agent narrowed those modes further to the narrowest columns only29,773,929.953 min · $10.12
  18. v17The agent refined the width grid to 50mm steps29,130,003.960 min · $11.24
  19. v18The agent pruned the fine widths back to the heights that used them29,130,003.964 min · $12.42

On the hidden set

Original metricNormalised score
Starter0.04810.0
Frontier-calibrated reference1.00.6
Upper1.51.0
This run (GPT-5.5)0.18950.2711

Leaderboard

Where each run landed on the sealed held-out set, on the same normalised-score scale as the anchors above.

0 0.3 0.6 1.0 1 Opus 5 claude code · max 0.554 2 Kimi K3 kimi cli · max 0.491 3 Gemini 3.7 Flash antigravity · high 0.471 4 Grok 4.6 grok · xhigh 0.437 5 GPT-5.6-sol codex · max 0.391 6 Qwen3.8 Max qwen coder · xhigh 0.325 7 GPT-5.5 codex · xhigh 0.271 8 DeepSeek V4 Pro claude code · max 0.218 9 GLM 5.3 claude code · max 0.201