solver: construct odd-order solutions

Avoid repeating the exponential search for odd orders at least nine. Search the even predecessor, translate its row-major placements to the enlarged board, and tile the new border.

Keep direct search and construction explicit so benchmarks can report their costs separately. Verify the routed order-9 result independently and require its search counters to match order 8.

Tests: Release, Debug, ASan and UBSan CTest (8 passed each)

Refs: #6
This commit was merged in pull request #21.
This commit is contained in:
Codex instance
2026-07-30 17:24:06 +01:00
parent ddf07e730a
commit 3e667d6de0
6 changed files with 189 additions and 44 deletions
+32 -9
View File
@@ -16,19 +16,20 @@ The default policy is one unrecorded warm-up followed by five repetitions per
case, with a 600-second timeout for each process. Solver stdout is captured;
the probe renders into an in-memory stream so grids do not perturb terminal I/O.
Override the policy with `--orders`, `--warmup`, `--repetitions`, and
`--timeout`. Order 9 is intentionally supported but may be omitted during
local iteration because the current solver takes minutes:
`--timeout`. Order 9 uses the constructive odd-order path, searching order 8
and then tiling the enlarged border, so it is suitable for normal local
benchmarking:
```sh
python3 benchmarks/run.py --binary build-benchmark/partridge_benchmark \
--orders 7 8 --warmup 1 --repetitions 5 --timeout 60 > benchmark.json
--orders 8 9 --warmup 1 --repetitions 5 --timeout 60 > benchmark.json
```
The JSON contains every run and median, range, and median absolute deviation
for solve, construction, independent validation, and rendering. The current
direct-search solver reports zero construction time: its setup and allocation
remain part of solve time. The separate construction field is reserved for
future constructive solution paths. The document also records compiler,
for solve, construction, independent validation, and rendering. Direct-search
cases report zero construction time: their setup and allocation remain part of
solve time. Constructed odd-order cases report predecessor search and
construction separately. The document also records compiler,
flags, build type, commit, OS/CPU metadata, worker count, search policy, seed,
timeouts, errors, invalid outputs, and the stdout policy. Search counts must
be stable across repeated runs. Prune and task counters are zero for the
@@ -80,8 +81,30 @@ Counts were stable across repetitions. Interleaved counter-free medians were
overheads of 0.53% and 0.64% respectively. Construction time was zero; median
independent validation and rendering times were each below 0.02 milliseconds.
Order 9 was not rerun for this initial baseline because its documented runtime
is several minutes. The default suite includes it with a per-run timeout.
Order 9 was not rerun for this initial baseline because the former direct
search took several minutes. The default suite includes it with a per-run
timeout.
## Odd construction comparison
The order-9 construction was measured from the issue 6 working tree based on
commit `ddf07e7`, using Apple Clang 21.0.0 with `-O3 -DNDEBUG`, macOS arm64,
one worker, one warm-up, and three measured repetitions. Counter-free and
counted runs were interleaved:
| Order | Mode | Search median (range) | Construction median | Nodes |
| --- | --- | --- | --- | ---: |
| 8 | counter-free | 1.773 s (1.7701.775 s) | 0 | 0 |
| 8 | counted | 1.849 s (1.8481.850 s) | 0 | 60,485,176 |
| 9 | counter-free | 1.778 s (1.7731.779 s) | 0.458 us | 0 |
| 9 | counted | 1.852 s (1.8451.912 s) | 0.416 us | 60,485,176 |
All runs completed with valid results and stable counters. The matching
order-8 and order-9 search counts demonstrate that the new path searches only
the predecessor. Compared with the recorded 158.69-second direct order-9
elapsed time in `results.md`, the 1.778-second counter-free median plus
construction is approximately 89 times faster. The benchmark working tree
was necessarily dirty with the issue 6 implementation.
New optimization issues should quote the exact JSON
environment, policy, median/spread, stable counters, and counted overhead from