Skip to content

算法Algorithm

半平面交的双端队列算法

Half-plane intersection by deque

在边界两两不平行、交集有界且有非空内部的条件下,按方向排序并从双端删除失效候选边界,构造半平面交。

形式陈述 ​

一组直线不等式描述了一个二维可行域。怎样直接得到它的边界,而不是从一个随意画大的矩形开始裁剪?每个输入用有向直线 ℓ=(a,b) 表示,保留它的左侧闭半平面

Hℓ={p:orient(a,b,p)≥0}.

本页先固定如下输入条件:边界直线两两不平行,最终交集已知有界且有非空内部,所有方向/求交采用精确算术。输入可以含冗余约束。这个版本输出交集的逆时针顶点序列,时间 O(nlog⁡n)、空间 O(n);空集、低维交和一般平行输入不包含在这条算法保证中。

先按方向 b−a 在 [0,2π) 中排序。比较时用上、下半平面编号与向量叉积,不必计算近乎相等的反三角函数。维护一个双端队列 Q,元素是候选边界直线。记相邻直线交点为 X(ℓi,ℓj)。加入新直线 h 时依次执行:

  1. 若队尾两线的交点在 Hh 外,弹出队尾,重复检查
  2. 若队首两线的交点在 Hh 外,弹出队首,重复检查
  3. 把 h 加到队尾

所有线处理完,还要闭合首尾:用队首约束检查队尾交点、用队尾约束检查队首交点,只要任一端仍违反就继续删除,直到两端同时有效。最后依次计算相邻交点,包括末线与首线的交点,再合并连续相同的点,首尾相同也只保留一次。两两不平行仍允许三条以上边界共点;严格的“在外”测试可能留下只接触一个顶点的冗余边界,未经这一步规范化的交点序列会含零长度边。

直觉

方向次序把凸边界变成一条只能向同一方向转弯的链。新约束的方向排在所有旧方向后面,因此它可能截掉的候选角点集中在链的两端;中间不能留下“先删一块、再保留一块、再删一块”的交替缺口,否则一条直线与凸链的相交次序会违背凸性。

这里保存的是尚可能属于最终边界的方向有序链。在扫描尚未闭合一圈时,交集可能无界,不能把当前相邻交点草率称为一个已经正确闭合的多边形。末尾的首尾清理正是把开放链变成真实有界边界的必要步骤。

删除队尾的局部理由可以从三条方向递增的线看出:若旧两线交点被新半平面排除,旧尾线在这一端留下的可行边段被夹空;旧前线和新线接起来即可代表这一端的约束边界。队首的论证相同,只发生在方向序列的另一端。这个判断反复应用,保留的每一条边界都有非空的相邻可行段;合约中的最终正面积和有界性保证闭合后至少有三条有效边界。

候选边界的进入与删除
例子与边界

一条暂存、随后被删的约束 ​

按逆时针顺序取五个点

A=(0,0), B=(4,0), C=(5,2), D=(2,5), E=(−1,3).

它们相邻连边的左半平面恰围出这个凸五边形。再加入直线

h: (−3,−2)→(1,−1),

其方向为 (4,1),保留区域为 y≥x/4−5/4,所以它实际上不切掉五边形。

方向排序后,AB 先入队,接着是 h。二者交于 (5,0)。加入 BC 时,这个交点在 BC 的右侧,因为

orient(B,C,(5,0))=−2<0.

于是 h 被弹出,队尾改由 AB,BC 构成,交点回到真正的顶点 B。后续 CD,DE,EA 加入,闭合后得到 A,B,C,D,E。这一次删除不是根据 h 的“看起来很远”,而是有精确的局部违反证书。

共点与其他退化边界 ​

例如三角形 (0,0),(4,0),(0,4) 的三条逆时针边,再加入过 (0,0)、方向为 (1,−2) 的线,保留半平面 2x+y≥0。四条边界两两不平行,交集仍是原三角形。新线仅接触 (0,0),严格删除条件不会将它弹出;末尾相邻求交会连续给出两次 (0,0),合并后才得到三个不同顶点。这个规范化只需再扫描一次,不改变线性队列阶段的界。

同向平行约束可以先保留更紧的一条。例如 y≥0 与 y≥2 只需保留后者。但反向平行线可能围出条带,也可能矛盾;仅按“平行”就报空会把 0≤y≤2 判错。本页给出的最简求交函数会拒绝平行边界,不能把除零后的数值继续当顶点。

两个相反半平面也可能把可行域压成直线;若再加入其他限制,还可能只剩线段或单点。方向队列最后少于三个普通角点,并不能区分这些情况与空集。因此若接口允许它们,应增加独立的可行性与维数分类,再使用相应的无界/低维输出类型;正面积版本仅返回二维有界多边形;扩大输入范围时,应同时扩大输出类型和判定步骤。

已知有界也不是“任选一个大数作框”。若真正解含坐标 1012,边长 106 的框会悄悄删掉它。只有问题本身提供合法边界,或已有证明给出足够的坐标界,才可以把框的四个半平面作为输入的一部分。

推论与应用

比较排序花 O(nlog⁡n)。每条线进入队列一次,离开至多一次,所以所有首尾清理合计 O(n) 次;不能把每次 while 的最坏长度相加成 O(n2)。每次判断只用常数次求交和方向判定。这里的算术操作数界以有理数运算为单位,大整数分子分母的位成本需要另外核算。

它把多面体的 H-表示转换成二维顶点表示;而逐半平面裁剪从一份已知有界轮廓出发,更容易保留点、线段和空集状态。两种算法的输入合约、状态和保证不同。对于已经按方向排列的凸轮廓约束,排序可以省略;队列阶段本身保持线性。

参考资料
关系图谱13 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系