File size: 5,590 Bytes
13d6258 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | """Standalone evaluator for all baseline solutions.
Runs each solution directly (no subprocess) and applies the same
validation/scoring logic as the evaluate_ori.py files.
"""
import sys
import os
import time
import importlib.util
import numpy as np
from scipy.signal import fftconvolve
BASEDIR = os.path.dirname(os.path.abspath(__file__))
RESULTS = os.path.join(BASEDIR, "results")
def load_module(path, name):
spec = importlib.util.spec_from_file_location(name, path)
mod = importlib.util.module_from_spec(spec)
sys.modules[name] = mod
spec.loader.exec_module(mod)
return mod
# ββ Circle Packing ββββββββββββββββββββββββββββββββββββββββββββββββββ
def eval_circle_packing(path):
name = os.path.splitext(os.path.basename(path))[0]
mod = load_module(path, f"cp_{name}")
t0 = time.time()
centers, radii, reported_sum = mod.run_packing()
elapsed = time.time() - t0
centers = np.asarray(centers)
radii = np.asarray(radii)
assert centers.shape == (26, 2), f"centers shape {centers.shape}"
assert radii.shape == (26,), f"radii shape {radii.shape}"
assert np.all(radii >= 0), "negative radii"
actual_sum = float(np.sum(radii))
assert np.isclose(actual_sum, reported_sum, atol=1e-6), \
f"sum mismatch: actual={actual_sum}, reported={reported_sum}"
# boundary check
for i in range(26):
x, y, r = centers[i, 0], centers[i, 1], radii[i]
assert x - r >= -1e-6 and x + r <= 1 + 1e-6, f"circle {i} outside x"
assert y - r >= -1e-6 and y + r <= 1 + 1e-6, f"circle {i} outside y"
# overlap check
for i in range(26):
for j in range(i + 1, 26):
dist = np.sqrt(np.sum((centers[i] - centers[j]) ** 2))
assert dist >= radii[i] + radii[j] - 1e-6, \
f"circles {i}&{j} overlap: dist={dist:.6f}, sum_r={radii[i]+radii[j]:.6f}"
return {"combined_score": actual_sum, "elapsed": elapsed}
# ββ Erdos Min Overlap βββββββββββββββββββββββββββββββββββββββββββββββ
def eval_erdos(path):
name = os.path.splitext(os.path.basename(path))[0]
mod = load_module(path, f"erdos_{name}")
t0 = time.time()
h_values, c5_bound, n_points = mod.run(seed=42, budget_s=10.0)
elapsed = time.time() - t0
h_values = np.asarray(h_values, dtype=np.float64)
n_points = int(n_points)
assert h_values.ndim == 1 and h_values.shape[0] == n_points
assert np.all(np.isfinite(h_values))
# normalize if needed
target = n_points / 2.0
cur = float(np.sum(h_values))
if abs(cur - target) > 1e-8:
h_values = h_values * (target / cur)
assert np.all(h_values >= -1e-10) and np.all(h_values <= 1 + 1e-10), \
f"h out of [0,1]: [{h_values.min()}, {h_values.max()}]"
dx = 2.0 / n_points
correlation = np.correlate(h_values, 1.0 - h_values, mode="full") * dx
computed_c5 = float(np.max(correlation))
assert np.isclose(computed_c5, float(c5_bound), atol=1e-4), \
f"C5 mismatch: computed={computed_c5:.8f}, reported={float(c5_bound):.8f}"
return {"combined_score": -computed_c5, "c5": computed_c5, "elapsed": elapsed}
# ββ AC1 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def eval_ac1(path):
name = os.path.splitext(os.path.basename(path))[0]
mod = load_module(path, f"ac1_{name}")
t0 = time.time()
seq = mod.run(seed=42, budget_s=10.0)
elapsed = time.time() - t0
assert isinstance(seq, list) and len(seq) > 0
a = np.array([float(x) for x in seq])
a = np.clip(a, 0.0, 1000.0)
n = len(a)
s = float(np.sum(a))
assert s >= 0.01, f"sum too small: {s}"
# Use FFT for large sequences
if n > 500:
conv = fftconvolve(a, a)
else:
conv = np.convolve(a, a)
max_b = float(np.max(conv))
value = 2.0 * n * max_b / (s * s)
return {"combined_score": -value, "ac1_value": value, "n": n, "elapsed": elapsed}
# ββ Main ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
if __name__ == "__main__":
tasks = {
"circle_packing": {
"eval_fn": eval_circle_packing,
"files": ["thetaevolve.py", "autoevolve.py"],
},
"erdos_min_overlap": {
"eval_fn": eval_erdos,
"files": ["ttt_discover.py", "autoevolve.py"],
},
"alphaevolve_ac": {
"eval_fn": eval_ac1,
"files": ["ttt_discover.py", "alphaevolve_v2.py", "autoevolve.py"],
},
}
for task_name, cfg in tasks.items():
print(f"\n{'='*60}")
print(f" {task_name}")
print(f"{'='*60}")
for fname in cfg["files"]:
fpath = os.path.join(RESULTS, task_name, fname)
if not os.path.exists(fpath):
print(f" {fname}: FILE NOT FOUND")
continue
try:
result = cfg["eval_fn"](fpath)
parts = [f"{k}={v:.8f}" if isinstance(v, float) else f"{k}={v}"
for k, v in result.items()]
print(f" {fname}: {', '.join(parts)}")
except Exception as e:
print(f" {fname}: ERROR - {e}")
|