捉迷藏:多边形行走问题的算法
1. 引言
想象一下,杰克和吉尔想要在一个简单多边形的边界上玩捉迷藏。已知这两个孩子沿着边界的任意路径,我们的目标是确定杰克能否沿着他的路径行走而不被吉尔看到。这个问题在很多场景中都有应用,比如兔子想在不被狼发现的情况下回到家,上班迟到的人想在不被警察看到的情况下赶路,或者资源需要秘密通过敌对区域。
1.1 多边形行走问题研究现状
多边形行走问题已经被广泛研究,不同的研究有着不同的目标:
| 研究人员 | 研究内容 | 时间复杂度 |
| — | — | — |
| Suzuki 等人和 Tan | 使用安装在墙壁循环轨道上的移动摄像头搜索简单多边形办公室空间中的入侵者 | - |
| Icking 和 Klein | 让两个警卫从一个入口点开始沿着简单多边形艺术画廊的边界巡逻,保持相互可见以检测入侵者 | O(n log n) |
| Heffernan | 改进 Icking 和 Klein 的算法 | O(n) |
| Zhang 和 Kameda | 检测边界上允许两个警卫成功检测入侵者的所有可能入口点 | O(n) |
| LaValle 等人 | 用一个警卫在 O(n²) 时间内搜索多边形区域 | O(n²) |
| Efrat 等人 | 用一组警卫沿着简单多边形的边界扫描以检测入侵者,连续的警卫对相互可见,目标是用最少的警卫检测入侵者 | O(n³) |
我们的问题与以往的研究不同,我们不试图让移动的实体之间保持相互可见,而是让两个实体在简单多边形边界上行走时保持相互不可见。
1.2 研究结果
设 P 是一个有 n 个顶点的简单多边形,πJack 和 πJill 是 P 边界上的两条任意路径。假设吉尔以恒定速度从 πJill 的起点走到终点,我们有一个 O(n log n) 时间和 O(n) 空间的算法来确定杰克是否可以控制自己的速度,从而从 πJack 的起点走到终点而不被吉尔看到。该算法还可以在输出敏感时间内报告杰克的任何现有遍历路径。
我们还考虑了更一般的问题,假设有 m 个孩子 c1, …, cm 都以恒定速度沿着他们各自在 P 边界上的路径行走,我们有算法确定杰克是否可以控制自己的速度,从而在不被任何孩子看到的情况下到达他路径的终点。
2. 预备知识
2.1 可见性与配置
给定一个简单多边形 P,如果线段 pq 完全包含在 P 内,则两点 p 和 q 相互可见;否则,它们相互不可见。我们定义一个配置 ⟨p, q⟩∈∂P × ∂P 为 P 边界上的一对点。当 p 和 q 相互不可见时,我们称这样的配置是安全的;否则,是不安全的。我们在边界 ∂P 上任意选取一个点作为原点,并从这个原点开始按顺时针方向测量 ∂P 上的所有距离,用 |∂P| 表示 ∂P 的总长度。
2.2 不可见性图
设 x1, x2, y1, y2 是 ∂P 上的点,杰克从 x1 走到 x2,吉尔从 y1 走到 y2。我们定义一个二维配置空间,其中 x 轴表示杰克在 ∂P 上的位置,y 轴表示吉尔在 ∂P 上的位置。如果杰克和吉尔在 ∂P 上位于同一点,那么他们一定相互可见,所以在这个配置空间中,直线 y = x 和 y = x - |∂P| 上的每个点都是不安全的。我们将搜索空间缩小到这两条直线之间的区域,并将所有安全配置用灰色阴影表示,这个增强的空间称为不可见性图。为了加快算法速度,我们将使用一个隐式的骨架不可见性图,它将所有安全配置表示为一组离散的线段。
2.3 单元与骨架
在不可见性图中,我们需要考虑多边形 P 的每个反射顶点。反射顶点是指 P 内部角度至少为 π 的顶点,例如图 1a 中的顶点 2、5、8 和 11 就是反射顶点。每个反射顶点都能阻挡 P 内的视线,因此与一组安全配置相关联,我们称这些安全配置为一个单元。
每个单元由一个水平线段和一个垂直线段界定,它们在 y = x 或 y = x - |∂P| 上相交。我们将单元的骨架定义为这些水平和垂直线段的并集,骨架不可见性图就是不可见性图中所有骨架的并集。
2.4 单元的边界
一个单元在不可见性图中总是由两个水平线段、两个垂直线段和一条单调曲线界定。为了描述这个边界,我们定义:
- Pred(r):顶点 r 在 ∂P 上的前一个顶点。
- Succ(r):顶点 r 在 ∂P 上的后一个顶点。
- B(r):从 Succ(r) 到 r 的边的向后延伸首次离开 P 的点。
- F(r):从 Pred(r) 到 r 的边的向前延伸首次离开 P 的点。
下面是计算反射顶点 r 对应的单元边界的步骤:
1.
步骤一
:杰克从 r 走到 Succ(r),吉尔静止在 B(r),这对应不可见性图中端点为 (r, B(r)) 和 (Succ(r), B(r)) 的水平线段。因为在这个过程中吉尔能看到杰克,但如果吉尔在 ∂P 上顺时针有一个微小移动,除了 r 点外就看不到杰克了。
2.
步骤二
:杰克从 Succ(r) 沿着多条线段走到 F(r),吉尔从 B(r) 走到 Pred(r)。所有通过 r 的杰克和吉尔之间的视线都将定义 r 对应的单元的边界,因为任何一个孩子的微小移动都可能打破他们之间的可见性。这部分单元边界从 (Succ(r), B(r)) 到 (F(r), Pred(r)) 是一条分段单调曲线,有 O(n) 个顶点。
3.
步骤三
:杰克静止在 F(r),吉尔从 Pred(r) 走到 r,这定义了单元的一个垂直边界线段。
4.
步骤四
:杰克从 F(r) 走到 r,吉尔静止在 r,这定义了单元的一个水平边界线段。
5.
步骤五
:杰克静止在 r,吉尔从 r 走到 B(r),这定义了单元的一个垂直边界线段。
最终,单元边界是一个由两个水平线段、两个垂直线段和一组单调曲线组成的封闭曲线,曲线内部的所有点都是杰克和吉尔相互不可见的安全点,因为反射顶点 r 阻挡了他们之间的视线。
单元的骨架由两条线段组成:从 (r, B(r)) 到 (r, r) 的垂直边界线段和从 (r, r) 到 (F(r), r) 的水平边界线段,我们有时将 (r, r) 称为角点。
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([开始]):::startend --> B(杰克从 r 走到 Succ(r),吉尔在 B(r)):::process
B --> C(杰克从 Succ(r) 到 F(r),吉尔从 B(r) 到 Pred(r)):::process
C --> D(杰克在 F(r),吉尔从 Pred(r) 到 r):::process
D --> E(杰克从 F(r) 到 r,吉尔在 r):::process
E --> F(杰克在 r,吉尔从 r 到 B(r)):::process
F --> G([结束]):::startend
3. 骨架不可见性图的性质
3.1 骨架交点性质
我们有以下两个重要的引理:
引理 1
:一对骨架最多有一个交点。
证明:设 S 和 S′ 是一对骨架,在不可见性图中分别有角点 (r, r) 和 (r′, r′)。
- 如果两个角点都与直线 y = x(或都与直线 y = x - |∂P|)相交,那么一个骨架的垂直线段一定完全位于另一个骨架的左侧,所以 S 和 S′ 最多有一个交点。
- 如果 S 的角点在直线 y = x 上,S′ 的角点在直线 y = x - |∂P| 上,假设两个骨架有两个交点 (r′, r) 和 (r, r′)。在骨架中,y 坐标从下到上的顺序是 B(r), r′, r, F(r′),这意味着这四个点在 ∂P 上按顺时针顺序排列,特别是 r′ 在 ∂P 的顺时针顺序中必须先于 r。而骨架中 x 坐标从左到右的顺序是 B(r′), r, r′, F(r),这意味着 r 在 ∂P 的顺时针顺序中必须先于 r′,这是矛盾的。所以一对骨架最多有一个交点。
引理 2
:两个单元相交当且仅当它们的骨架相交。
证明:
-
充分性
:如果两个骨架相交,因为单元总是其骨架的超集,所以这两个骨架对应的单元也一定相交。
-
必要性
:设 c1 和 c2 是不可见性图中的单元,假设它们的边界至少有一个交点 (a, b)。设 r1 和 r2 是 P 中定义这些单元的反射顶点,不妨设 r1 在 ∂P 的顺时针顺序中先于 r2。在不可见性图中的点 (a, b) 对应简单多边形 P 边界上的一对点,r1 和 r2 都会影响 a 和 b 之间的可见性,所以 a、r1、r2 和 b 四点在 P 中共线。
-
情况一
:如果 ∂P 上的两个点 B(r1) 和 F(r2) 在直线段 ab 的同一侧,那么在 ∂P 的顺时针顺序中,r1 和 r2 之间不会出现骨架端点。因此,对于任何 r1 < x < r2 或 r1 < y < r2,不可见性图中不会出现骨架端点。所以 r1 对应的骨架的水平线段必须与 c2 对应的骨架的垂直线段相交。
-
情况二
:如果 ∂P 上的两个点 B(r1) 和 F(r2) 在直线段 ab 的两侧,因为 r1 在 ∂P 的顺时针顺序中先于 r2,在不可见性图中,点 (r, B(r1)) 在点 (r2, r2) 下方,点 (B(r2), r2) 在点 (r1, r1) 左侧。所以 c1 的骨架的垂直线段必须与 c2 的骨架的水平线段相交。
综上所述,两个单元相交当且仅当它们的骨架相交。这个性质允许我们在不明确计算任何单元的情况下计算通过不可见性图的路径。
3.2 应用骨架不可见性图解决问题
基于上述骨架不可见性图的性质,我们可以利用它来解决杰克和吉尔的捉迷藏问题。以下是具体的步骤:
1.
构建骨架不可见性图
- 首先,找出简单多边形 (P) 的所有反射顶点。
- 对于每个反射顶点 (r),计算 (Pred(r))、(Succ(r))、(B(r)) 和 (F(r))。
- 根据这些信息,确定每个反射顶点对应的单元的骨架。
2.
确定起点和终点
- 已知杰克的起点 (x_1) 和终点 (x_2),吉尔的起点 (y_1) 和终点 (y_2),得到不可见性图中的起点 (s=(x_1,y_1)) 和终点 (t=(x_2,y_2))。
3.
检查路径可行性
- 利用引理 2,通过检查骨架之间的交点情况,判断是否存在一条从 (s) 到 (t) 的路径,使得杰克在行走过程中不被吉尔看到。
- 由于一对骨架最多有一个交点(引理 1),可以高效地进行交点检查。
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([开始]):::startend --> B(构建骨架不可见性图):::process
B --> C(确定起点 s 和终点 t):::process
C --> D(检查骨架交点,判断路径可行性):::process
D --> E{是否存在可行路径?}:::process
E -- 是 --> F([找到可行路径]):::startend
E -- 否 --> G([不存在可行路径]):::startend
3.3 多孩子情况的扩展
上述方法可以扩展到多个孩子的情况。假设有 (m) 个孩子 (c_1, \cdots, c_m) 都以恒定速度沿着他们各自在 (P) 边界上的路径行走。
1.
构建多个不可见性图
- 对于每个孩子 (c_i),分别构建杰克与 (c_i) 的不可见性图和对应的骨架不可见性图。
2.
综合判断
- 要使杰克不被任何孩子看到,需要在所有的不可见性图中都存在从起点到终点的可行路径。
- 可以通过依次检查每个不可见性图中的骨架交点情况,来综合判断杰克是否能成功到达终点。
| 情况 | 操作步骤 |
|---|---|
| 单个孩子 | 构建骨架不可见性图,确定起点和终点,检查路径可行性 |
| 多个孩子 | 为每个孩子构建不可见性图和骨架不可见性图,依次检查每个图的路径可行性,综合判断 |
4. 算法复杂度分析
4.1 时间复杂度
- 构建骨架不可见性图 :对于一个有 (n) 个顶点的简单多边形,找出反射顶点、计算相关点(如 (Pred(r))、(Succ(r))、(B(r)) 和 (F(r)))的时间复杂度为 (O(n))。
- 检查骨架交点 :由于一对骨架最多有一个交点,检查所有骨架交点的时间复杂度为 (O(n \log n))。
- 多孩子情况 :对于 (m) 个孩子,需要构建 (m) 个不可见性图,总的时间复杂度为 (O(mn \log n))。
4.2 空间复杂度
- 骨架不可见性图的空间复杂度为 (O(n)),因为它主要存储了每个反射顶点对应的骨架信息。
- 在多孩子情况中,空间复杂度为 (O(mn)),因为需要存储 (m) 个不可见性图的骨架信息。
5. 实际应用场景
这种多边形行走问题的算法在很多实际场景中都有应用:
1.
动物行为模拟
:例如,模拟兔子在不被狼发现的情况下回到家的路径规划。
- 可以将兔子看作杰克,狼看作吉尔或多个孩子。
- 利用算法计算兔子的安全路径。
2.
城市交通规划
:一个人上班迟到,想在不被警察看到的情况下赶路。
- 把城市道路抽象成简单多边形的边界。
- 警察的巡逻路径作为吉尔或多个孩子的路径。
- 算法可以帮助规划安全的出行路线。
3.
军事资源运输
:在敌对区域秘密运输资源。
- 敌对区域的边界看作简单多边形。
- 敌人的巡逻路径作为多个孩子的路径。
- 通过算法确定资源的安全运输路径。
综上所述,这种基于骨架不可见性图的算法为解决多边形行走问题提供了一种高效的方法。它不仅可以解决两个实体的捉迷藏问题,还能扩展到多个实体的情况,并且在多个实际场景中具有重要的应用价值。通过合理利用算法的性质和步骤,可以有效地规划路径,确保一个实体在行走过程中不被其他实体看到。
超级会员免费看
1496

被折叠的 条评论
为什么被折叠?



