homemaker-layout/experiments/run_e01_sweep.py
Bruno Postle 15abba9679 e01: harbor-house beam-width larger-N confirmation (null)
N=15 driver.search sweep of construction_beam_width 1 vs 4 (protocol
identical to c94's original 5-seed run, DESIGN.md §29): 6W/4L/5T, mean
fails 57.0->56.6, Wilcoxon p=0.84. Excluding seed 2's outlier the mean
flips slightly negative (56.3->56.9), confirming the §29 5-seed
"improvement" was that one outlier. construction_beam_width stays
default 1 on confirmed rather than precautionary grounds. DESIGN.md §30.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R8agJBT2ZpmF3ErW7wi2wY
2026-07-29 00:22:55 +01:00

63 lines
1.9 KiB
Python

"""homemaker-py-e01: larger-N harbor-house-only sweep, construction_beam_width
1 vs 4, following the exact protocol of c94's original 5-seed end-to-end run
(DESIGN.md §29) -- driver.search from a clean bootstrap (init.dom), n_workers=1
for reproducibility, budget=1500, same seed both arms, all other driver.search
kwargs left at default. Extends seeds 1-5 (reproduced here as a sanity check
against the DESIGN.md §29 table) up to N=15 seeds.
Usage: python experiments/run_e01_sweep.py
"""
from __future__ import annotations
import sys
import time
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from homemaker_layout import dom, driver # noqa: E402
ROOT = Path(__file__).resolve().parents[1]
EX = ROOT / "examples" / "harbor-house"
BUDGET = 1500
SEEDS = range(1, 16)
OUT = ROOT / "scratch" / "e01_sweep_results.tsv"
def run(seed: int, bw: int) -> tuple[int, float]:
seed_root = dom.load(str(EX / "init.dom"))
r = driver.search(
seed_root,
EX,
budget=BUDGET,
seed=seed,
n_workers=1,
construction_beam_width=bw,
)
return r.best.n_fails, r.best.fitness
def main() -> None:
OUT.parent.mkdir(exist_ok=True)
with open(OUT, "w") as f:
f.write("seed\tbw1_fails\tbw4_fails\tresult\telapsed_s\n")
for seed in SEEDS:
t0 = time.perf_counter()
fails1, _ = run(seed, 1)
fails4, _ = run(seed, 4)
elapsed = time.perf_counter() - t0
if fails4 < fails1:
result = "bw4 win"
elif fails4 > fails1:
result = "bw4 loss"
else:
result = "tie"
line = f"{seed}\t{fails1}\t{fails4}\t{result}\t{elapsed:.1f}"
print(line, flush=True)
f.write(line + "\n")
f.flush()
if __name__ == "__main__":
main()