凸包问题及其求解方法

凸包问题

什么是凸包问题?

  • 凸包:包含给定集合X的凸集的交集。
  • 概念
    -点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。下图中由红色线段表示的多边形就是点集Q={p0,p1,…p12}的凸包。
    凸包
  • 凸包问题:一组平面上的点,求一个包含所有点的最小的凸多边形。
    -这可以形象地想成这样:在地上放置一些不可移动的木桩,用一根绳子把他们尽量紧地圈起来,并且为凸边形,这就是凸包了。

常见的求解方法

  • Graham扫描法
  • Jarvis步进法
  • 分治法

  • 1.Graham扫描法
    复杂度
    这个算法可以直接在原数据上进行运算,因此空间复杂度为O⑴。但如果将凸包的结果存储到另一数组中,则可能在代码级别进行优化。由于在扫描凸包前要进行排序,因此时间复杂度至少为快速排序的O(nlgn)。后面的扫描过程复杂度为O(n),因此整个算法的复杂度为O(nlgn)。

    思路:先找到凸包上一个点,然后从那个点按逆时针方向逐个找凸包上的点。

    步骤:

    • 1.把所有点放在二维坐标系中,找到纵坐标最小的点,这个点一定是凸包上的点,为P0。
    • 2.计算各个点与P0连线P0Pi,与水平方向的夹角,按从小到大对各个点进行排序,当夹角相同是,距离P0近的点排在前面,依次为P0,P1,……P(n-1)。由几何知识知道,结果中第一个点和最后一个点一定是凸包上的点。
    • 3.将凸包上的第一个点P0和第二个点P1放入栈里面,然后将P1后面的点,即P2拿出来作为当前点,开始找第三个点:
    • 4.连接P0和栈顶的那个点,得到直线L。看当前点是在直线L的左边还是右边。如果在右边(叉积大于0),执行步骤5,如果在直线上或是在左边(叉积小于等于0),就执行步骤6。
    • 5.如果在右边,则栈顶的那个点P1不是凸包上的点,把栈顶元素出栈。执行步骤4.
    • 6.当前点是凸包上的点,把它P2压入栈,执行步骤7.
    • 7.检查当前点P2是不是步骤3中结果的最后一个元素。是,就结束。如果不是就把P2后面的点作为当前点,返回步骤4。

    最后,栈中元素就是凸包上的点了。
    Graham扫描法

  • 2.Jarvis步进法
    复杂度
    时间复杂度:O(nH)。(其中n是点的总个数,H是凸包上的点的个数)

    思路:

    • 找到纵坐标最小的点,这个点一定为凸包上的点,设为P0。
    • 从P0开始,按逆时针的方向,逐个找凸包上的点,每前进一步找到一个点,所以叫做步进法。
    • 利用夹角找下一个点。假设现在已经找到了{P0,P1,P2},要找下一个点:剩下的点分别和P2组成向量,设这个向量与向量P1P2的夹角为 β 。当 β 最小的时候,就是所要求的下一个点了。

    注意:

    • 1.找第二个点P1时,因为已经找到的只有P0一个点,所以向量只能和水平线做夹角 α ,当 α 最小时,求得第二个点。
    • 2.共线情况:如果直线P2P3上还有一个点P4,即三个点共线,此时由向量P2P3和向量P2P4产生的两个 β 是相同的。我们应该把P3、P4都当做凸包上的点,并且把距离P2最远的那个点作为最后搜索到的点,继续找它的下一个连接点。
      Jarvis步进法
  • 3.分治法
    复杂度
    时间复杂度:O(nlogn)。
    思路:应用分治法思想,把一个大问题分成几个结构相同的子问题,把子问题进一步细化。然后利用递归的方法分别求子问题的解。

    步骤:

    • 1.将所有点放入二维坐标系中,设横坐标最小的点为P0,横坐标最大的点为Pn。这两点一定是凸包上的点。直线P1Pn把点集分成两个部分,x轴上部叫做上包,下部叫做下包。
    • 2.对上包:求距离直线P1Pn最远的点,即下图中的点Pmax。
    • 3.作直线P1Pmax、PnPmax,把直线P1Pmax左侧的点当成是上包,把直线PnPmax右侧的点也当成是上包。
    • 4.重复步骤2、3。
    • 5.对下包也作类似操作。
      分治法

参考:http://blog.csdn.net/bone_ace/article/details/46239187

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值