点的第 k 个最近邻居的空间查询

Posted

技术标签:

【中文标题】点的第 k 个最近邻居的空间查询【英文标题】:Spatial querying for k-th closest neighbour of a point 【发布时间】:2018-02-11 07:00:57 【问题描述】:

我正在研究一种算法,该算法反复需要从某个给定查询点到第 k 个最近点的(欧几里德)距离,这些查询点全部取自点向量。此外,我反复需要找到一个点的给定半径内的所有点。

我正在考虑使用 nanoflann 库中的 k-d 树。但是, knnSearch() 函数返回所有 k 最近的邻居,我不需要。 (不过,radiusSearch() 函数很适合我)。

除了每次都遍历所有 k 个最近的邻居之外,有没有更有效的方法来获得我需要的东西?更好的数据结构还是更好的实现? (我使用的是 C++。)

【问题讨论】:

【参考方案1】:

我正在考虑使用 k-d 树

2D 或 3D 的绝佳选择。

k-d 树对于低维数据来说是一个不错的选择(我假设你已经有了,因为 nanoflann “主要针对 2D 或 3D 点云进行了优化。”)。

除了每次遍历所有 k 个最近的邻居之外,有没有更有效的方法来获得我需要的东西?

您需要第 k 个最近邻 (NN),但是在为 k 个 NN 搜索 kd 树时,代价高昂的操作(就时间而言)是找到第一个 NN(这需要您沿着树向下,所有从根到叶)。

查找第 2、第 3 或其他索引 NN 相对便宜,我高度怀疑它会损害性能(即从树返回的 k 个 NN 中取出第 k 个 NN 将成为瓶颈)。

所以,我强烈建议你不要担心这一步。

更好的数据结构还是更好的实现?

我不这么认为。我没有使用 nanoflann,但 CGAL 用于此类查询,值得一试(但是 CGAL 需要安装(不是小菜一碟),而 nanoflann 只是一个标题包含)。

【讨论】:

已知任何给定数据集的维度为 5 或更少。很高兴知道我不是代码瓶颈的原因。现在,我坚持使用 nanoflann 正是因为它是一个标头包含,并且只实现 k-d 树,这就是我所需要的。谢谢。

以上是关于点的第 k 个最近邻居的空间查询的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2648SJY摆棋子(kdtree)

KNN实现图像验证码识别

最近邻居 - k-d 树 - ***证明

Mongoose 地理空间查询查找所有包含给定点的用户球体

KNN-分类算法

K-近邻(KNN)算法