Files
mcm-26-b/docs/algo-3-bayes.md
T
2026-09-11 11:36:08 +08:00

7.6 KiB
Raw Blame History

算法说明:问题3 贝叶斯闭环(bayes 策略)

对应实现:src/mcm26b/particles.py(感知层)、src/mcm26b/planner/bayes_loop.py (决策层)、scripts/benchmark_q3_bayes.py(消融)、scripts/tune_q3_bayes.py (Optuna 调参)。基线对比:docs/algo-3.md 的七点批量(seven,A2)。

1. 建模定位

问题3是部分可观察的在线决策问题:频道数未知(10–16/20)、位置未知、有效 接收半径未知(1000–1500m)、测向误差 ±1°(服务器保留两位小数)。策略层 只能拿到 /measure 与 /clear 的响应,目标是最小化"发现—定位—清除"的 虚拟总时间。bayes 策略把它分解为三层滚动时域闭环:

  1. 感知层:每频道一个贝叶斯后验(网格幸存集),融合全部正/负观测;
  2. 决策层:站点扫频、定位测量、清除三类任务统一建表,开放路径 最近邻 + 2-opt 排序,每个动作后滚动重排(动态 TSP);
  3. 选点层:定位测量点按信息增益(期望 log 幸存占比,默认)或期望 后验半径 + λ·移动时间评分,直指 20m 清除证书阈值。

2. 网格幸存集滤波与真源保留定理

每频道维护 Ω 上间距 h 的网格(h=14.65m,约 4.7 万格),alive 为幸存格 集合。Voronoi 裕量 m = √2/2·h 是格心到格内任一点的最大距离;所有删除 判定都内缩 m,即仅当整格与可行集不相交时才删格:

观测 题面语义 删除判定
no_signal@s 距离 > r_eff ≥ 1000 删格心距 s ≤ 1000 − m 的格
direction@s 距离 ≤ 1500,|读数−真值| ≤ δ_eff 删角向超出 δ_eff + asin(m/(d−m)) 或距 s > 1500 + m 的格
near@s 距离 ≤ 5 删格心距 s > 5 + m 的格

定理(真源保留):真源 P 满足全部题面约束;P 所在格的格心 g 满足 |g−P| ≤ m,故"整格不相交"判定永不命中该格。因此任意观测序列后 P ∈ 幸存格的并集,且:

  • 缺席证明:幸存集为空 ⟹ 可行集为空 ⟹ 该频道无源(严格);
  • 清除证书:MEC(幸存).R + m ≤ 20 − 工程余量 ⟹ 真源距清除点 ≤ 20;
  • 跳测规则:幸存格到测点最小距离 > 1500 + m ⟹ 该测量必 no_signal 且无新排除,可跳过。

性质测试:tests/test_particles.py(随机源 × 随机测点 × 随机合法误差, 真源格永不被删;tests/test_bayes_loop_q3.py 端到端零异常)。

与 belief.CandidateRegion(保守凸外包)的分工:凸表示负责清除证书 (精确角域裁剪、收敛后触发),网格负责凸表示做不到的三件事——非凸负 观测挖洞(no_signal 排除盘)、缺席提前证毕、跳测判定。两者同读一套 响应流(_record_measure),任何一方证毕即收尾。

3. 信息增益选点

候选点集(二选一,按保证接收盘是否非空):

  • 保证接收盘 B(MEC_poly 圆心, 1000 − ρ_poly)(盘内必收 direction/near, 几何同 docs/algo-2.md 定理1):环形采样(search.candidate_rings×12 方向);
  • 宽候选集(ρ_poly > 1000 时):PF MEC 的 1.0/1.5/2.0 倍探索环。

评分(BayesConfig.score_mode):

  • entropy(默认,Optuna 选定):期望 log 幸存占比 —— 香农信息增益在 均匀先验下的形式。对 K 个代表假设(幸存格均匀抽样)各自模拟一次 测量的幸存分支,r_eff~U(1000,1500) 的不确定性解析积分 (p_no_signal = (d−1000)/500);总分 = E[log 幸存占比] + λ·移动秒数;
  • radius:期望后验半径 —— 同样的分支模拟,但以幸存子采样的质心最大 距离为半径代理,总分 = E[半径] + λ·移动秒数。更直接瞄准证书阈值, 在 entropy 模式下半径项与信息项量纲失配的场合可作为备选。

两种模式的 λ 量级都必须小:λ 过大时终局阶段"走 300m"的代价压过 "后验收缩"的收益,选点器原地重测、收敛停滞(消融实测 entropy+λ=0.01 显著优于早期 radius+λ=1.0 组合,单源定位步数从 ~7 降到 ~2)。

4. 统一任务循环(动态 TSP)

每个决策点构建任务表并排序执行首个任务,随后滚动重排:

  • 站点任务:七站(原点 + 1200m 环六点,覆盖半径解析上界 968.9m < 1000m)上仍待测的 UNKNOWN 频道;跳测规则与覆盖账本过滤;
  • 定位任务:DETECTED 且无证书的频道,位置由信息增益选点产生;
  • 清除任务:有证书(凸或网格)的频道,目标为证书圆心。

排序 = 开放路径最近邻打底 + 2-opt 改进(two_opt_passes 轮,成本含 移动 + 换频 + 动作耗时;终点自由不回起点)。这是 A2"站内最近邻服务 队列"的推广:消融显示距离缩短约 24% 是主要收益来源。

停止条件与基线一致:清满 16(数量上界)或全部频道 CLEARED/ABSENT, stop_reason=all_resolved 即停并 /exit——虚拟时间即评测成绩口径 [用户决策修订 2026-09-11]。复扫保险模式(mcm26b run --persistent, 原默认行为):找全后继续只复扫未清除频道直到清除数达 16、实机预算 耗尽或虚拟安全余量(search.virtual_reserve_s=10000s)不足,供需要 "防缺席证明假设偏差"保险的场景显式开启。

5. 消融结果(自建模拟器,persistent 关,对齐找全口径)

12 随机场景(6 种子 × 10/16 源)+ 2 边界场景,与 SevenBatch 配对; bayes 参数为 Optuna 回填后的库默认值:

指标 SevenBatch bayes
有效运行(全清+缺席正确+零异常+正常退出) 14/14 14/14
平均虚拟时间 5352.7s 3726.2s(−30.0%)
配对降幅(最差 / 最好) — +7% / −41%
平均移动距离 23413m 15050m(−36%)
平均检测次数 102.4 110.0
单局实机计算墙钟 1.3s 1.9s

复现:uv run python scripts/benchmark_q3_bayes.py --seeds 0,1,2,3,4,5 (逐场景数据与场景 JSON 见 output/q3/bayes-ablation/)。

6. Optuna 调参

scripts/tune_q3_bayes.py:TPE(dev 依赖 optuna,缺失时自动退化为 随机搜索),目标 = 场景子集平均虚拟时间 + 10⁶×失败惩罚。搜索空间: λ、代表点数、子采样规模、网格间距、站点环半径、2-opt 轮数、评分模式。 最优组合(entropy 评分、λ=0.0105、h=14.65m、代表点 7、2-opt 4 轮) 已按验收流程回填为 config.BayesConfig 默认值:全量基准 3726s/−30.0% 优于回填前的 4277s/−19.5%。两处人工修订:

  • station_ring_radius_m 保留 1200(Optuna 建议 1159.7 虽再快约 60s, 但七站排除盘对最外圈格心的覆盖差 3.3m,PF 无法独立证明缺席, 只能靠覆盖账本兜底——设计性质优先于 1.7% 的均值差异);
  • 评分模式在 entropy(信息增益)与 radius(期望后验半径)之间由调参 数据决定,两者实现均保留(BayesConfig.score_mode)。 调参记录见 output/q3/bayes-tuning/best_params.json。

7. 已知边界

  • 检测次数略多于 A2(109.6 vs 102.4):定位收敛多用 1-2 次测量换距离 大幅缩短,净收益为正;跳测规则在 UNKNOWN 阶段(先验全域)暂无收益 面,收益集中在定位与复扫阶段;
  • 网格清除证书(h=25m 时阈值 ≤1.8m)极少触发,作为凸证书的补位保险;
  • 调参与消融基于自建模拟器(逐点固定 ±1° 误差场),不代表官方误差 分布;真源保留定理只依赖题面界(±1°、r_eff∈[1000,1500]),不依赖 误差分布假设。