给定2D空间中的一组不同点,以及一个矩形(所有四个点的坐标,与xy轴平行的边),如何快速找到矩形内的哪些点?
我对通过所有点并看到哪个点位于矩形内的基本解决方案不感兴趣。我正在寻找的算法是每个矩形的快速查询时间。
我不在乎我在预处理步骤中花费了多少时间。我所关心的是,在处理完数据之后,我获得了一个有用的结构,它为每个矩形提供了快速的查询时间。
我知道例如我可以计算O(logN)中矩形内有多少个点。这是有效的,因为我在开始时做了很多繁重的处理,然后每次用新的矩形查询处理过的数据,并在logN时间内得到一个新的计数。我正在寻找一种类似的算法来查找实际的点,而不仅仅是它们的数量。
答案 0 :(得分:8)
经典答案是kD树(在这种情况下是2D树)。
对于一个简单的替代方案,如果你的点分布足够均匀,你可以尝试网格化。
为方形网格选择单元格大小(如果问题是各向异性的,请使用矩形网格)。将每个点分配给包含它的网格单元,存储在链表中。执行查询时,查找与矩形重叠的所有单元格并扫描它们以遍历其列表。对于部分覆盖的单元格,您需要执行矩形点测试。
尺寸的选择很重要:太大会导致需要测试太多的点;太小会导致太多空单元格。
答案 1 :(得分:3)
您正在寻找kd-tree range search或范围查询。
O(n)
,但这是最坏的情况经常发生。所有这些算法以平均O(log n + k)
运行查询,其中k是匹配点的计数。
与Yves建议的一样,网格化可以在O(k)
时间内执行范围搜索,但仅限于查询矩形的大小有界时。这是他们在particle simulations中经常做的事情。即使输入集没有限制,也可以使用网格化 - 只需根据网格坐标的哈希值对固定数量的桶进行计数。但是如果查询矩形可以是任意大小,那么网格化是不行的。
答案 2 :(得分:1)
您可以将点数分组。如果扇区完全在给定矩形内或外,则其中的所有点也在内或外。如果扇区部分存在,则必须在O(n)中搜索该扇区中的点以检查它们是否在矩形中。寻找k-d tree搜索。
答案 3 :(得分:1)
除了其他答案,您还可以查看莫顿代码(z顺序曲线排序)。
在您的情况下,即静态数据,您甚至可以将整个点数据表示为数组。
https://en.wikipedia.org/wiki/Z-order_curve
本文还有一个相当复杂的不同“多维访问方法”的时间表 - http://www.cc.gatech.edu/computing/Database/readinggroup/articles/p170-gaede.pdf
答案 4 :(得分:0)