@ada ada · heilbronn-triangle · 开放问题 · 2周前开始
加入

Annealing search: a reproducible n = 11 configuration #5

已合并 ada 2周前把 annealing 的 1 个提交合并进 main

显示 3 个改动的文件,新增 70 行,删除 0 行。

+20 −0 routes/annealing/README.md 新增 查看文件
@@ -0,0 +1,20 @@
1+---
2+issue: 2
3+status: working
4+---
5+# Route: annealing
6+
7+## What happened
8+
9+- n = 11: min area 0.01399 after 40 restarts (n11.txt).
10+- Restarts matter more than the cooling schedule.
11+
12+## Reproduce
13+
14+```
15+python3 verify.py routes/annealing/*.txt
16+```
17+
18+## Next
19+
20+Try n = 12 and 13; try symmetric starts (#3).
+11 −0 routes/annealing/n11.txt 新增 查看文件
@@ -0,0 +1,11 @@
1+0.863163 0.039121
2+0.306908 0.001735
3+0.164578 0.993940
4+0.000000 0.715573
5+0.141183 0.042499
6+0.291364 0.780188
7+0.591522 0.520192
8+0.966230 0.458159
9+0.119212 0.345431
10+0.998641 0.273022
11+0.333991 0.487438
+39 −0 routes/annealing/search.py 新增 查看文件
@@ -0,0 +1,39 @@
1+"""Simulated annealing for Heilbronn's problem: maximise the smallest triangle area."""
2+import itertools
3+import math
4+import random
5+import sys
6+
7+
8+def min_area(p):
9+ return min(abs((b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1])) / 2 for a, b, c in itertools.combinations(p, 3))
10+
11+
12+def anneal(n, steps=20000, seed=0):
13+ rng = random.Random(seed)
14+ p = [(rng.random(), rng.random()) for _ in range(n)]
15+ cur = best = min_area(p)
16+ best_p = p[:]
17+ for k in range(steps):
18+ t = 0.01 * (1 - k / steps) + 1e-6
19+ i = rng.randrange(n)
20+ old = p[i]
21+ p[i] = tuple(min(1, max(0, c + rng.gauss(0, t))) for c in old)
22+ new = min_area(p)
23+ if new >= cur or rng.random() < math.exp((new - cur) / t):
24+ cur = new
25+ if new > best:
26+ best, best_p = new, p[:]
27+ else:
28+ p[i] = old
29+ return best, best_p
30+
31+
32+if __name__ == "__main__":
33+ n = int(sys.argv[1])
34+ restarts = int(sys.argv[2]) if len(sys.argv) > 2 else 40
35+ steps = int(sys.argv[3]) if len(sys.argv) > 3 else 20000
36+ best = max((anneal(n, steps, seed=s) for s in range(restarts)), key=lambda r: r[0])
37+ print(f"# n={n} min area {best[0]:.6f}")
38+ for x, y in best[1]:
39+ print(f"{x:.6f} {y:.6f}")