homemaker-layout/experiments/run_leu2_ab.sh
Bruno Postle 995342d0a4 Phase 7 §12.2: proportion-aware constructive seeding + storey_minimum fix (leu.2, cq1)
Size each constructive-seed cut from leaf TARGET areas (division=[f,f] gives
left area-fraction f) and pick each cut's rotation for child squareness — both
derived from target dims, topology/type assignment untouched. Area-only
regressed (slivers); rotation choice is what makes it pay.

End-to-end (20000 evals, 3 seeds, staged): harbor 85.3->74.0 (-13%, best 69),
maple-court 151.7->136.0 (-10%, best 126). PROP=0 reproduces the §11.7/§12.1
baselines exactly. programme-house regresses at fixed budget (deeper local
optimum walls off the undivide restructuring path) but a budget sweep shows
it's convergence speed, not a worse asymptote (PROP=1 reaches 1 fail at 150k).
Default-on (seed_proportion_aware=True, env PROP=1).

cq1: n_storeys now honours storey_minimum, not just level: keys — programme-house
(storey_minimum:2, all rooms level:0) was seeded one storey short and fell
through to plain search. New programme.storey_minimum()/n_storeys_for();
driver.search passes min_storeys to the seeder; search_staged routes on the max.
No-op for harbor/maple; programme-house single-stage 8.0->5.0.

New maple-court best (126) saved as generated.dom. 204 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 14:04:42 +01:00

49 lines
1.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# leu.2 end-to-end A/B: proportion-aware split sizing (PROP=0 vs PROP=1).
# programme-house is single-stage (1 storey); harbor & maple-court are staged.
# Concurrency capped at 2 (machine has ~2 GB free). Results -> scratch/leu2/summary.tsv
set -u
cd "$(dirname "$0")/.."
OUT=scratch/leu2
mkdir -p "$OUT"
SUMMARY="$OUT/summary.tsv"
: > "$SUMMARY"
BUDGET=${BUDGET:-20000}
SEEDS=${SEEDS:-"0 1 2"}
MAXJOBS=${MAXJOBS:-2}
run_one() {
local prog=$1 harness=$2 prop=$3 seed=$4
local tag="${prog}_p${prop}_s${seed}"
local log="$OUT/${tag}.log"
URB_NO_OCCLUSION=1 PROP=$prop python3 "experiments/$harness" \
"examples/$prog" "$BUDGET" "$seed" "examples/$prog/init.dom" \
"$OUT/${tag}.dom" > "$log" 2>&1
local best
best=$(grep -oE 'best *: [0-9.eE+-]+ \([0-9]+ fails\)' "$log" | grep -oE '\([0-9]+ fails\)' | grep -oE '[0-9]+' | tail -1)
printf '%s\t%s\t%s\t%s\t%s\n' "$prog" "$prop" "$seed" "${best:-ERR}" "$tag" >> "$SUMMARY"
echo "DONE $tag -> ${best:-ERR} fails"
}
JOBS=()
for prog_h in "programme-house:run_search_scaled.py" \
"harbor-house:run_staged_search.py" \
"maple-court:run_staged_search.py"; do
prog=${prog_h%%:*}; harness=${prog_h##*:}
for prop in 0 1; do
for seed in $SEEDS; do
JOBS+=("$prog|$harness|$prop|$seed")
done
done
done
echo "queued ${#JOBS[@]} jobs, budget=$BUDGET, maxjobs=$MAXJOBS"
for job in "${JOBS[@]}"; do
IFS='|' read -r prog harness prop seed <<< "$job"
while [ "$(jobs -rp | wc -l)" -ge "$MAXJOBS" ]; do wait -n; done
run_one "$prog" "$harness" "$prop" "$seed" &
done
wait
echo "ALL DONE"
sort "$SUMMARY" -o "$SUMMARY"
cat "$SUMMARY"