如何快速找到3个或更多个维度中与飞机最近的k个点

问题描述

我需要快速找到3个(或更多个)维度中距平面(或超平面)最近的k个点。是否存在使用某种聪明的数据结构(类似于kd-tree对k个最近邻居的工作方式)执行该搜索快速方法

我知道我可以旋转平面和所有点,以使平面正交于其中一个轴,然后仅通过使用该轴上的坐标来测量每个点到平面的距离。但是,这种蛮力方法的时间复杂度是O(N),其中(N)是点数。由于我必须找到大量平面和大量点的k个最近邻居,因此,如果可能,我需要找到一种更快的算法。

解决方法

通过使用具有超平面法线的点积来测量距离...所以让:


n-是超平面法线单位向量
p0-是超平面上的任意点
p[i]-是您的Pointcloud i={ 0,1,2...n-1 }的第i点

那么到超平面的距离是:

d = |dot( p[i] - p0,n )|

,如您所见,无需任何昂贵的操作就无需变换/对齐任何内容及其O(1)。我希望在大多数情况下,任何预先排序的点或使用巧妙的结构都比这要慢...

现在您有2个选择,要么为每个点计算d,然后进行快速排序,这将导致O(n.log(n))时间和O(n)空间复杂度。

或者记住跑步中k个最接近的点,这些时间导致O(k*n)个时间和O(k)个空间。

因此,如果k很小(k < log(n)),或者您没有足够的内存来备用,请使用第二种方法,否则请使用第一种方法。

,

我认为您可以简单地使用任何支持自定义距离功能的空间数据结构(kd-tree,R-tree等)。您应该能够定义一个距离函数,该函数仅使用到平面的距离而不是到中心点的距离。

@Spektre描述了如何计算此距离。

我不知道它如何扩展,因为它可能取决于实现所使用的kNN搜索算法。 但是,我相信标准算法(Hjaltason和Samet:“在空间数据库中进行距离浏览”。)至少应优于O(n)。

如果您使用的是Java,我的TinSpin库中的R-Tree,Quadtree和PH-Tree索引都使用此算法。