Algorithm 相交矩形的快速隐藏

Algorithm 相交矩形的快速隐藏,algorithm,graph-theory,computational-geometry,intersection,Algorithm,Graph Theory,Computational Geometry,Intersection,我正在研究一种有效的算法,以“隐藏”在一组N矩形(轴对齐)中二维布局的所有相交矩形对。 所有矩形的宽度和高度都相同 假设我在2D中布置的矩形的起始集是 R={R_1,R_2,…,R_n} 其中r\u i是所有的矩形,r\u i具有布尔属性可见 我想找到R的子集S,这样对于属于SR\I的每个R\u I,R\u j,R\u j不相交 第一个简单的解决方案是蛮力最大独立集方法。 首先,我迭代N(N-1)/2矩形(给定的矩形不与其自身相交),并检查它们是否相交。同时,我还将集合中的所有矩形作为图的节点G

我正在研究一种有效的算法,以“隐藏”在一组
N
矩形(轴对齐)中二维布局的所有相交矩形对。 所有矩形的宽度和高度都相同

假设我在2D中布置的矩形的起始集是
R={R_1,R_2,…,R_n}
其中
r\u i
是所有的矩形,
r\u i
具有布尔属性
可见

我想找到R的子集S,这样对于属于S
R\I的每个
R\u I
R\u j
,R\u j
不相交

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

非相交矩形集就是图的一个最大独立集

我认为这不是最快的方法,尽管是正确的。我在一些讨论中读到过,例如,如何通过x坐标提前排序矩形列表,将相交矩形对的计算速度提高到
O(nlog(n))
(而不是暴力
O(n^2)

现在我在问,有人知道更好的算法来解决这个问题吗(用于计算一组矩形中的相交对和过滤这些矩形?)


将这个问题重新表述为SAT问题也很有趣,尽管我刚刚想到了这个想法。问题是在这里发现
可见属性的排列方式,使得没有可见矩形与另一个相交。

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


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

可能只有一个子集<代码> s>代码>。例如,考虑下面的矩形布局:

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

{A,C}
{B,D}
都是有效的答案。因此,这个问题的定义有点不准确。你在寻找最大基数子集吗?

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

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

这些单元必须比矩形大一点,可能是矩形的两倍,整个空间需要分成“几个”行和列——比如说十几行、几百行,但是许多行和列对于矩形的数量和它们所居住的区域的大小来说是有意义的。但是至少有五行和五列,否则你不会获得太多的效率

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

这样可以节省执行时间,因为您永远不会测试一个矩形在这里,而另一个矩形在远处的任何对


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

好吧,我会尝试一下。真正的问题确实是如何找到矩形的排列,使得给定它们的成对相交,星系中没有相交的矩形原始集。有没有比我的最大独立集更快的方法?我不确定你所说的矩形排列是什么意思。你是通过对一些种子值进行排列来创建矩形的吗?我不相信除了两两之外还有其他方法来进行矩形交合。也许你可以使用矩形面积/空间区域来实现它ccupies(如果您知道如何标记它)并将其添加到映射中。然后再次循环所有矩形,查看它们是否“匹配”该映射中的任何区域(它们自己的区域除外)。列表排序后不需要成对。您可以利用此属性编写O(N日志(N))碰撞检查!它工作得很好,我按照扫描线算法的精神实现了它。这是逻辑:I=0,S={},N=| R | while(i@linello这正是应该做的;但我看到你也在做成对排列……除非我不理解成对排列的正确含义。你在一个接一个地比较矩形,看它们是否相交。这不是“一对”吗或者矩形?是的,这实际上是成对的,但通过这种方式,我可以利用矩形在其x坐标上排序的事实来避免双重嵌套的for循环。成对比较很难避免。我知道有很多解决方案。我用一个简单的随机化算法取一个最大独立子集,因为找到最大值对于这个任务来说,最小独立子集的计算量太大,我不需要它。@Adrian:在这种情况下,所有“非相交”矩形的有效排列是或{A,C}或{B,D}