solver: replace cell DFS with skyline search
Represent partial placements as column heights and branch on the narrowest local valley. This removes the board-area cell state and makes first-solution search substantially smaller for feasible orders. Expose direct-search and candidate-order benchmark controls so the skyline core can be measured independently of odd-order construction. Document the completeness argument and the 10/11 test-tier decision. Tests: Release, Debug, ASan, and UBSan CTest (10 passed each) Refs: #4
This commit was merged in pull request #23.
This commit is contained in:
+27
-5
@@ -74,16 +74,16 @@ def environment(binary):
|
||||
"logical_cpus": os.cpu_count(),
|
||||
},
|
||||
"workers": 1,
|
||||
"search_policy": "single-threaded, deterministic, largest-fitting-first",
|
||||
"search_policy": "single-threaded, deterministic, smallest-width valley",
|
||||
"seed": None,
|
||||
}
|
||||
|
||||
|
||||
def run_once(binary, order, mode, timeout):
|
||||
def run_once(binary, order, mode, candidate_order, search_route, timeout):
|
||||
started = time.monotonic()
|
||||
try:
|
||||
process = subprocess.run(
|
||||
[str(binary), str(order), mode],
|
||||
[str(binary), str(order), mode, candidate_order, search_route],
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
@@ -216,6 +216,12 @@ def main():
|
||||
parser.add_argument("--warmup", type=int, default=1)
|
||||
parser.add_argument("--repetitions", type=int, default=5)
|
||||
parser.add_argument("--timeout", type=float, default=600.0)
|
||||
parser.add_argument(
|
||||
"--candidate-order",
|
||||
choices=("ascending", "descending"),
|
||||
default="ascending",
|
||||
)
|
||||
parser.add_argument("--direct-search", action="store_true")
|
||||
parser.add_argument(
|
||||
"--measure-overhead",
|
||||
action="store_true",
|
||||
@@ -241,11 +247,25 @@ def main():
|
||||
mode_results = {mode: {"runs": []} for mode in modes}
|
||||
for trial in range(args.warmup):
|
||||
for mode in trial_modes(modes, trial):
|
||||
run_once(args.binary, order, mode, args.timeout)
|
||||
run_once(
|
||||
args.binary,
|
||||
order,
|
||||
mode,
|
||||
args.candidate_order,
|
||||
"direct" if args.direct_search else "public",
|
||||
args.timeout,
|
||||
)
|
||||
for trial in range(args.repetitions):
|
||||
for mode in trial_modes(modes, trial):
|
||||
mode_results[mode]["runs"].append(
|
||||
run_once(args.binary, order, mode, args.timeout)
|
||||
run_once(
|
||||
args.binary,
|
||||
order,
|
||||
mode,
|
||||
args.candidate_order,
|
||||
"direct" if args.direct_search else "public",
|
||||
args.timeout,
|
||||
)
|
||||
)
|
||||
for result in mode_results.values():
|
||||
result["summary"] = summarize(result["runs"])
|
||||
@@ -270,6 +290,8 @@ def main():
|
||||
"warmup_runs": args.warmup,
|
||||
"measured_repetitions": args.repetitions,
|
||||
"per_run_timeout_seconds": args.timeout,
|
||||
"candidate_order": args.candidate_order,
|
||||
"search_route": "direct" if args.direct_search else "public",
|
||||
"stdout": "captured; rendered grid suppressed by probe",
|
||||
},
|
||||
"cases": cases,
|
||||
|
||||
Reference in New Issue
Block a user