凸包学习

432 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

有帮助的话请点个赞吧~

刷题的时候看到了新的概念,来好好学习一下。

定义

  • 在一个实数向量空间VV中,对于给定集合XX,所有包含XX的凸集的交集SS被称为XX的凸包。

    • S:=XKV,KisconvexKS:=\bigcap_{X\subseteq K\subseteq V,\,K\,is\,convex} K
    • 凸集:在点集拓扑学与欧几里得空间中,凸集(Convex set)是一个点集合,其中每两点之间的直线点都落在该点集合中。
      image.png
      • 其实可以发现这些点集构成的图形每个边都是向外凸的,所以才叫凸集嘛。
    • XX的凸包可以用XX内所有点(x1,,xn)(x_1,\dots,x_n)的线性组合来构造。
      • S:={j=1ntjxjxjX,j=1ntj=1,tj[0,1]}S:=\lbrace \sum^n_{j=1}t_jx_j|x_j\in X,\sum^n_{j=1}t_j=1,t_j\in[0,1]\rbrace
  • 在二维欧几里得空间中,凸包可想象为一条刚好包着所有点的橡皮圈。

算法简介

  • 增量式算法
    • 逐个将点加入集合构成凸包,检查之前的点是否存在于新的凸包集合。
    • 每次都要检查之前所有的点,遍历套一个遍历,所以时间复杂度为O(n2)O(n^2)
  • 包裹法(Jarvis步进法)
    • 由必定在凸包的点开始,如最左边的点P1P_1,然后找P1P_1右边的第一个点P2P_2,使得其他所有点与P1PP_1P_*构成的向量都在向量P1P2P_1P_2右边。(比较所有向量P1PP_1P_*的极坐标角度)
    • 然后以P2P_2作为向量起点,重复上述步骤,依次找到后续的P3,P4,,Pk,P1P_3,P_4,\dots,P_k,P_1,最终会找回到起点P1P_1
    • 总共会找到kk个点,每找一个点的时间复杂度为O(n)O(n),所以总时间复杂度为O(kn)O(kn)
    • 会每次都重复遍历后面所有的点。
  • 葛立恒(Graham)扫描法
    • 由最底的点P1P_1开始(最左下),计算它与其他各点连线与x轴正向的角度,由小到大排序,称其对应点为P2,P3,,PnP_2,P_3,\dots,P_n
    • 从该集合中依次取点判断,上一条路径到下一条路径是向右(内)转还是向左(外)转
      • 若向右转则该点不会在凸包上,丢弃考虑下一个点;
      • 若向左转则以该点为头重复判断,直至最终转回P1P_1
      • 如最开始考虑路径P2P3\overrightarrow{P_2P_3}相对路径P1P2\overrightarrow{P_1P_2}如何变化:
        • 若向右(内),则表示P3P_3不可能是凸包上的一点,开始判断P2P4\overrightarrow{P_2P_4}
        • 若向左(外):则表示P3P_3可能是凸包上的一点,开始判断P3P4\overrightarrow{P_3P_4}
    • 时间复杂度由前面的排序决定,后面判断为O(1)O(1),则整体时间复杂度为O(nlogn)O(n\log n)
    • 每个点只会被考虑一次,但不可推广到二维以上的情况。
  • 单调链(Andrew算法基于此)
    • 按坐标进行双关键字排序,先按x坐标值排序,再按y坐标值排序。(从左到右、从下到上)
    • 选择x坐标为最小值的点,在这些点中找出y坐标的值最大和y坐标的值最小的点。对于x坐标为最大值也是这样处理。将两组点中y坐标值较小的点连起。在这条线段下的点,找出它们之中y坐标值最大的点,又在它们之间找x坐标值再最小和最大的点……如此类推。
      • 大概是先定位首尾边界,然后找离连线最近的凸包外点,分别与边界相连,再继续找离新连线最近的外点……一个一个往里面放。
  • 分治链
    • 将点集XX划分为两个不相交的子集,分别求两者的凸包后,计算这两个凸包的凸包,结果即为XX的凸包。(二分)
    • 时间复杂度为O(nlogn)O(n\log n)
  • 快包法(Akl-Toussaint启发式)
    • 选择最左、最右、最上、最下的点构成一个凸四边形,排除其内的点,然后其余点按靠近的边划分为四个部分,再分别进行快包法(Quick Hull)。

实现应用

在leetcode587.安装栅栏一题中进行更详细的叙述与应用,并用两种语言实现了三种算法,可以康康这里→ Java&C++题解与拓展——leetcode587.安装栅栏【二维凸包学习】

参考

[1] 凸包 - wikipedia


欢迎指正与讨论!