【问题标题】:Dynamic and/or Static Rectilinear/Orthogonal/X-Y Convex Hull动态和/或静态直线/正交/X-Y 凸包
【发布时间】:2013-01-02 19:14:57
【问题描述】:

我正在寻找一种有效的算法来处理二维动态rectilinear convex hulls

我编写了一个静态算法,虽然它在大多数情况下都有效,但它根本不起作用,所以我也在寻找关于静态直线凸包的资源。维基百科有一些关于算法的研究论文,但我无法访问它们。所以寻找其他来源或帮助编写代码。

任何帮助都将不胜感激,Python 中的算法,非常感谢。

当前静态代码:

def stepped_hull(points, is_sorted=False, return_sections=False):
    # May be equivalent to the orthogonal convex hull

    if not is_sorted:
        points = sorted(set(points))

    if len(points) <= 1:
        return points

    # Get extreme y points
    min_y = min(points, lambda p:p[1])
    max_y = max(points, lambda p:p[1])

    points_reversed = list(reversed(points))

    # Create upper section
    upper_left = build_stepped_upper(points, max_y)
    upper_right = build_stepped_upper(points_reversed, max_y)

    # Create lower section
    lower_left = build_stepped_lower(points, min_y)
    lower_right = build_stepped_lower(points_reversed, min_y)

    # Correct the ordering
    lower_right.reverse()
    upper_left.reverse()

    if return_sections:
        return lower_left, lower_right, upper_right, upper_left

    # Remove duplicate points
    hull = OrderedSet(lower_left + lower_right + upper_right + upper_left)
    return list(hull)

def build_stepped_upper(points, max_y):
    # Steps towards the highest y point

    section = [points[0]]

    if max_y != points[0]:
        for point in points:
            if point[1] >= section[-1][1]:
                section.append(point)

            if max_y == point:
                break
    return section

def build_stepped_lower(points, min_y):
    # Steps towards the lowest y point

    section = [points[0]]

    if min_y != points[0]:
        for point in points:
            if point[1] <= section[-1][1]:
                section.append(point)

            if min_y == point:
                break
    return section

【问题讨论】:

  • 动态你的意思是你想维护一个 x-y 凸包,它的点在程序执行过程中被修改?您的意思是您的静态算法有效,但更新凸包失败,还是在其他方面失败?
  • 基本上,我想从一组点创建一个 x-y 船体,删除 1 个或多个船体点,重新计算船体。删除一些排序点重新计算,依此类推。我想避免在 O(N log N) 处删除点,O(N) 可能是可行的,O(log N) 是理想的。我目前正在使用一种静态算法来给出正确的点,但由于我编码它的方式,在一个点是 x 和 y 的极值点的情况下,可能已经越过了边缘。一个相对较小的问题,但表明该算法可能在其他方面存在缺陷。因此,如果可能的话,会更喜欢已知的“正确”算法。
  • 我承认我还没有为这种凸包实现算法,但它是独一无二的(考虑单平面方向)吗?例如,如果您有两个点,ab,在相同的 x 坐标和不同的 y 坐标上,您可以简单地链接一个点 c,它位于两个点的左侧,并且位于两个点的下方他们,在ab 之间的最上面?或者是否需要先将c 连接到最底部?
  • 在这种情况下连接到最上面会创建一个凸包,该凸包的面积大于另一种方法所做的面积。这是否会取消前者作为 x-y 凸包的资格?
  • 我用来检查要删除哪些点的算法依赖于正确的顺序,因此需要 c-b-a,这就是为什么我在静态算法中遇到的小问题是有问题的。虽然,既然你提到它,这可能是获得算法比 O(N) 算法更好的问题

标签: python performance algorithm convex


【解决方案1】:

对于正确算法的实现,您可能需要查看this。对于Rectilinear Convex hull的动态维护,最好寻找动态数据结构来维护Maxima of a Set,这是一个研究较多的课题。点集的最大元素的集合就是Rectilinear Convex Hull的顶点集合,所以这两个问题是等价的。

您可以在 this paper 中找到每次操作花费 $O(\log n)$ 时间的算法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 2012-03-12
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多