"""问题二近似最优参考:在保证接收盘内做稠密网格枚举。 目标函数与生产实现一致(最坏后验包围半径 + 移动时间同分决胜),但候选点 取自**均匀网格**而非环形采样族,因此可用来检验生产采样是否接近该目标下的 网格最优。注意这是"同一目标下的网格参考",不是连续问题的严格全局最优。 """ from __future__ import annotations import math from mcm26b.config import ProblemConfig from mcm26b.planner import (_worst_posterior_radius, safe_disk_radius) from project.common import Method, problem_config from project.q2.region import first_bearing_region METHOD = Method( key="reference", name="保证接收盘内网格枚举", kind="reference", note="同一目标下的稠密网格参考,非连续全局最优", ) GRID_SIDES = 9 WITNESS_SPACING_M = 150.0 def candidate(case: dict, config: ProblemConfig | None = None) -> dict: config = config or problem_config() region = first_bearing_region(case, config) station = (case["station"][0], case["station"][1]) center = region.mec()[0] safe = safe_disk_radius(region, config) if safe < 0: return _payload(center, region, config, station, "无保证接收盘:退回 MEC 圆心") field, search = config.field, config.search half_angle = field.bearing_error_half_deg + search.bearing_rounding_margin_deg witnesses = region.witnesses(WITNESS_SPACING_M) step = 2.0 * safe / (GRID_SIDES - 1) best_key, best_point, best_worst = None, center, None for i in range(GRID_SIDES): for j in range(GRID_SIDES): point = (center[0] - safe + i * step, center[1] - safe + j * step) if math.dist(point, center) > safe + 1e-9: continue worst = _worst_posterior_radius(region, point, witnesses, half_angle, field.near_radius_m, search.polygon_sides) move = math.dist(station, point) / config.cost.speed_mps key = (round(worst, 6), round(move, 6)) if best_key is None or key < best_key: best_key, best_point, best_worst = key, point, worst return _payload(best_point, region, config, station, f"安全盘网格 {GRID_SIDES}×{GRID_SIDES} 取最坏后验最小", worst_value=best_worst) def _payload(point, region, config, station, reason, worst_value=None) -> dict: return { "method": METHOD.key, "position": [round(point[0], 4), round(point[1], 4)], "worst_posterior_radius_m": worst_value, "move_cost_s": math.dist(station, point) / config.cost.speed_mps, "safe_disk_radius_m": safe_disk_radius(region, config), "initial_radius_m": region.mec()[1], "reason": reason, }