solver: prune unplaceable large squares
A skyline may retain enough total empty area while no longer containing a box for its largest remaining square. Scan for the required consecutive low columns and reject such monotonic dead states. Keep each pruning combination independently measurable and record the small public-path gain, the direct-order-9 regression, and the rejected periodic schedule. Tests: Debug CTest (13 passed) Tests: ASan+UBSan CTest (13 passed) Refs: #15
This commit was merged in pull request #27.
This commit is contained in:
+52
-2
@@ -21,8 +21,9 @@ and `--candidate-order`. The choices are `ascending`, `descending`, and
|
||||
The production default also removes equivalent D4 board orientations by
|
||||
constraining the unique unit square. Pass `--no-symmetry` to obtain an
|
||||
otherwise identical unconstrained baseline.
|
||||
The production default also applies the valley-capacity rule described below.
|
||||
Pass `--no-pruning` to obtain an otherwise identical unpruned search.
|
||||
The production default also applies the pruning rules described below.
|
||||
Use `--pruning valley-capacity`, `--pruning large-square`, or
|
||||
`--no-pruning` to measure each rule alone or obtain an unpruned search.
|
||||
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:
|
||||
|
||||
@@ -107,6 +108,55 @@ The rule reduced nodes by 7.8% for order 7 and 7.1% for order 8. Its low
|
||||
per-node cost also reduced median counted solve time by 10.3% and 9.9%,
|
||||
respectively, so it remains enabled by default.
|
||||
|
||||
## Remaining-large-square pruning
|
||||
|
||||
For a remaining side `k`, a skyline can contain an empty `k`-by-`k` box only
|
||||
if it has `k` consecutive columns whose filled heights are no greater than the
|
||||
board height minus `k`. A single linear scan tracks qualifying consecutive
|
||||
columns. If no such run exists, the square cannot be placed and the state is
|
||||
infeasible even when its total empty area is sufficient.
|
||||
|
||||
Empty-box feasibility is monotonic in the side length: a box which fits the
|
||||
largest remaining square also fits every smaller remaining size. The solver
|
||||
therefore invokes only one `O(board width)` scan per surviving node, after the
|
||||
cheaper valley-capacity check. It does not attempt an unproven multiplicity
|
||||
bound. `--pruning large-square` measures the rule independently;
|
||||
`--pruning valley-capacity` provides the production baseline without it.
|
||||
Instrumented output records `large_square_checks` and
|
||||
`large_square_prunes`.
|
||||
|
||||
Measurements used the issue #15 working tree based on commit `e27427d`, Apple
|
||||
Clang 21.0.0, `-O3 -DNDEBUG`, macOS arm64, one worker, one warm-up, and seven
|
||||
measured repetitions. Counter-free and counted runs were interleaved; the
|
||||
table reports the counter-free production instantiation. The baseline keeps
|
||||
valley-capacity pruning enabled, so it isolates the new rule. All results
|
||||
passed independent validation and counters were stable:
|
||||
|
||||
| Search | Large-square check | Median solve | Nodes | Checks | Prunes |
|
||||
| --- | --- | ---: | ---: | ---: | ---: |
|
||||
| Order 7 exhaustive | enabled | 0.946 s | 13,221,239 | 6,163,390 | 227,321 |
|
||||
| Order 7 exhaustive | disabled | 0.947 s | 13,833,048 | 0 | 0 |
|
||||
| Order 8 first solution | enabled | 0.195 s | 2,597,678 | 1,063,472 | 38,177 |
|
||||
| Order 8 first solution | disabled | 0.197 s | 2,724,096 | 0 | 0 |
|
||||
| Order 9 direct | enabled | 1.225 s | 14,840,146 | 5,592,843 | 54,900 |
|
||||
| Order 9 direct | disabled | 1.208 s | 14,995,127 | 0 | 0 |
|
||||
|
||||
The rule reduced nodes by 4.4% for order 7, 4.6% for order 8, and 1.0% for
|
||||
direct order 9. Counter-free median time improved by 0.12% and 0.89% on the
|
||||
two distinct searches in the public benchmark set. Public order 9 constructs
|
||||
from the improving order-8 search. Direct order 9, which bypasses that public
|
||||
route, regressed by 1.39%; it remains documented as a caution for future
|
||||
policy tuning.
|
||||
|
||||
Checking only every fourth placement depth was also measured. It retained
|
||||
fewer prunes and was slower than checking every surviving node by 2.2% for
|
||||
order 7, 2.3% for order 8, and 0.6% for direct order 9, so the periodic
|
||||
schedule was rejected. Incremental maintenance would need additional
|
||||
per-size window state and undo logic for an `O(W)` scan whose public net cost
|
||||
is already recovered; it was not added without evidence that the complexity
|
||||
would improve elapsed time. The simple every-node scan remains enabled by
|
||||
default for the measured public benchmark benefit.
|
||||
|
||||
## D4 board symmetry
|
||||
|
||||
Every solution contains exactly one 1-by-1 square. Rotations and reflections
|
||||
|
||||
Reference in New Issue
Block a user