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
+67
View File
@@ -0,0 +1,67 @@
"""问题一算例:官方示例目录 ``examples/q1`` + 随机交会算例。"""
from __future__ import annotations
import json
import math
import random
from project.common import ROOT
EXAMPLE_DIR = ROOT / "examples" / "q1"
EXAMPLE_IDS = ("normal", "triangle", "poor", "segment", "empty")
def load_examples() -> list[dict]:
"""读取固定算例;缺文件时跳过,保证离线可跑。"""
cases = []
for key in EXAMPLE_IDS:
path = EXAMPLE_DIR / f"{key}.json"
if not path.exists():
continue
raw = json.loads(path.read_text(encoding="utf-8-sig"))
cases.append({
"id": raw.get("id", key),
"name": raw.get("name", key),
"source": "examples/q1",
"measurements": [
{"x": float(row["x"]), "y": float(row["y"]),
"bearing_deg": float(row["bearing_deg"]),
"half_angle_deg": float(row.get("half_angle_deg", 1.0))}
for row in raw["measurements"]
],
})
return cases
def random_case(seed: int) -> dict:
"""随机三点/四点交会:目标在 Ω 内,测站分布在不同象限。
仅生成"区域有界且非退化"的良态算例,避免参考网格因细长区域失效;
生成后由 ``compare`` 再用最优实现复核状态。
"""
rng = random.Random(seed)
target = (rng.uniform(-900, 900), rng.uniform(-900, 900))
count = rng.choice((3, 3, 4, 5))
stations = []
base_angle = rng.uniform(0, 360)
for index in range(count):
angle = base_angle + 360 * index / count + rng.uniform(-25, 25)
radius = rng.uniform(500, 1100)
stations.append((target[0] + radius * math.cos(math.radians(angle)),
target[1] + radius * math.sin(math.radians(angle))))
measurements = []
for (sx, sy) in stations:
true_bearing = math.degrees(math.atan2(target[1] - sy, target[0] - sx)) % 360.0
# 观测误差固定在同一地点、落在 ±1° 内;读数保留两位小数
error = rng.uniform(-0.9, 0.9)
measurements.append({"x": round(sx, 2), "y": round(sy, 2),
"bearing_deg": round((true_bearing + error) % 360.0, 2),
"half_angle_deg": 1.0})
return {"id": f"rand-{seed}", "name": "随机交会", "source": "synthetic",
"target": [round(target[0], 2), round(target[1], 2)],
"measurements": measurements}
def random_cases(count: int, base_seed: int = 7000) -> list[dict]:
return [random_case(base_seed + index) for index in range(count)]