Files
mcm-26-b/project/q2/cases.py
2026-09-12 16:58:25 +08:00

38 lines
1.6 KiB
Python

"""问题二算例:随机首次示向度(全向源)。"""
from __future__ import annotations
import math
import random
from mcm26b.config import ProblemConfig
def random_case(seed: int, config: ProblemConfig | None = None) -> dict:
"""随机检测点 s 与示向度 θ:默认让真源与读数一致(误差 ±1° 内)。"""
config = config or ProblemConfig()
rng = random.Random(seed)
radius = config.field.omega_radius_m
# 检测点可在目标域内或域外;这里取域内,符合题目常规场景
angle_s = rng.uniform(0, 2 * math.pi)
distance_s = radius * math.sqrt(rng.random()) * 0.9
station = (distance_s * math.cos(angle_s), distance_s * math.sin(angle_s))
# 真源与检测点距离落在 [60, 1500) 且仍在 Ω 内
while True:
bearing_true = rng.uniform(0, 2 * math.pi)
source_distance = rng.uniform(60, config.field.r_eff_max_m - 1)
target = (station[0] + source_distance * math.cos(bearing_true),
station[1] + source_distance * math.sin(bearing_true))
if math.hypot(*target) <= radius:
break
error = math.radians(rng.uniform(-0.95, 0.95))
bearing_deg = math.degrees(bearing_true + error) % 360.0
return {"id": f"q2-{seed}", "station": [round(station[0], 2), round(station[1], 2)],
"bearing_deg": round(bearing_deg, 2), "half_angle_deg": 1.0,
"true_source": [round(target[0], 2), round(target[1], 2)]}
def random_cases(count: int, base_seed: int = 4200,
config: ProblemConfig | None = None) -> list[dict]:
return [random_case(base_seed + index, config) for index in range(count)]