具有动态点的二维最近邻查询算法

时间:2017-09-17 21:49:32

标签: algorithm data-structures 2d computational-geometry nearest-neighbor

我正在尝试找到一种快速算法,用于在二维空间中找到给定点的近似(近似,如果需要),其中经常从数据集中删除点并添加新点。

(相关地,我感兴趣的是这个问题的两个变体:一个可以被认为是随机添加和删除的点,另一个是所有点都在不断运动的颜色。)

一些想法:

  • kd-trees提供了良好的性能,但仅适用于静态点集
  • R * -trees似乎为各种维度提供了良好的性能,但其设计的一般性(任意维度,一般内容几何)表明更具体的算法可能提供性能优势的可能性
  • 优先使用现有实现的算法(尽管这不是必需的)

这里有什么好选择?

2 个答案:

答案 0 :(得分:2)

检查Bkd-Tree,即:

  

基于kd-tree的I / O高效动态数据结构。 [...] Bkd树保持其高空间利用率和优秀   查询和更新性能,无论对其执行的更新次数如何。

然而,这种数据结构是多维的,并不专门用于较低的维度(如kd树)。

bkdtree中播放。

Dynamic Quadtrees也可以是候选者,具有O(logn)查询时间和O(Q(n))插入/删除时间,其中Q(n)是时间 在所使用的数据结构中执行查询。请注意,此数据结构专用于2D。然而,对于3D,我们有八叉树,并且以类似的方式可以将结构推广到更高的维度。

实施是QuadTree

R*-tree是另一种选择,但我同意你的一般性。还存在r-star-tree个实现。

也可以考虑Cover tree,但我不确定它是否符合您的描述。阅读更多here,并检查CoverTree上的实施情况。

Kd-tree仍然应该被考虑,因为它在2个维度上的表现非常出色,并且其插入复杂度的大小也是对数。

nanoflannCGAL是jsut的两个实现,其中第一个不需要安装而第二个需要安装,但可能性能更高。

无论如何,我会尝试多种方法和基准测试(因为它们都有实现,而且这些数据结构通常受数据的性质影响)。

答案 1 :(得分:2)

我同意(几乎)@gsamaras所说的所有内容,只是为了添加一些内容:

  • 根据我的经验(使用> = 500,000点的大型数据集),KD-Trees的kNN性能比其他任何空间索引差10到100倍。我测试了它们(2个KD树)和大型OpenStreetMap数据集上的各种其他索引。在下图中,KD-Trees称为KDL和KDS,2D数据集称为OSM-P(左图):enter image description here该图取自this document,请参阅下面的要点以获取更多信息信息。
  • This research描述了一种移动对象的索引方法,以防您在稍微不同的位置保持(重新)插入相同的点。
  • 四叉树也不是太糟糕,它们可以在2D中非常快,对数据集具有出色的kNN性能< 1,000,000个条目。
  • 如果您正在寻找Java实现,请查看我的index library。 In具有四叉树,R-star-tree,ph-tree等的实现,所有这些都具有也支持kNN的通用API。该库是为TinSpin编写的,它是一个用于测试多维索引的框架。可以找到一些结果enter link description here(它并没有真正描述测试数据,但'OSM-P'结果基于OpenStreetMap数据,最多有50,000,000个2D点。
  • 根据您的情况,您可能还需要考虑PH-Trees。它们对于kNN查询而言似乎比低维度中的R * -Trees慢(尽管仍然比KD-Trees快),但是它们比R *树更快地移除和更新。如果你有很多删除/插入,这可能是一个更好的选择(参见TinSpin results,图2和46)。可以使用C ++版本enter link description here