This commit is contained in:
Horldsence
2026-09-13 08:29:30 +08:00
parent f71d7d9288
commit 71688b2ab2
10 changed files with 3064 additions and 702 deletions
+225 -144
View File
@@ -1,185 +1,266 @@
# 问题一:有界测向误差下定位区域的直径与圆覆盖
# 问题一算法说明:有界测向误差下的角域交会、直径与最小包围圆
## 摘要
> 本文按**当前仓库实现**重写,替代早期只描述理论方案的版本。
> 问题一生产入口为 `src/mcm26b/geometry/localization.py::solve`,CLI 为
> `python -m mcm26b.geometry`;问题二至四只复用其中的
> `smallest_enclosing_circle` 与同一套角域半平面语义,并不直接调用
> `solve`(复用与差异见 §7)。
针对同一干扰源在多个检测点处的带误差方位观测,建立前向角域交集模型,将定位区域表示为二维线性不等式组的可行域。首先推导角域的半平面表达,给出兼顾空集、点、线段和无界区域的几何构造算法;随后证明,有界定位区域的直径必由一对顶点取得,且判断是否存在直径等于区域直径的覆盖圆,只需检验任意一组最远顶点的中点。通过符合题设测向条件的等边三角形反例,说明直径圆一般不能覆盖定位区域。进一步以最小包围圆连接定位精度和后续清除条件,并给出算法复杂度、数值处理原则及既有演练观测的复算结果。全部结论以有界误差模型为前提,不引入误差独立、正态或均匀分布假设。
## 1. 问题与实现入口
**关键词:** 交会定位;有界误差;半平面交;凸多边形直径;最小包围圆。
同一频道的同一静止干扰源,在若干检测点 $s_i=(s_{ix},s_{iy})$ 处得到示向度
$\theta_i$。题设测向误差不超过 $\pm1^\circ$,同一地点重复测量误差不变;
示向度从正东逆时针计量。问题一要求定位区域的直径,并判断“以该直径为
直径的圆”能否覆盖定位区域。
## 1. 问题界定与思路来源
题目要求由若干检测点坐标及同一干扰源的示向度,求交会定位多边形的直径,并判断以该直径为直径的圆能否覆盖定位区域。题面规定测向误差在 $[-1^\circ,1^\circ]$ 内,同一地点重复测量的误差不变;示向度从正东沿逆时针方向计量。[题面第1页、附录2第(1)、(3)项](C:/Users/HelixCopex/code/MATH/issue/B题.pdf)
由此得到三步建模思路。第一,单次观测不能确定一条精确射线,却可以确定一个包含真实方向的角域,因此采用集合相交而非直线最小二乘。第二,角域可以写成半平面交,问题随之转化为凸几何问题。第三,“两点最远距离”和“覆盖全部位置所需半径”是不同的优化量,应分别计算直径和最小包围圆。
半平面、凸组合和凸集交运算属于标准凸分析工具,其背景见 Boyd 与 Vandenberghe 的《Convex Optimization》第2章;本文针对测向模型给出独立推导,不将一般理论本身视为新的研究贡献。[文献2](https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf)
本文严格区分两个集合:问题一的 $P$ 仅表示测向角域之交;第二问及在线搜索中的 $K$ 可进一步结合源位置圆域和接收距离先验。向 $P$ 加入圆盘后,边界可能出现圆弧,不能继续把它当成原问题中的纯多边形。
## 2. 符号及基本假设
| 符号 | 含义 |
| --- | --- |
| $s_i=(s_{ix},s_{iy})$ | 第 $i$ 个检测点,坐标单位为米 |
| $\theta_i$ | 第 $i$ 次有效示向度 |
| $\delta_i$ | 误差半角,题设取 $1^\circ$ |
| $g=(x,y)$ | 未知干扰源位置 |
| $W_i$ | 第 $i$ 次测向对应的闭前向角域 |
| $P$ | 所有角域的交集 |
| $V=\{v_1,\ldots,v_m\}$ | 非空有界 $P$ 的顶点集 |
| $D(P)$ | 区域内任意两点距离的上确界 |
| $B(c,r)$ | 中心为 $c$、半径为 $r$ 的闭圆盘 |
| $\rho(P)$ | 覆盖 $P$ 的最小圆盘半径 |
假设各次有效示向度对应同一频道的同一个静止源。仅把 `direction` 观测代入角域模型,不能给 `near` 或 `no_signal` 人为赋予角度。理论推导允许 $0\le\delta_i<90^\circ$,用于讨论退化情况,题目主模型始终采用 $\delta_i=1^\circ$。
程序可额外计入两位小数舍入对应的 $0.005^\circ$ 裕量,但必须显式声明。题设的 $1^\circ$ 误差界与实现中的浮点容差是两个概念,均不能在结果解释时省略。
## 3. 由角域推导半平面约束
定义方向向量 $u(\alpha)=(\cos\alpha,\sin\alpha)$,二维叉积为 $[a,b]=a_xb_y-a_yb_x$。三角函数计算前将角度换成弧度。
令 $u_i^-=u(\theta_i-\delta_i)$、$u_i^+=u(\theta_i+\delta_i)$。当 $0<\delta_i<90^\circ$ 时,真实位置位于两条边界射线之间,等价于 $[u_i^-,g-s_i]\ge0$ 和 $[u_i^+,g-s_i]\le0$。第一条要求 $g-s_i$ 在下边界的左侧,第二条要求其在上边界的右侧。
将第一条展开,得到 $\sin(\theta_i-\delta_i)x-\cos(\theta_i-\delta_i)y\le\sin(\theta_i-\delta_i)s_{ix}-\cos(\theta_i-\delta_i)s_{iy}$。
将第二条展开,得到 $-\sin(\theta_i+\delta_i)x+\cos(\theta_i+\delta_i)y\le-\sin(\theta_i+\delta_i)s_{ix}+\cos(\theta_i+\delta_i)s_{iy}$。
同时保留前向约束 $u(\theta_i)\cdot(g-s_i)\ge0$。该约束在正半角情形下冗余,但当 $\delta_i=0$ 时,前两条只限定一条直线,加入它才得到正确的射线。角域顶点本身也包含在闭集合内,这是保守几何处理,并不表示该点仍能获得示向度。
因此,$P=\bigcap_{i=1}^{n}W_i=\{g:Ag\le b\}$。采用向量不等式后,$359^\circ$ 与 $0^\circ$ 跨界无需分段比较角度。每个 $W_i$ 是闭凸集,故 $P$ 也是闭凸集;它可能为空、为单点、为线段、为有界凸多边形,也可能无界。
## 4. 定位区域的构造与分类
### 4.1 边界交点与可行性
把约束统一写成 $a_jx+b_jy\le c_j$。两条边界的行列式为 $\Delta_{jk}=a_jb_k-a_kb_j$。当 $\Delta_{jk}\ne0$ 时,交点坐标为 $x=(c_jb_k-c_kb_j)/\Delta_{jk}$、$y=(a_jc_k-a_kc_j)/\Delta_{jk}$。保留满足全部约束的交点,再去重并构造凸包。
**命题1:** 至少有一次观测时,非空的角域交集一定存在极点,因此可通过可行边界交点枚举判空。
**证明:** 取第一个角域的轴向量 $u_1$,其中任意 $g$ 满足 $u_1\cdot(g-s_1)\ge\cos\delta_1\,\lVert g-s_1\rVert$,且 $\cos\delta_1>0$。在非空 $P$ 上最小化线性函数 $u_1\cdot(g-s_1)$;以任一可行点的函数值截取下水平集,得到非空紧集,故最小值能够取得。最小化点集位于一条支撑直线上,且有界,所以为点或线段。取该点或线段端点即得到 $P$ 的极点。二维线性约束的极点至少有两条法向量线性无关的有效边界,否则沿所有有效边界的公共切向可作双向小扰动,与极点定义矛盾。因此极点包含在上述交点枚举中。证毕。
无观测时,$P=\mathbb R^2$,应直接判为无界,不能用“没有交点”判断为空集。
### 4.2 无界性判定
对非空 $P$ 定义衰退锥 $\mathcal R=\{d:Ad\le0\}$。若存在 $d\ne0$,则任意 $g_0\in P$ 与 $t\ge0$ 都满足 $g_0+td\in P$,所以 $P$ 无界。
反之,若 $P$ 无界,可取 $g_k\in P$ 使 $\lVert g_k-g_0\rVert\to\infty$。单位向量 $(g_k-g_0)/\lVert g_k-g_0\rVert$ 存在收敛子列,极限 $d$ 满足 $\lVert d\rVert=1$。将 $Ag_k\le b$ 减去 $Ag_0$,再除以距离并取极限,得到 $Ad\le0$。因此 $P$ 有界当且仅当 $\mathcal R=\{0\}$。
本模型的衰退锥被一个小于 $180^\circ$ 的闭角域约束,若包含非零向量,必含一条极射线,该射线平行于某条有效约束边界。故只需检查每个法向量 $(a_j,b_j)$ 的两个切向方向 $(b_j,-a_j)$、$(-b_j,a_j)$ 是否满足所有齐次不等式。
### 4.3 分类约定
可行交点为空时返回空集;存在非零衰退方向时返回无界。否则求可行交点的凸包,按顶点数和仿射维数区分单点、线段和二维多边形。空集的直径在本文约定为未定义;无界集合的直径为 $+\infty$。程序使用空值及单独的无穷标志表示二者,避免写入非标准 JSON 数值。
显示窗口只用于绘图裁剪。任意大矩形都不能取代衰退锥判定,更不能把截断图形的直径称为原无界区域的直径。
## 5. 直径的顶点定理
**定理1:** 若 $P=\operatorname{conv}(V)$ 非空且有界,则 $D(P)=\max_{i,j}\lVert v_i-v_j\rVert$。
**证明:** 任取 $x,y\in P$,可写成 $x=\sum_i\lambda_i v_i$、$y=\sum_j\mu_jv_j$,其中权重非负且分别求和为1。于是 $x-y=\sum_{i,j}\lambda_i\mu_j(v_i-v_j)$。由三角不等式,$\lVert x-y\rVert\le\sum_{i,j}\lambda_i\mu_j\lVert v_i-v_j\rVert\le\max_{i,j}\lVert v_i-v_j\rVert$。最远顶点对又属于 $P$,上界可以达到,结论成立。证毕。
因此,小规模问题中直接枚举所有顶点对即可,计算复杂度为 $O(m^2)$。单点的直径为0,线段的直径为端点距离。这里的直接枚举不是近似算法;其缺点仅在于大规模时计算量较高。
## 6. 直径圆覆盖的充要条件
**定理2:** 取任意一组最远顶点 $a,b$,令 $D=\lVert a-b\rVert$、$o=(a+b)/2$。存在直径为 $D$ 的覆盖圆,当且仅当所有顶点均满足 $\lVert v_i-o\rVert\le D/2$。
**证明:** 若半径为 $D/2$、中心为 $z$ 的圆同时包含 $a,b$,则 $D\le\lVert a-z\rVert+\lVert z-b\rVert\le D$。两个不等式必须同时取等号,所以 $z$ 在两点连线上,且到两点距离相等,只能是中点 $o$。当 $D=0$ 时结论直接成立。另一方面,圆盘是凸集,包含全部顶点等价于包含它们的凸包。因此只需在这个唯一可能的圆心处检查全部顶点。证毕。
该定理不仅回答“以某条直径线段为直径的圆是否覆盖”,也回答“能否移动一个同样大小的圆使其覆盖”。若检查失败,移动圆心或更换最远顶点对均不能解决。
定义最大超出量 $E=\max_i\lVert v_i-o\rVert-D/2$。在精确算术下,$E=0$ 表示覆盖成立,$E>0$ 表示失败;不会出现严格负值,因为最远点对就在圆周上。取达到最大值的顶点,即得到一份可以独立复核的覆盖失败证据。
## 7. 符合测向条件的反例
取误差半角均为 $1^\circ$,三个检测点及读数如下。
| 检测点 | 坐标(米) | 示向度 |
| 层次 | 文件 | 内容 |
| --- | --- | --- |
| $s_1$ | $(-1000,0)$ | $1^\circ$ |
| $s_2$ | $(540,-500\sqrt3)$ | $121^\circ$ |
| $s_3$ | $(520,520\sqrt3)$ | $241^\circ$ |
| 生产内核 | `src/mcm26b/geometry/localization.py` | `Measurement`、`halfplanes`、`convex_hull`、`diameter`、`smallest_enclosing_circle`、`solve` |
| CLI | `src/mcm26b/geometry/__main__.py` | 读 JSON、可加两位小数舍入裕量、输出结果 |
| 统一入口 | `src/mcm26b/cli.py` | `mcm26b q1` |
| 对比框架 | `project/q1/{optimal,baseline,reference,cases,compare}.py` | 生产实现 / 朴素基线 / 独立大框参考解 |
| 回归 | `tests/test_geometry.py`、`tests/test_geometry_certificates.py` | 解析形状、真值保留、随机对拍、证书边界 |
| 结果 | `examples/q1/*.json`、`project/results/q1.md` | 固定解析算例与 40 个随机交会算例的配对结果 |
每个角域的下边界方向分别为 $0^\circ,120^\circ,240^\circ$。对应的三个左半平面是 $y\ge0$、$\sqrt3x+y\le40\sqrt3$、$y\le\sqrt3x$,交集为顶点 $A=(0,0)$、$B=(40,0)$、$C=(20,20\sqrt3)$ 的等边三角形。
```bash
.venv/bin/python -m mcm26b.geometry examples/q1/triangle.json
.venv/bin/python -m mcm26b.geometry examples/q1/normal.json --rounding-margin-deg 0.005
```
还需验证每个角域的另一条边不会切去这个三角形。以 $s_1$ 为例,到三个顶点的方向分别为 $0^\circ,0^\circ,\arctan(20\sqrt3/1020)$,最后一项约为 $1.945^\circ<2^\circ$,均在 $[0^\circ,2^\circ]$ 内。其余两站由绕三角形中心旋转 $120^\circ$ 的对称性成立。因此三个完整前向角域之交恰为上述三角形。
`--rounding-margin-deg` 默认 $0$;库内在线求解默认把服务器两位小数舍入的
$\le0.005^\circ$ 偏差计入有效半角,这是**实现口径**,不是题面新增误差。
问题一 CLI 只有显式传参才附加该裕量,以便同时报告纯 $1^\circ$ 与
$1.005^\circ$ 两套敏感性结果。
将真实源取为三角形中心 $g_*=(20,20\sqrt3/3)$。以第一站为例,真实方向约为 $0.649^\circ$,与 $1^\circ$ 的读数偏差小于 $1^\circ$;检测距离约为1020米,小于1500米。另两站同理。该反例符合题设方位误差和可能的有效接收半径。
## 2. 模型:把角域写成半平面交
此时 $D=40$ 米,而以 $AB$ 为直径的圆中心为 $(20,0)$,到 $C$ 的距离为 $20\sqrt3>20$ 米,不能覆盖。三角形外接圆即最小包围圆,其中心为 $(20,20\sqrt3/3)$,半径为 $40/\sqrt3\approx23.094011$ 米。这也证明了“直径不超过40米”不足以保证一次清除。
令方向向量 $u(\alpha)=(\cos\alpha,\sin\alpha)$,二维叉积
$[a,b]=a_xb_y-a_yb_x$。设误差半角为 $\delta$(题设主模型 $\delta=1^\circ$),
真实源 $g$ 属于闭前向角域
## 8. 最小包围圆及其清除含义
$$
W(s,\theta,\delta)=\{g:\ [u(\theta-\delta),g-s]\ge0,\
[u(\theta+\delta),g-s]\le0,\ u(\theta)\cdot(g-s)\ge0\}.
$$
### 8.1 存在性、唯一性与支撑点
对应实现中的三条半平面 $a x+b y\le c$ 为
定义 $f(z)=\max_{v\in V}\lVert v-z\rVert$,则 $\rho(P)=\min_z f(z)$。由于 $V$ 有限,$f$ 连续且随 $\lVert z\rVert\to\infty$ 而趋于无穷,最小值存在。
| 约束 | $a$ | $b$ | $c$ |
| --- | --- | --- | --- |
| 下边界左侧 | $\sin(\theta-\delta)$ | $-\cos(\theta-\delta)$ | $a s_x+b s_y$ |
| 上边界右侧 | $-\sin(\theta+\delta)$ | $\cos(\theta+\delta)$ | $a s_x+b s_y$ |
| 前向 | $-\cos\theta$ | $-\sin\theta$ | $a s_x+b s_y$ |
若两个不同中心 $c_1,c_2$ 都以半径 $r$ 覆盖 $V$,中点 $c$ 对每个顶点满足 $\lVert v-c\rVert^2=(\lVert v-c_1\rVert^2+\lVert v-c_2\rVert^2)/2-\lVert c_1-c_2\rVert^2/4<r^2$,与最小性矛盾。因此最小包围圆唯一。
第三条前向约束在 $0<\delta<90^\circ$ 时冗余,但在 $\delta=0$ 时必须保留,
否则两条边界只确定一条直线而非一条射线。角域顶点按闭集处理;这是保守的
几何含义,不表示边界点仍能返回方向读数。
在最优中心 $c$ 处,令 $T$ 为圆周上的顶点集。若 $c$ 不在 $T$ 的凸包中,可沿严格分离方向小幅移动中心,使所有圆周点的距离同时减小;其余有限个点有严格余量,仍被稍小圆覆盖,产生矛盾。故 $c\in\operatorname{conv}(T)$。二维凸组合经仿射相关权重消元,最多保留3个点。因此最小包围圆由至多3个圆周顶点支撑。
$P=\bigcap_i W_i$ 是有限条闭半平面之交,因而是闭凸集;可能为空、单点、
线段、有界多边形或无界多边形。实现不做正态、均匀或独立误差假设,
只使用题面给定的有界误差。
更具体地,若支撑点 $p_j$ 的权重满足 $c=\sum_j\lambda_jp_j$,则对任意 $z$ 有 $\sum_j\lambda_j\lVert p_j-z\rVert^2=r^2+\lVert c-z\rVert^2\ge r^2$。这给出了任何覆盖圆半径不能小于 $r$ 的直接证据。
## 3. 精确算法流程
### 8.2 求解方法与来源
`solve(measurements, eps)` 的步骤如下。
由支撑点性质,可以枚举单点零半径圆、两点直径圆和三点外接圆,再检查全体顶点。这是便于核查的基准方法,最坏复杂度为 $O(m^4)$。
### 3.1 坐标归一化与边界交点枚举
当前实现采用 Welzl 的随机增量算法:打乱点序,若当前圆不包含新点,则在该点成为边界点的约束下递归求解较小问题;边界点至多3个。程序用显式栈避免递归深度限制,并固定随机种子以复现结果。理论期望线性依赖随机排列分析,不等于任意固定排列的最坏时间保证。3个强制边界点应使用外接圆,不能替换成其无约束最小圆。算法来源为 Welzl 的原论文,CGAL 文档提供了定义与实现背景。[文献3](https://people.inf.ethz.ch/emo/PublFiles/SmallEnclDisk_LNCS555_91.pdf)、[文献4](https://doc.cgal.org/latest/Bounding_volumes/classCGAL_1_1Min__circle__2.html)
先对所有检测点做平移和统一缩放,使数值量级接近单位坐标;结果再换回原坐标。
### 8.3 与一次清除的关系
1. 生成 $k=3n$ 条半平面。
2. 枚举全部边界直线对($\binom{k}{2}$ 对),用行列式
$\Delta=ae-bd$ 求交点;仅在 $\Delta$ 恰为 $0$ 时跳过,近平行对也保留,
因为其交点可能是细长区域的合法远端顶点。
3. 保留满足全部约束的交点;可行性判定使用随坐标量级缩放的位置容差
`eps * max(1, |x|, |y|)`,避免大坐标下绝对残差被误判为不可行。
所有能够保证一次清除的位置构成 $C_{20}(P)=\bigcap_{g\in P}B(g,20)=\bigcap_{v\in V}B(v,20)$。第二个等号来自圆盘凸性。该集合非空当且仅当 $\rho(P)\le20$。
### 3.2 空集、有界与无界
因此,最小包围圆中心是保证清除的充分选择,但不一定是移动距离最短的选择。若后续需要优化路径,可以在 $C_{20}(P)$ 内寻找距离机器狗最近的位置。相比之下,$D(P)\le40$ 只是必要条件。
- 无观测:$P=\mathbb R^2$,返回 `unbounded`。
- 没有任何可行边界交点:返回 `empty`。
- 否则检查衰退锥 $\mathcal R=\{d:Ad\le0\}$ 是否存在非零方向。二维情况下
该锥若非零必含一条与某条有效边界平行的极射线;实现只需检查每条约束的
两个切向 $(b,-a)$、$(-b,a)$ 是否满足全部齐次不等式
$a d_x+b d_y\le 2\times10^{-14}$。阈值取得比位置容差紧得多,避免把
极细长有界区域误判成无界。
- 存在非零衰退方向时返回 `unbounded`,直径为 `null` 且显式置
`diameter_infinite=true`,不伪造有限数值。
## 9. 算法流程与计算量
### 3.3 凸包与状态分类
**算法1:角域交、直径及覆盖证据。**
将可行交点去重后,用 Andrew 单调链求凸包(逆时针、无重复首尾点)。
按顶点数与维数返回:
1. 校验观测并进行坐标平移、尺度归一化,保留原误差半角。
2. 生成每次观测的三条半平面约束。
3. 枚举非平行边界交点,保留满足全部约束的点;无观测和空集分别处理。
4. 检验非零衰退方向;存在时报告无界并停止有限圆计算。
5. 对可行点去重并求凸包,识别点、线段或多边形。
6. 枚举顶点对求直径及任意一组最远点。
7. 检查其中点到全部顶点的距离,输出最大超出量与失败顶点。
8. 求最小包围圆,换回原坐标,重新检查顶点包含性,输出清除半径余量。
| `status` | 含义 | 直径 | 最小包围圆 |
| --- | --- | --- | --- |
| `empty` | 观测不相容 | 未定义(`null`) | 不计算 |
| `unbounded` | 存在非零衰退方向 | $+\infty$(`null` + 标志) | 不计算 |
| `point` | 单点 | 0 | 半径 0 |
| `segment` | 线段 | 两端点距离 | 半径 = 直径 / 2 |
| `polygon` | 二维有界凸多边形 | 见 §3.4 | 见 §3.6 |
令半平面数 $k=3n$,顶点数为 $m$。边界交点枚举及全约束检查为 $O(k^3)$,衰退方向检查为 $O(k^2)$,交点排序上界为 $O(k^2\log k)$,直径计算为 $O(m^2)$,覆盖证据检查为 $O(m)$。随机增量最小圆在随机排列下期望为 $O(m)$;整个算法仍由半平面交点枚举主导,不能因此称为总体线性算法。
### 3.4 直径:只需枚举顶点对(已证明)
## 10. 数值实现与已有观测复核
**定理 1.** 若 $P=\operatorname{conv}(V)$ 非空有界,则
$D(P)=\max_{v_i,v_j\in V}\lVert v_i-v_j\rVert$。
数学结论使用精确不等式。浮点实现先平移、归一化,再用位置容差、平行判定阈值和衰退方向容差分别处理不同问题。接近平行或退化输入应进行精度与容差敏感性检查;任意追加一个固定小数裕量都不能替代严格的误差传播上界。
证明:任一 $x,y\in P$ 写成凸组合后,
$x-y=\sum_{i,j}\lambda_i\mu_j(v_i-v_j)$,由三角不等式有
$\lVert x-y\rVert\le\max_{i,j}\lVert v_i-v_j\rVert$,而最远顶点对本身
属于 $P$,故上界可达。实现直接枚举顶点对,复杂度 $O(m^2)$;单点返回 0,
线段返回端点距离。
当前程序输出 `diameter_circle` 中的圆心、半径、最大超出量和反例顶点,以及 `minimum_enclosing_circle`。清除判断采用 $\rho+\varepsilon_m\le20$,其中 $\varepsilon_m$ 是工程数值裕量。它是观测及几何计算可靠这一前提下的决策条件,不是一次真实清除成功记录。
### 3.5 直径圆覆盖:唯一候选圆心是直径中点(已证明)
既有官方演练案例 `U5ZW-P9KN-TCAG-R7ST` 的三次不同位置观测如下。
**定理 2.** 取任意一组最远顶点 $a,b$,$D=\lVert a-b\rVert$,
$o=(a+b)/2$。存在直径为 $D$ 的覆盖圆,当且仅当所有顶点 $v_i$ 满足
$\lVert v_i-o\rVert\le D/2$。
| 检测点 | $x$ / 米 | $y$ / 米 | 示向度 / 度 |
| --- | ---: | ---: | ---: |
| 1 | 0 | 0 | 131.52 |
| 2 | -613.7618853216 | 391.5307754525 | 34.92 |
| 3 | -314.2721344680 | 656.6833525352 | 227.19 |
证明:若半径 $D/2$ 的圆心 $z$ 同时包含 $a,b$,则
$D\le\lVert a-z\rVert+\lVert z-b\rVert\le D$,两个不等式都必须取等号,
故 $z$ 只能在两点中点。圆盘是凸集,检查全部顶点即检查整个凸包。
| 误差半角 | 直径 / 米 | 最小包围半径 / 米 | 直径圆最大超出 / 米 |
实现输出 `diameter_circle`:圆心、半径、全部顶点到圆心的最大距离、
`covers` 布尔值、最大超出量 `max_excess_m`、圆外顶点索引
`outside_vertex_indices` 和反例顶点 `witness_vertex`。`witness_vertex`
是一份可独立复核的覆盖失败证据;`max_excess_m` 不能为负,因为最远顶点
本身在圆周上(精确算术下)。
### 3.6 最小包围圆与 20 m 清除证书
对凸包求最小包围圆 $\rho(P)$。实现采用 Welzl 随机增量算法的显式栈版本:
固定随机种子使结果可复现;三个强制边界点使用外接圆;输出前再对全部
顶点复核一次。内部有 $O(m^4)$ 的 1/2/3 点支撑圆枚举参考实现
(`_enclosing_circle_reference`)用于单测对拍。
在最小包围圆中心 $m$、半径 $\rho$ 处,若
$\rho+\varepsilon_m\le20$,则可直接以 $m$ 为清除点:任意真源
$g\in P\subseteq B(m,\rho)$,到 $m$ 的距离不超过 $\rho$。实现输出
`minimum_enclosing_circle`、`guaranteed_clearable_at_mec_center` 以及
`clearance_certificate`(含数值余量和剩余裕量)。
注意:直径 $D\le40$ 只是“可能一次清除”的必要条件,**不是充分条件**;
三角形反例中 $D=40$ 而 $\rho=23.094>20$。
## 4. 伪代码
```text
solve(measurements):
if measurements 为空: return unbounded
平移/缩放,生成每条读数的三条半平面
V = []
for 每一对边界直线:
求交点 p
if p 满足全部半平面: V.append(p)
if V 为空: return empty
if 存在非零衰退切向 d: return unbounded
H = convex_hull(V)
D, (a,b) = argmax_{v_i,v_j∈H} |v_i-v_j|
o = (a+b)/2
covers = max_{v∈H} |v-o| <= D/2
输出 diameter、diameter_circle、witness
(m,rho) = Welzl_MEC(H)
输出 minimum_enclosing_circle 与 rho+eps<=20 清除证书
```
## 5. 复杂度与数值实现
| 步骤 | 复杂度 |
| --- | --- |
| 生成半平面 | $O(k)$,$k=3n$ |
| 边界交点枚举与可行性判定 | $O(k^3)$ |
| 凸包 | $O(k^2\log k)$ 最坏 |
| 直径 | $O(m^2)$ |
| 直径圆检查 | $O(m)$ |
| Welzl 最小圆 | 随机排列下期望 $O(m)$;固定排列不声称最坏线性 |
主要数值约定:
- 坐标归一化后计算,输出换回原坐标并重新复核包含性;
- 仅对**精确平行**直线对跳过求交;近平行对保留;
- 位置可行性容差随坐标幅值缩放;衰退锥判定使用独立紧阈值;
- `solve` 主动限制最多 100 个检测点,超过时要求改用半平面交算法;
- 所有输出用 `null`/显式标志表示空集和无界,不写非法 JSON 浮点数。
## 6. 已验证算例与结果
固定解析算例(`examples/q1`,当前代码实测):
| 算例 | 状态 | 直径 (m) | MEC 半径 (m) | 直径圆覆盖 | 最大超出 (m) | MEC 可直接清除 |
| --- | --- | ---: | ---: | --- | ---: | --- |
| `normal` 三点交会 | polygon | 26.986 | 13.943 | 否(2 个圆外顶点) | 3.964 | 是 |
| `triangle` 等边三角形反例 | polygon | 40.000 | 23.094 | 否(1 个圆外顶点) | 14.641 | 否 |
| `segment` 零误差退化线段 | segment | 100.000 | 50.000 | 是 | 0.000 | 否 |
| `poor` 近共线检测点 | unbounded | — | — | — | — | — |
| `empty` 不相容观测 | empty | — | — | — | — | — |
`triangle` 的三个顶点是 $(0,0)$、$(40,0)$、$(20,20\sqrt3)$:以直径
$AB$ 为直径的圆圆心 $(20,0)$、半径 20,到 $C$ 的距离为 $20\sqrt3>20$,
故不能覆盖;最小包围圆半径 $40/\sqrt3\approx23.094$,也不能一次清除。
其中 $A=(0,0)$ 坐标是浮点下的 $-6.4\times10^{-13}$,上表按解析值取整。
既有官方演练观测(案例 `U5ZW-P9KN-TCAG-R7ST`,不公开源坐标、未执行清除)
的复算结果:
| 误差半角 | 直径 (m) | MEC 半径 (m) | 直径圆最大超出 (m) |
| --- | ---: | ---: | ---: |
| $1^\circ$ | 23.996723 | 12.068583 | 0.604002 |
| $1.005^\circ$ | 24.119088 | 12.130377 | 0.608486 |
两种口径下直径圆均不覆盖区域,最小包围半径均小于20米。该演练未公开源坐标,且没有执行清除,故只用于观测交会和计算一致性复核,不能据此声称实测定位误差或全清成功率。数据见[原始三点观测](C:/Users/HelixCopex/code/MATH/output/q1/practice/U5ZW-P9KN-TCAG-R7ST_observations.json),敏感性数值见[已有复算报告](C:/Users/HelixCopex/code/MATH/output/q1/optimization_report.json)。
两种口径下直径圆都不覆盖定位区域,MEC 半径都小于 20 m,但该演练没有
真实清除动作,不能据此声称实测定位误差或全清成功率。
## 11. 结论与实现对应
`project/q1` 的 40 个随机交会算例(冻结算例与独立参考解对拍):
问题一的准确答案为:将测向角域表示为半平面交,先判断非空性及有界性,再由最远顶点对得到直径;以该直径为直径的圆一般不能覆盖定位区域,覆盖的充要条件是任意一组最远顶点的中点到全部顶点的距离均不超过半径。最小包围圆提供独立且适合后续清除的精度指标。
| 方法 | 状态准确率 | 直径平均绝对误差 | 直径圆覆盖准确率 | 平均耗时 |
| --- | ---: | ---: | ---: | ---: |
| 生产 `solve` | 100% | 0.000 m | 100% | 0.086 ms |
| 朴素基线(网格 + 包围盒对角线) | 100% | 4.583 m | 52.5% | 15.932 ms |
对应实现为 [localization.py](C:/Users/HelixCopex/code/MATH/geometry/localization.py)。在项目根目录可运行 `python -m geometry examples/q1/triangle.json`;追加 `--rounding-margin-deg 0.005` 可复算额外舍入裕量。本文整理理论与已有计算结果,不改变原始观测或既有程序。
## 7. 与问题二/三/四当前实现的复用关系和差异(核对结果)
问题一给出的几何内核是后续所有几何决策的基础,但**复用方式是“语义 + 最小圆函数”,
不是直接调用 `solve`**。代码层面的核对结果如下。
| 后续问题 | 实际复用了什么 | 实际没有复用 / 做了什么替换 |
| --- | --- | --- |
| 问题二(`planner.select_second_point`) | 同一套角域半平面语义;`smallest_enclosing_circle` 求候选集 MEC;用 MEC 半径构造保证接收盘 | 不调用 `solve`;候选集不是纯角域交,而是 $K_1=\Omega\cap W\cap B(s,1500)$;用 192 边形外包圆盘 + Sutherland–Hodgman 裁剪,而不是枚举直线交点;不计算直径,也不使用“直径中点圆”判据 |
| 问题三(`belief.CandidateRegion`、`planner.bayes_loop`) | 复用 `smallest_enclosing_circle`;角域边界公式与问题一相同;MEC 作为清除证书 | 在线信念是有界凸外包多边形,圆盘边界是外切多边形而非精确曲线;不再判无界;no_signal 的负观测由网格粒子滤波处理(问题一模型里没有负观测);不用直径,而用“MEC 半径 + 外包余量 + 工程余量 $\le20$” |
| 问题四(`planner.DirectionalExtension`、`belief.joint`) | 继续复用问题一的 MEC 与角域语义;(位置 × 朝向)联合信念也建立在同一网格上 | 定向源的 no_signal 不能排除位置,不能沿用问题一/三的纯角度或全向距离解释;覆盖语义改为 `forward_half_disk`(见 `algo-4.md`) |
代码证据:
- `src/mcm26b/belief/__init__.py` 只从 `geometry.localization` 导入
`smallest_enclosing_circle`;
- `src/mcm26b/particles.py` 同样只导入 `smallest_enclosing_circle`;
- `生产/运行代码中 `geometry.localization.solve` 的调用者只有
`geometry/__main__.py` 和 `project/q1/optimal.py`,即问题一 CLI 与其
对比框架;测试文件会直接调用它做解析与随机对拍,不在此列;
- 在线 `clip_wedge` 的半平面系数与问题一 `halfplanes` 一致,但作用在
凸多边形裁剪流程上;`solve` 的“纯角域 + 精确顶点枚举 + 无界判定”
是针对问题一的一站式分析工具,不适合直接嵌入带圆盘、负观测和状态更新
的在线闭环。
**差异一句话总结:** 问题一回答“固定角域观测下源可能在哪里、直径圆能否覆盖”,
是纯几何精确解;问题二至四把其中的角域半平面和最小圆升级为“带距离先验的
保守信念 + 主动动作 + 证据证明”的闭环,问题三再加非凸负观测,问题四再加
朝向维度。
## 8. 结论与适用边界
问题一的当前实现是:三条半平面 → 可行顶点枚举/凸包 → 衰退锥判有界 →
顶点对精确直径 → 任意直径中点唯一候选的覆盖检验 → Welzl 最小包围圆与
20 m 证书。其结论只依赖题面有界误差,不引入误差分布假设。空集、无界、
点、线段和多边形状态都有明确输出。
未解决问题一的数值敏感性时,不应把在线闭环里的外包多边形半径直接当成
问题一的精确直径;两者口径不同。反过来,在线闭环也不能把 `solve` 直接套在
$K_1$ 上,因为 $K_1$ 含圆盘和距离上界,边界可能含圆弧。
## 参考文献
1. 全国大学生数学建模竞赛组委会. 2026年高教社杯全国大学生数学建模竞赛B题:无线电干扰源的快速自动定位与清除[Z]. 2026. [本地题面](C:/Users/HelixCopex/code/MATH/issue/B题.pdf),第1页、附录2。
2. BOYD S, VANDENBERGHE L. Convex Optimization[M]. Cambridge: Cambridge University Press, 2004. [作者公开版本](https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf),第2章。用于凸几何背景,本文的题目化证明在正文给出。
3. WELZL E. Smallest enclosing disks (balls and ellipsoids)[C]//MAURER H. New Results and New Trends in Computer Science. Lecture Notes in Computer Science, vol. 555. Berlin: Springer, 1991: 359–370. [作者公开论文](https://people.inf.ethz.ch/emo/PublFiles/SmallEnclDisk_LNCS555_91.pdf)。用于随机增量最小包围圆算法来源。
4. CGAL Project. CGAL::Min_circle_2: Bounding Volumes[EB/OL]. [在线文档](https://doc.cgal.org/latest/Bounding_volumes/classCGAL_1_1Min__circle__2.html),访问日期:2026-09-10。用于最小圆及支撑点定义的交叉核对。
1. 全国大学生数学建模竞赛组委会. 2026 年高教社杯全国大学生数学建模竞赛 B 题:无线电干扰源的快速自动定位与清除[Z]. 2026. 本地题面 `issue/B题.pdf`。
2. BOYD S, VANDENBERGHE L. Convex Optimization[M]. Cambridge University Press, 2004. 凸集、半平面与凸组合背景。
3. WELZL E. Smallest enclosing disks (balls and ellipsoids)[C]//New Results and New Trends in Computer Science, LNCS 555, 1991: 359–370. 随机增量最小包围圆。
4. 本项目. `docs/algo-2.md`(问题二当前实现). 问题二对本文半平面语义与最小圆的复用说明。
5. 本项目. `docs/algo-3.md`、`docs/algo-4.md`. 在线闭环中的保守信念、负观测与联合信念差异。