【问题标题】:Algorithm to find if a set of point describes a convex enveloppe查找一组点是否描述凸包络的算法
【发布时间】:2011-07-04 16:24:47
【问题描述】:

我想检查一组 N 个点是否描述了一个凸多边形

我想知道是否有一个好的算法?

这是我想到的一些方法:


1.凸包算法:

如果集合等于他的凸包,那么它是凸的。这种算法的复杂度为 O(n*LN(N))。但我有一种感觉,就像在轮子上折断一只蝴蝶。


3.看角度:

然后我想检查两个连续向量的角度是否永远不会超过 180°。 但由于我的点没有排序,我需要检查 3 个连续点的所有组合,这使得复杂度像 O(n3)。(应该有比这更好的方法)

例如,我尝试从右到左选择点,但结果并不总是预期的:

例如在这种情况下,如果我从左到右,我会发现一个凸形:

所以对于这个解决方案,我可能需要一个好的算法来选择点。


3.看着重心:

我认为检查所有 3 个连续点的重心是否在形状内会告诉我形状是否是凸的。

这就是我的意思(G 是每个三角形的重心):

对于这个解决方案,我可以毫无问题地从左到右选择点。如果检查 G 是否在形状中的复杂度为 O(N),那么总体复杂度将类似于 O(N2)。

您能否建议我解决这个问题的好算法或改进我正在考虑的解决方案

提前致谢

【问题讨论】:

  • 对方法 1 的快速建议:与其实际构建凸包,不如运行算法并尽快终止/如果它丢弃任何点。
  • 我去看看。谢谢
  • 错过了我评论的编辑窗口。 '算法' = Grahams Scan (它或多或少地按照您的方法 2 建议的方式执行)。另外,我知道这不会提高渐近运行时间,但它使问题很容易并行化。
  • 我的印象是,如果您没有关于您的 N 积分的信息(它们是否已订购?)那么您将无法得到比 N*log(N) 更好的信息。如果我能拿出一个证明,我会很乐意与你分享,但现在,这更像是一种感觉而不是证明。
  • @user786653:要做到这一点,您仍然需要对项目进行排序,因此您最终会完成相同数量的工作(渐近地说)。但是,在实践中执行它仍然是一个很好的优化,即使您最好减少小于一个常数因子。

标签: algorithm convex-polygon


【解决方案1】:

如果你的输入是一个简单的多边形,你可以在线性时间内完成,但这并不明显。这个问题的错误解决方案由来已久,您可以在以下网页上阅读:

http://cgm.cs.mcgill.ca/~athens/cs601/

今天,人们普遍认为解决这个问题的最简单/最好的方法是使用梅尔克曼算法:

http://softsurfer.com/Archive/algorithm_0203/algorithm_0203.htm#Melkman%20Algorithm

如果您没有简单的多边形,那么在最坏的情况下,它与常规凸包一样难(因为您可以解决任何普通的凸包问题并任意连接点以获得一些无意义的多边形)。

【讨论】:

  • 非常感谢我会仔细看看这个算法
【解决方案2】:

我想从维基百科开始Grahams Scan:

做所有事情,包括“用点[1]按极角排序点”。

然后:

for i = 3 to N:
    if ccw(points[i-2], points[i-1], points[i]) < 0: # Note this inequality might need checking
        return NotConvex
return Convex

排序和凸性检查都非常适合并行化,如果需要,可以合并以进一步加快速度。

【讨论】:

    猜你喜欢
    • 2011-06-21
    • 2016-12-21
    • 2019-06-11
    • 2014-12-12
    • 2021-10-23
    • 2015-10-02
    • 2013-05-20
    • 2015-05-25
    相关资源
    最近更新 更多