This commit is contained in:
Horldsence
2026-09-12 16:58:25 +08:00
parent 1fa2264a17
commit 892451dca9
36 changed files with 8767 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
"""问题一最优实现:复用生产几何内核 ``mcm26b.geometry.localization.solve``。
算法(已由 ``tests/test_geometry.py`` / ``tests/test_geometry_certificates.py``
固化,本模块只做输入输出适配,不重写):
1. 每条带 ±δ 误差的示向度写成前向角域的三条半平面约束(含 0°/360° 跨界);
2. 枚举全部边界直线交点,保留满足全部约束者,单调链求凸包;
3. 检查是否存在非零衰退方向判定无界;否则枚举凸包顶点对取精确直径;
4. 用直径两端点中点圆检验覆盖,并给出圆外顶点、最大超出距离等反例见证;
5. Welzl 增量法求最小包围圆,给出 20 m 清除余量证书。
"""
from __future__ import annotations
from time import perf_counter
from mcm26b.geometry.localization import Measurement, solve
from project.common import Method
METHOD = Method(
key="optimal",
name="精确半平面交 + 顶点对直径 + MEC",
kind="optimal",
note="生产内核 mcm26b.geometry.localization.solve",
)
def solve_case(case: dict) -> dict:
"""输入 case["measurements"],输出归一化结果。"""
measurements = [Measurement(row["x"], row["y"], row["bearing_deg"],
row.get("half_angle_deg", 1.0))
for row in case["measurements"]]
start = perf_counter()
result = solve(measurements)
elapsed_ms = (perf_counter() - start) * 1000.0
return normalize(result, elapsed_ms)
def normalize(result: dict, elapsed_ms: float) -> dict:
status = result["status"]
diameter = result.get("diameter_m")
circle = result.get("diameter_circle") or {}
mec = result.get("minimum_enclosing_circle") or {}
covers = circle.get("covers") if status in ("point", "segment", "polygon") else None
return {
"method": METHOD.key,
"status": status,
"diameter_m": diameter,
"diameter_infinite": result.get("diameter_infinite"),
"covers": covers,
"mec_radius_m": mec.get("radius_m"),
"max_excess_m": circle.get("max_excess_m"),
"outside_vertex_count": len(circle.get("outside_vertex_indices", []))
if circle else None,
"vertex_count": len(result.get("vertices", [])),
"runtime_ms": round(elapsed_ms, 4),
"algorithm": METHOD.name,
}