【问题标题】:Intersection of N rectanglesN 个矩形的交集
【发布时间】:2011-05-04 08:22:44
【问题描述】:

我正在寻找解决这个问题的算法:

给定笛卡尔坐标上的 N 个矩形,找出这些矩形的交点是否为空。每个矩形可以位于任何方向(不必使其边缘平行于 Ox 和 Oy)

您对解决这个问题有什么建议吗? :) 我可以考虑测试每个矩形对的交集。但是,它是 O(N*N) 并且非常慢:(

【问题讨论】:

标签: algorithm geometry computational-geometry


【解决方案1】:

摘要

要么根据矩形的最小 X 值使用排序算法,要么将矩形存储在 R-tree 中并搜索它。

直截了当的方法(带排序)

让我们表示low_x() - 矩形的最小(最左侧)X 值,high_x() - 矩形的最高(最右侧)X 值。

算法:

Sort the rectangles according to low_x().                   # O(n log n)

For each rectangle in sorted array:                         # O(n)
    Finds its highest X point.                              # O(1)
    Compare it with all rectangles whose low_x() is smaller # O(log n)
        than this.high(x)

复杂性分析

这应该适用于均匀分布的矩形上的O(n log n)

最坏的情况是O(n^2),例如当矩形不重叠但一个在另一个之上时。在这种情况下,将算法推广到也有low_y()high_y()

数据结构方法:R-Trees

R-trees(B-trees 的空间泛化)是存储地理空间数据的最佳方式之一,可用于解决此问题。只需将矩形存储在 R-tree 中,您就可以通过简单的O(n log n) 复杂性发现交叉点。 (n 搜索,log n 每个时间)。

【讨论】:

  • O(n^2)。最后一步不是 O(log n)。反例:一组矩形{ [k, 2n-k]×[0, 1] | k ∈ {0, ..., n-1} }
  • @ybungalobill:见附录 - 矩形也可以根据 Y 值排序,所以它仍然是 O(n log n)
  • @Adam:不。反例 2:{ [k, 2n-k]×[k, 2n-k] | k ∈ {0, ..., n-1} } — 随心所欲地排序,使用 R-tree... 它仍然是 O(n^2)。
  • 亚当,记住“每个矩形都可以位于任何方向(不一定要使其边缘平行于 Ox 和 Oy)”
  • 是的,这是错误问题的答案。并且累积 n 个轴对齐框的交集是微不足道的,您不需要任何非平凡的数据结构。只需敲掉框的轴对齐切片即可。
【解决方案2】:

观察 1:给定一个多边形 A 和一个矩形 B,交点 A ∩ B 可以通过与 B 的每条边对应的半平面的 4 个交点来计算。

观察 2:从凸多边形切割半平面会得到一个凸多边形。第一个矩形是凸多边形。这个操作最多每增加1个顶点数。

观察 3:凸多边形的顶点到直线的有符号距离是单峰函数。

这是算法的草图:

在平衡二叉树中按逆时针顺序维护当前部分交集D。

当切割由直线 L 定义的半平面时,找到 D 中与 L 相交的两条边。这可以通过一些巧妙的二元或三元搜索在对数时间内完成,该搜索利用到 L 的有符号距离的单峰性。(这是我不太记得的部分。)从D中删除L一侧的所有顶点,并将交点插入D。

对所有矩形的所有边 L 重复。

【讨论】:

    【解决方案3】:

    这似乎是克利测量的一个很好的应用。基本上,如果您阅读http://en.wikipedia.org/wiki/Klee%27s_measure_problem,则可以在 O(n log n) 处找到直线交叉点的最佳算法的运行时间下限。

    【讨论】:

    • 是的,Klee 的度量几乎是这个问题的概括,并且完美地涵盖了它,展示了一个最佳算法。
    • 我正在寻找交叉点。我认为克利的衡量标准是关于这些矩形的联合?
    • 这个答案很有趣,但不清楚它是如何应用的。也许通过以某种方式取补,关于交集的问题可以被构建为关于并集的问题?
    【解决方案4】:

    我认为你应该使用sweep line algorithm 之类的东西:寻找交叉点是它的应用之一。另外,看看answers to this questions

    【讨论】:

    • 我在这里看到的一个问题是,我可以使用 n 个矩形创建 n^2 个边界交叉点...(考虑不同厚度的加号)。
    【解决方案5】:

    由于矩形不能平行于轴,将问题转换为已经解决的问题更容易:计算矩形的边界交点 .

    • 建立一个包含所有边框的集合S,以及它们所属的矩形;你会得到一组形式为 ((x_start,y_start), (x_end,y_end), r_n) 的元组,其中 r_n 当然是对应矩形的 ID
    • 现在使用扫描线算法来查找这些线的交点

    扫描线在 S 中的每个 x 坐标处停止,即所有起始值和所有结束值。对于每一个新的起始坐标,将对应的线放入一个临时集合 I。对于每个新的结束坐标,从 I 中删除对应的线。

    除了向 I 添加新线之外,您还可以检查每条新线是否与当前 I 中的一条线相交。如果相交,相应的矩形也会相交。

    你可以找到这个算法的详细解释here

    运行时间为O(n*log(n) + c*log(n)),其中c是I中线的交点数。

    【讨论】:

    • 问题是 c=n^2 是可能的。请参阅我对@MarcoS 答案的评论。
    • @ybunga:没错,但这就是潜在问题的本质。如果解集的最大大小为 n^2,则找到该集的算法也必须具有 O(n^2) 的最坏情况运行时间。我建议的算法的优点是它的运行时间可以适应解决方案的复杂性。
    【解决方案6】:

    从集合中选择最小的矩形(或任何矩形),然后遍历其中的每个点。如果其中一个点也存在于所有其他矩形中,则交点不为空。如果所有点都没有 ALL 其他矩形,则交点为空。

    【讨论】:

    • 如果 R1 不与 R2 和 R3 相交,这并不意味着 R2 和 R3 不相交
    • @ariel :但这意味着 R1、R2 和 R3 不相交。但这仍然是低效的,我们可以说只看亚当提到的矩形的边缘(顶部/底部或左/右)。
    • 你如何确定“其中的每个点”? :) 因为一个区域内有无数个点。
    猜你喜欢
    • 2018-05-24
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多