floor-planner/benchmarks
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Andras Schmelczer 171fbf1927
All checks were successful
Deploy to Pages / build (push) Successful in 26s
better patterns
2026-09-11 22:46:23 +01:00
..
baseline.json landing 2026-09-11 20:34:36 +01:00
cases.ts better 2026-09-11 22:14:24 +01:00
h-pattern-baseline.json better patterns 2026-09-11 22:46:23 +01:00
metrics.ts better patterns 2026-09-11 22:46:23 +01:00
README.md better patterns 2026-09-11 22:46:23 +01:00

Optimiser measurements

Run npm run benchmark for Minimise cuts, or npm run benchmark -- --random for Maximise randomness. Both are compared with the original stock-first optimiser's frozen results in baseline.json. The 84 inputs in cases.ts cover rectangular remainders, fireplaces in both directions, room-order permutations, tight and exact stagger limits, fractional stock, large floors, and both supplied angled rooms. --output=/tmp/results.json saves a run; --compare=/tmp/results.json compares against a previous iteration. Do not overwrite the baseline to hide regressions. h-pattern-baseline.json separately freezes both options immediately before the visual H-pattern correction, evaluated using the broader alignment metric below.

Fixed metrics

  • Saw passes: crosscuts actually required by the allocation, long-edge rips, and additional shaping edges. Skirting includes bevel and coping operations.
  • Cut difficulty: shaping passes, then rip passes, used to break equal saw-count ties. This is an explicit proxy, not an estimate of minutes or tool-specific effort.
  • Legacy repetition: the original penalty, evaluated independently from the output rows. It penalises nearby repeating joints, similar consecutive steps and staircases, including steps that wrap across a board length. Raw repeat, similar-step and staircase counts are also reported. This stays unchanged for historical comparisons, but its 3%-of-board-length alignment tolerance missed visible H patterns.
  • Near-H row pairs: joints two rows apart separated by less than one board width, capped at one sixth of the board length. This catches the 40–150 mm misalignments that still look like an H. Current appearance cost is the legacy penalty plus 12 per near-H pair, so avoiding an H outweighs several same-direction steps.
  • Waste: purchased stock minus installed material, including kerf. The report gives board counts and waste percentages weighted by purchased stock.
  • Validity and runtime: errors, elapsed time, p95 and maximum case time. Tests separately verify coverage, non-overlapping row bands, minimum sizes, stagger, factory ends, rounded stock consumption, cut accounting, references and input purity.

Minimise cuts orders (passes, shaping, rips, appearance cost, boards). Maximise randomness orders (appearance cost, passes, shaping, rips, boards). Validity precedes either objective. Skirting orders (passes, waste).

Measured results

Totals across the same 84 cases, September 2026:

Metric Original Minimise cuts Maximise randomness
Flooring saw passes 2,177 1,741 2,113
Shaping passes 192 184 188
Rip passes 414 402 409
Legacy penalty 265 2,207 346
Flooring boards 3,561 3,548 3,551
Flooring waste 8.20% 7.85% 7.94%
Invalid cases 0 0 0

Minimise cuts saves 20.0% of saw passes. Maximise randomness saves 2.9% of saw passes against the original planner. For random flooring in the default 4,800 × 3,600 mm room, 38 passes become 24 or 31, respectively; both options use 76 boards and have approximately 1.2% waste.

Skirting drops from 1,447 to 1,436 passes. It uses 521 boards instead of 513: cutting effort now takes precedence over waste, which rises from 9.28% to 10.68%. Eight cases improve and 76 tie. For flooring, 78 cut-priority cases improve and six tie against the original planner. The bounded search does not establish global optimality.

H-pattern correction

The first optimisation reported a 57% lower legacy penalty, but visual inspection showed that the metric was too narrow. The default appearance-priority room still had 11 near-H row pairs, despite no repeats within the old 36 mm tolerance. The candidate hash also generated almost identical offsets for adjacent candidate numbers. A final bit-mixing step now spreads those candidates across the allowed range.

Metric Cuts before Cuts now Random before Random now
Near-H row pairs 515 247 557 6
Saw passes 1,741 1,741 1,994 2,113
Boards 3,537 3,548 3,579 3,551
Waste 7.57% 7.85% 8.66% 7.94%
Default-room near-H pairs 17 17 11 0
Default-room saw passes 24 24 30 31

Appearance priority removes 98.9% of near-H pairs for 6.0% more cuts than the previous iteration. All six remaining pairs are in forced-alternation, whose 600 mm minimum pieces force alternating starts. It improves 79 cases and ties five under the corrected objective. Ten additional room seeds also produce zero near-H pairs.

The tradeoff is explicit: the old direction-run/staircase score increases, and the randomness option uses more cuts. Cuts-first retains its total saw count but three individual cases use extra cuts (two-rooms-reversed-6, angled, angled-f8). It can still show H patterns when avoiding them requires extra cuts; the UI explains this beside the laying-pattern choice. Both frozen baselines remain unchanged.

Iterations retained

  1. Correct the objective order; measuring stock first contradicted the requested priorities.
  2. Deduplicate the complete relevant state, including recent joint history. Stop computing keys once the beam is full; share immutable exhausted stocks and avoid searching offcuts for pieces requiring both factory ends.
  3. Repack completed boundary blanks, reserving exact complementary factory ends first. Preserve the original placement and cutting order within each source board.
  4. Try bounded swaps of interchangeable rectangular rows. Accept only a lower pattern penalty with unchanged cuts, stock and geometry coverage.
  5. Polish all surviving completed candidates, retaining the best result.
  6. Preserve end remnants during search instead of trimming them immediately. This alone improves 56 cut-priority cases and saves another 99 passes after the earlier improvements. Final packing can still combine non-exact blanks.
  7. When repetition remains, compare an immediate-reuse search as well. This improves five appearance-priority cases. All searches share their clipping cache, and the two UI choices select from the completed results. Selection itself does not rerun the optimiser.
  8. Compare exact three-piece skirting fills with the original packing. This improves two cases for a small additional calculation cost.
  9. Add the board-scale H penalty and mix the offset hash. Search size and geometry constraints stay unchanged. Before/after drawings were checked for the default rectangle, fireplace and large floor, alongside the numeric metrics.

Experiments rejected

Increasing beam widths from 5/2 to 12/4 roughly tripled search time, with regressions in both modes. Carrying two room results into the next room worsened two appearance cases for a single waste improvement. Expanding the offcut candidate pool with distinct remnants had no cut-priority benefit and regressed a large-room result, including after the end-preservation change. These variants were removed.

The original single-result benchmark took about 1.5 seconds for the corpus. Producing both choices, including the conditional extra appearance search, takes about 3 seconds on the same machine; p95 is around 110 ms and the most complex case around 0.7 seconds. These are indicative timings, not CI thresholds. Ordinary option changes reuse the already calculated plans. A separate 500-row, 2,000-board boundary check completes without an error; temporary stock is repacked before enforcing the board limit.

Tests enforce aggregate cutting budgets, broad H avoidance and physical invariants. The original metrics and cases remain fixed; the new H metric has its own frozen baseline so the correction does not rewrite the earlier results.