查找包含点的矩形 - 高效算法

Posted

技术标签:

【中文标题】查找包含点的矩形 - 高效算法【英文标题】:Find rectangles that contain point – Efficient Algorithm 【发布时间】:2012-04-22 15:20:53 【问题描述】:

下午好。

我的情况:

二维空间输入:一组矩形(也有重叠的矩形)。 矩形坐标是整数类型。 矩形大小和矩形位置没有任何限制(仅整数范围)。 没有宽度=0 或高度=0 的矩形。 我需要找到:所有包含输入的(带有整数坐标)的矩形。

问题:

保持矩形的有效结构是什么? 什么算法在这种情况下是有效的? 什么算法只对添加矩形而不删除有效?

谢谢:-)。

【问题讨论】:

对点的位置、矩形的大小或位置是否有任何限制?该点可以在任何(浮点)位置,还是仅在固定网格上?矩形可以有最小和最大尺寸吗? 谢谢,我会编辑问题。 也相关 - ***.com/questions/16583908/… 【参考方案1】:

R-Tree 是最适合此用例的数据结构。 R-trees 是用于空间访问方法的树数据结构,即用于索引地理坐标等多维信息,矩形或多边形。所有矩形的信息都可以以树的形式存储,搜索起来很容易

Wikipedia 页面、short ppt 和 research paper 将帮助您理解这个概念。

【讨论】:

非常感谢 :-),我会试试的。 @Nanik 你试过了吗?如果您遇到任何问题,请让我知道。几年前我已经对其进行了编码,可以帮助你。 @TejasP 我一直在努力。谢谢你的提议:-)。 我想知道段树。在这种情况下,R 树是否比分段树更好? 来自***页面:“即使数据可以放入内存(或缓存),大多数实际应用程序中的 R-tree 通常会在对象超过几百个左右。但是,对于内存应用程序,有类似的替代方案可以提供稍微更好的性能或在实践中更易于实现。听起来 R-tree 对于内存或较小的数据集来说可能是多余的。知道在这种情况下哪种算法(除了蛮力)可能更好吗?【参考方案2】:

在 java 中你可以使用 shape.contains

但一般来说,假设一个矩形是由 (x,y,width,height) 定义的

如果 (pt.x >= x && pt.x = y && pt.y

如果您将所有矩形都放在一个集合中,您可以遍历该集合并找到包含该点的矩形

【讨论】:

谢谢:-)。我用 C++ 编写它。我想有数千个矩形,我不想单独检查每个矩形。也许是某种排序结构。 实际上在数千个矩形上使用这种算法在今天的计算机上应该不是一个处理问题。这个数学公式将执行得非常快。尝试排序有点问题 - 您将如何对矩形进行排序? 我正在考虑一些二叉树 - 按左角 x 坐标排序。然后我只检查输入点 x 坐标左侧的矩形。使用平衡树,我可以节省大约一半的检查时间。这样对吗?我正在寻找有效的解决方案... 是的,应该可以。节省的处理时间取决于您的数据。但是假设随机点大约一半是正确的【参考方案3】:

您的矩形集似乎是动态的(“...用于添加矩形...”)。在这种情况下 - 2D Interval tree 可能是解决方案。

【讨论】:

感谢您的回复 :-)。【参考方案4】:

这是一个简单的解决方案。

    在您的平面上定义一个网格。 每个单元格维护两个列表:完全覆盖该单元格的矩形和部分覆盖该单元格的矩形。 在每次插入时,将目标矩形的 ID 放入所有涉及的单元格列表中。 在每个查询中,找到包含目标点的单元格,输出完全覆盖列表并在部分覆盖列表上运行扫描。

【讨论】:

在网格组装好后进行快速搜索。但是,根据网格的分辨率,向其中添加一堆巨大的矩形似乎会非常慢。 @cHao 没错,只有当矩形大小相似时才理想【参考方案5】:

一个矩形(left, top, right, bottom) 包含一个点(x, y) 如果left < x < right top < y < bottom(假设坐标向下增加,这是我见过的大多数硬件的情况;如果你坐标向上增加,更传统的数学情况,交换topbottom)。你不会比测试更有效率。

如果您认为一个矩形“包含”一个点(如果它也在边界上),那么将所有 <s 替换为 <=

至于如何处理矩形集合...我不知道。我认为按角落坐标排序的列表会做一些事情,但我并没有真正看到它有多大好处......最多,你会平均将要检查的东西列表减少一半(最坏的情况仍然需要检查所有内容)。一大堆该死的一半仍然可以是一大堆。 :)

【讨论】:

谢谢:-)。我想有数千个矩形,我不想单独检查每个矩形。我正在寻找一些排序结构来仅获得可能的候选人。 不知道你是否能找到任何东西,没有预先计算带有预期测试点的列表。在这一点上,除非您多次测试相同的几个点,否则您并没有真正节省任何东西。任何想到的算法都会在巨大的矩形上产生误报。 正如你所写...我正在考虑一些二叉树 - 按左角 x 坐标排序。然后我只检查输入点 x 坐标左侧的矩形。使用平衡树,我可以节省大约一半的检查时间。对吗? 如果你的矩形分布均匀,可能。但是,当然,如果您要检查右侧/附近的一个点,您仍然需要检查所有内容。此外,您还要承担遍历和/或搜索树的成本。

以上是关于查找包含点的矩形 - 高效算法的主要内容,如果未能解决你的问题,请参考以下文章

无重叠的高效随机矩形放置

js需要一个查找一个数组中相同的元素算法。

生成包含多个 2D 点的矩形的快速算法

试编写在带头节点的单链表L中删除最小值点的高效算法(最小值唯一)

试编写在带头节点的单链表L中删除最小值点的高效算法(最小值唯一)

查找所有连接对之和的高效算法