【问题标题】:Fast hiding of intersecting rectangles快速隐藏相交的矩形
【发布时间】:2012-03-19 14:45:55
【问题描述】:

我正在研究一种有效的算法,以“隐藏”在一组N 矩形(轴对齐)中以 2D 形式排列的所有相交矩形对。 所有矩形都具有相同的宽度和高度。

假设我以 2D 布局的起始矩形集是 R={r_1,r_2,...,r_n} 其中r_i 是所有矩形,r_i 具有布尔属性visible

我想找到 R 的子集 S,使得对于属于 S r_i,_r_j 的每个 r_ir_j 不相交。

第一个简单的解决方案是蛮力最大独立集方法。 首先,我遍历N(N-1)/2 矩形(给定的矩形不与自身相交)并检查它们是否相交。同时,我还将集合R 中的所有矩形作为图G=(V,E) 的节点。该图中的边由成对的相交三角形表示。

这组不相交的矩形是图的一个最大独立集

我认为这不是最快的方法,虽然是正确的。我在一些讨论中读过,例如如何通过 x 坐标预先对矩形列表进行排序将加速相交矩形对的计算到O(nlog(n) )(而不是蛮力O(n^2)

现在我在问,是否有人知道针对此类问题的更好算法(用于计算一组矩形中的相交对和过滤这些矩形?)

将问题重新表述为 SAT 问题也可能很有趣,尽管这个想法刚刚出现在我的脑海中。问题在于找到visible 属性的排列,使得没有可见的矩形与另一个矩形相交。

【问题讨论】:

    标签: algorithm graph-theory computational-geometry intersection


    【解决方案1】:

    是的,您应该按 x 对矩形进行排序。
    由于您的矩形在同一 x 轴上并且高度相同,因此在对它们进行排序后,您应该能够在线性时间内找到交点。您正在寻找的算法称为扫描线。

    您在所有矩形上移动一条扫描线(从您刚刚排序的集合中的 x 坐标跳转)并查看哪些在当前 x 位置相交。将所有 x 坐标重叠的矩形加载到数据结构中并检查它们是否相交(基于 y 坐标)。

    【讨论】:

    • 好吧,我会试试的。真正的问题确实是如何找到矩形的排列,使得给定它们的成对交集,在原始集合中没有相交的矩形。有最大独立集比我更快的方法吗?
    • 我不确定你所说的矩形排列是什么意思。您是否通过对某些种子值进行排列来创建矩形?我不相信除了成对之外还有其他方法可以进行直交。也许您可以使用它占据的矩形区域/空间区域(如果您知道如何标记它)并将其添加到地图中。然后再次遍历所有矩形,看看它们是否“匹配”该地图中的任何区域(除了它们自己的区域)。
    • 列表排序后就不需要成对了。您可以利用此属性编写 O(N log(N) ) 碰撞检查!它运作良好,我本着扫描线算法的精神实现了它。这是逻辑:i=0,S={},N=|R| while (i
    • @linello 这正是它应该做的;但我看到你也在成对地做......除非我不正确理解成对的意思。您正在逐个比较矩形以查看它们是否相交。这不是“一对”还是矩形?
    • 是的,这实际上是成对的,但通过这种方式,我可以避免双重嵌套 for 循环,通过利用矩形按其 x 坐标排序的事实。成对比较很难避免。
    【解决方案2】:

    S 可能不止一个子集。例如,考虑以下矩形布局:

         +-----+
         |     |
         |  A  |
    +----|    +-----+
    |    +----|     |
    |  D  |   |  B  |
    |     |--- +    |
    +-----+    |----+
         |  C  |
         |     |
         +-----+
    

    {A,C}{B,D} 都是有效答案。所以,这个问题有点不明确。您在寻找最大基数子集吗?

    【讨论】:

    • 我知道有很多解决方案。我用一个简单的随机算法取一个最大独立子集,因为找到最大独立子集对于这个任务来说计算量太大,我不需要它。
    • @Adrian:在这种情况下,所有“不相交”的矩形的有效排列是 {A,C} 或 {B,D}
    【解决方案3】:

    测试所有成对的组合是个好主意,但是 O(n^2) 有助于找到加快速度的方法。

    将空间划分为一个粗略的网格,就像棋盘一样,每个单元格都有一个它拥有的矩形列表。这意味着矩形的中心点在单元格中。将矩形分配给单元格是 O(n)。

    单元格的大小必须比矩形大很多,可能是两倍,并且整个空间需要分成“几”行和列——比如一打、几百,但是对于数量而言,多少是有意义的矩形和它们所在区域的大小。不过至少要五行五列,否则效率不会很高。

    然后测试每个单元格内的所有成对组合。这将消除一堆重叠的对。对于每个单元格,您还必须测试涉及八个相邻单元格的所有成对组合 - 共享边或角的单元格 - 因为一个矩形最多可以重叠四个单元格。当然,请注意不要重复计算对。

    节省了执行时间,因为您永远不会测试一个矩形在此处而另一个矩形在远处区域的任何对。

    这种技术是通用的,可以应用于任何形状,类似于物理学家在模拟巨大的粒子系统(如星系中的恒星)时使用的技术。

    【讨论】:

      猜你喜欢
      • 2014-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 2021-05-24
      • 2021-02-25
      • 1970-01-01
      相关资源
      最近更新 更多