fix(E03): 엄밀해 해 없음 허용 2 % — 찾은 최소가 Bishop +2 % 안이면 값 살림(converged_far · 요구 351)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 04:08:53 +09:00
co-authored by Claude Opus 5.5
parent d5b828dc26
commit 3ead4efa6c
2 changed files with 28 additions and 3 deletions
@@ -40,6 +40,8 @@ SPENCER_SEED_POOL = 300
CROSS_TOP = 10
#: Spencer 원호 씨앗 — Bishop 임계 둘레 구름 크기
CLOUD_SIZE = 200
#: 엄밀해 「해 없음」 허용 — Bishop 임계 원에서 해 없어도 찾은 최소가 Bishop × (1 + 이 값) 안이면 값을 살림
FAR_TOL = 0.02
# ---- 원호 ---------------------------------------------------------------------
@@ -487,8 +489,9 @@ def analyze(
if g is not None:
best_circles[m] = g
results[m]["circular"] = _describe(prep, "circle", g, m, n_slices, min_depth)
# 엄밀해(Spencer · M-P)가 Bishop 임계 원에서 해 없음 · 찾은 최소가 Bishop 보다 높음 = 임계 둘레에서
# 풀리는 원이 없어 먼 원을 고른 것 → 그 방법 원호 = 「해 없음」(Bishop 임계 원 · F None · 까닭 · F–λ 곡선)
# 엄밀해(Spencer · M-P)가 Bishop 임계 원에서 해 없음 · 찾은 최소가 Bishop + FAR_TOL 넘게 높음 = 임계
# 둘레에서 풀리는 원이 없어 먼 원을 고른 것 → 그 방법 원호 = 「해 없음」(Bishop 임계 원 · F None · 까닭 ·
# F–λ 곡선) · 허용 안이면 찾은 값을 살림(status converged_far)
ref = best_circles.get("bishop") if "bishop" in results else None
fb = (results.get("bishop", {}).get("circular") or {}).get("F")
for m in [k for k in ("spencer", "morgenstern_price") if k in methods and ref and fb]:
@@ -496,7 +499,14 @@ def analyze(
if cur and cur["F"] is not None and cur["F"] <= fb:
continue
at = _describe(prep, "circle", ref, m, n_slices, min_depth)
if at["F"] is None:
if at["F"] is not None:
continue
if cur and cur["F"] is not None and cur["F"] <= fb * (1 + FAR_TOL):
cur["status"] = "converged_far"
cur["reason"] = (
f"Bishop 임계 원에서 해 없음 · 다른 원 최소가 Bishop 의 +{FAR_TOL:.0%} 안이라 살림"
)
else:
results[m]["circular"] = at
if noncircular:
mv = polyline_vertices