Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 由最大n个点组成的凸包_Algorithm_Geometry_Polygon_Computational Geometry_Convex Hull - Fatal编程技术网

Algorithm 由最大n个点组成的凸包

Algorithm 由最大n个点组成的凸包,algorithm,geometry,polygon,computational-geometry,convex-hull,Algorithm,Geometry,Polygon,Computational Geometry,Convex Hull,给定一组二维点X,我想找到一个由最大n个点组成的凸包。当然,这并不总是可能的。因此,我在寻找一个近似的凸壳,它由最大n个点组成,最大覆盖点集X 更正式地说,如果F(H,X)返回凸壳H覆盖的X点的数量,其中| H |是构建壳的点的数量,那么我寻求以下数量: H|hat=argmax|H F(H,X),s.t | H |可能以下方法适用于您:最初,计算凸包H。然后从H中随机选择n点的子集,这将构造一个新的多边形,该多边形可能不会覆盖所有点,因此我们将其称为准凸壳Q。计算Q(内联线)中包含的点数。重复

给定一组二维点X,我想找到一个由最大n个点组成的凸包。当然,这并不总是可能的。因此,我在寻找一个近似的凸壳,它由最大n个点组成,最大覆盖点集X

更正式地说,如果F(H,X)返回凸壳H覆盖的X点的数量,其中| H |是构建壳的点的数量,那么我寻求以下数量:


H|hat=argmax|H F(H,X),s.t | H |可能以下方法适用于您:最初,计算凸包
H
。然后从
H
中随机选择
n
点的子集,这将构造一个新的多边形,该多边形可能不会覆盖所有点,因此我们将其称为准凸壳
Q
。计算
Q
(内联线)中包含的点数。重复此操作一定次数,并将
Q
提案保持在最内联的位置

这似乎与RANSAC有点相关,但对于这项任务,我们实际上不知道什么是离群值,因此我们无法真正估计离群值比率。因此,我不知道近似值有多好,或者需要多少次迭代才能得到合理的结果。可能您可以添加一些试探法,而不是纯粹随机选择
n
点,或者您可以设置一个阈值,即
Q
中至少应包含多少点,然后在达到该阈值时停止

编辑

实际上,在考虑之后,您可以使用RANSAC方法:

max\u inliers=0
最佳=无
虽然(正确):
点=样本点(X)
Q=构造凸壳(点)
n\u内插层=计数内插层(Q,X)
如果n\u inliers>max\u inliers:
最大内边界=n内边界
最佳Q=Q
如果出现以下情况:
打破
这样做的好处是,凸包的创建速度比您的方法快,因为它最多只使用
n
个点。此外,检查内联线的数量应该很快,因为它可能只是对凸包的每个分支进行一系列符号比较。

一些想法

  • 删除顶点时排除的点位于由该顶点和凸包上与其相邻的两个顶点构成的三角形中。删除任何其他顶点不会影响可能排除的点集。因此,对于每个删除的顶点,我们只需重新计算覆盖率两次

  • 说到重新计算覆盖率,我们不一定要看每一点。这个想法并不能改善最坏的情况,但我认为它在实践中应该是一个很大的改进。按如下所示维护点索引。选择一个随机顶点作为“根”,并将由根和其他两个顶点组成的三角形所包含的点分组(O(m log m)时间,使用良好的算法)。每当我们删除一个非根顶点时,我们就合并并过滤两个点集,以获得涉及已删除顶点的三角形。每当我们重新计算覆盖率时,我们只能扫描两个相关三角形中的点。如果我们删除了这个根,请选择一个新的根并重做索引。此维护的总成本预计为O(m log^2 m),其中m是点数。然而,计算覆盖率的成本更难估计

  • 如果点在船体内合理均匀分布,可以使用面积作为覆盖范围的代理。将顶点按其邻居(ear)形成的三角形面积排序存储在优先级队列中。无论何时删除一个点,都会更新其两个相邻点的耳朵区域。这是一个O(m log m)算法


  • 下面的内容并没有像我所描述的那样解决这个问题,但是它解决了产生这个问题的问题。因此,我想添加它,以防其他人遇到类似的情况

    我调查了两种方法:

    1) 将凸包视为多边形,并对其应用多边形简化算法。我研究的具体算法是

    2) 应用问题中描述的算法,无需重新计算凸包


    这两种方法都不能(据我所知)为所述的优化问题提供所需的解决方案,但对于我的任务来说,它们工作得足够好。

    是不是必须由原始点组成,还是可以添加新点?嘿,我添加了计算几何作为标签,因为我知道至少有一位专家专门关注它。你做了一个很好的标签,所以我不得不退出“凸面”。希望没问题;您可以根据需要进行调整。一个主要的困难是,当您删除点时,船体的大小不会单调减小。我怀疑是否可以逐步找到最佳解决方案。考虑H=3的情况,假设您找到了一个覆盖5个点的三角形。也许在另一个完全不同的地方有另一个地方包含了100个。@Davidisenstat:我的意思是,这个问题似乎没有很好的局部属性。更改一个顶点可能会更改90%的覆盖率。
    X = getSet() \\ Get the set of 2D points
    H = convexHull(X) \\ Compute the convex hull
    while |H| > n do
        n_max = 0
        for h in H:
            H_ = remove(h,H) \\ Remove one point of the convex hull
            n_c = computeCoverage(X,H_) \\ Compute the coverage of the modified convex hull.
            \\ Save which point can be removed such that the coverage is reduced minimally.
            if n_c > n_max:
                n_max = n_c
                h_toremove = h
        \\ Remove the point and recompute the convex hull.
        X = remove(h,X)
        H = convexHull(X)