适用于2D中快速k-最近邻搜索的数据结构和算法

时间:2010-10-15 17:38:22

标签: algorithm performance nearest-neighbor

我有一个大约100,000(X,Y)对的数据集,代表2D空间中的点。对于每个点,我想找到它的k个最近邻点。

所以,我的问题是 - 假设我想绝对最小化整体运行时间,那么哪种数据结构/算法是合适的选择?

我不是在寻找代码 - 只是指向合适方法的指针。我对一些似乎相关的选择感到有些畏惧 - 四棵树,R树,kd树等等。

我认为最好的方法是构建一个数据结构,然后为每个点运行某种k-Nearest Neighbor搜索。但是,由于(a)我事先知道了这些要点,并且(b)我知道我必须完全搜索每一点,或许还有更好的方法?

一些额外的细节:

  • 由于我想最大限度地缩短整个运行时间,我不在乎大部分时间花在结构与搜索上。
  • (X,Y)对分布相当均匀,因此我们可以假设几乎均匀分布。

1 个答案:

答案 0 :(得分:7)

如果k相对较小(<20左右)且分布大致均匀,则创建一个覆盖点落差范围的网格,选择此网格以使每个网格的平均点数明显高于k (因此,位于中心的点通常会在该一个网格点中获得其k个邻居)。然后创建一组其他网格,从第一个(重叠)沿每个轴设置半个。现在对于每个点,计算它落入哪个网格元素(因为网格是常规的,不需要搜索)并选择具有最接近其中心的点的四个(或者多个重叠网格)中的一个。

在每个网格元素中,点应该在一个坐标中排序(比方说x)。从您选择的元素开始(使用二分法找到它),沿着排序列表向外走,直到找到k个项目(同样,如果k很小,维护k个最佳命中列表的最快方法是使用二进制插入排序,当你插入时,让最差的匹配结束;插入排序通常比现代硬件上的大约30个项目更好。继续前行,直到离你最近的最近邻居比你离x的下一个点更近(即不计算它们的y偏移量,所以可能没有新点可能比目前为止最近发现的k点更接近)

如果你还没有k点,或者你有k点,但是网格元素的一个或多个墙壁比k点的最远点更接近你的兴趣点,那么在搜索中添加相关的相邻网格元素

这应该可以为您提供类似O(N*k^2)的性能,具有相对较低的常数因子。如果k很大,那么这个策略太简单了,你应该选择k中线性或对数线性的算法,就像kd-tree一样。