Adds operators.mutate_ruin_recreate: un-divides one wing of a storey and rebuilds it with the same adjacency-aware constructor the seeders use (_assign_adjacency_aware, generalised with a new `scope` param), seeded from the surviving circulation bordering the wing. Gated behind enable_ruin_recreate (default off) / --ruin-recreate, same pattern as reassociate/bridge_circulation. A/B (qpk protocol, DESIGN.md §23): initial uniform-weight run was underpowered (fired ~1/32 children), null. A weight=3.0 follow-up (_MUTATION_WEIGHTS["ruin_recreate"]) showed a statistically significant win on programme-house across 15 seeds (8W/1L/6T, mean fails 7.07->6.00, Wilcoxon p=0.041) but no consistent effect on harbor-house across 8 seeds (3W/2L/3T). Kept default off pending a size-threshold follow-up. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
53 lines
2.3 KiB
Bash
Executable file
53 lines
2.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# f1d A/B: does the ruin-and-recreate LNS move (un-divide one wing of a
|
|
# storey, rebuild it with the adjacency-aware constructor seeded from the
|
|
# surviving circulation bordering the wing) reduce the fail count relative
|
|
# to the current baseline (small local mutation operators only)? Same qpk
|
|
# protocol as 8sh/qi6: equal-budget ON vs OFF, both arms finished with the
|
|
# standard finish-time --collapse (94g) so the comparison is apples-to-apples
|
|
# on the final collapsed score.
|
|
#
|
|
# Authoritative metrics: total fail count read from the .fails file
|
|
# homemaker-fitness writes. Each run appends one TSV row so partial results
|
|
# survive an interrupt.
|
|
#
|
|
# Usage: experiments/run_f1d_ab.sh
|
|
set -u
|
|
cd "$(dirname "$0")/.."
|
|
|
|
WORKERS=4
|
|
OUT=scratch/f1d_ab; mkdir -p "$OUT"
|
|
TSV=scratch/f1d_ab_results.tsv
|
|
[ -f "$TSV" ] || printf 'programme\tseed\truin\tbudget\tfails\tfitness\telapsed_s\n' > "$TSV"
|
|
|
|
run() { # programme seed ruin(0|1) budget
|
|
local prog="$1" seed="$2" rr="$3" budget="$4"
|
|
local tag="rr${rr}"
|
|
local dom="$OUT/${prog}_${tag}_s${seed}.dom"
|
|
local log="$OUT/${prog}_${tag}_s${seed}.log"
|
|
local flag="--no-ruin-recreate"; [ "$rr" = 1 ] && flag="--ruin-recreate"
|
|
echo ">>> $prog seed=$seed ruin_recreate=$rr budget=$budget"
|
|
local t0; t0=$(date +%s)
|
|
homemaker-evolve "examples/$prog/init.dom" \
|
|
--budget "$budget" --workers "$WORKERS" --seed "$seed" \
|
|
$flag --output "$dom" > "$log" 2>&1
|
|
local t1; t1=$(date +%s)
|
|
local fitness fails
|
|
fitness=$(sed -n 's/^best *: \([0-9.e+-]*\) .*/\1/p' "$log")
|
|
fails=$(sed -n 's/^best *: [0-9.e+-]* (\([0-9]*\) fails).*/\1/p' "$log")
|
|
( cd "examples/$prog" && homemaker-fitness "$(realpath "../../$dom")" > /dev/null 2>&1 )
|
|
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
|
|
"$prog" "$seed" "$rr" "$budget" "${fails:-ERR}" "${fitness:-ERR}" "$((t1-t0))" >> "$TSV"
|
|
echo " -> ${fails:-ERR} fails, fitness=${fitness:-ERR}, $((t1-t0))s"
|
|
}
|
|
|
|
# harbor-house: budget 2500, seeds 1-3 (qpk protocol)
|
|
for seed in 1 2 3; do run harbor-house "$seed" 0 2500; done
|
|
for seed in 1 2 3; do run harbor-house "$seed" 1 2500; done
|
|
|
|
# programme-house: budget 3000, seeds 1-5 (qpk protocol)
|
|
for seed in 1 2 3 4 5; do run programme-house "$seed" 0 3000; done
|
|
for seed in 1 2 3 4 5; do run programme-house "$seed" 1 3000; done
|
|
|
|
echo "=== f1d ruin_recreate A/B complete ==="
|
|
column -t -s $'\t' "$TSV"
|