由于kd-tree最近邻搜索中的最大半径而导致意外减速

时间:2015-02-16 10:22:49

标签: r algorithm

我正在使用kd-tree算法(found here)来查找矩阵1中相对于矩阵2中所有点的点的最近邻点。上面链接的算法非常快,能够找到使用

在约20秒内使用3E6最近邻居
nn2(SetA,SetB,k=1)

现在,我只想在彼此的某个半径范围内包含最近的邻居,所以我尝试了

nn2(SetA,SetB,k=1,searchtype='radius',radius=1000)

哪种方法运行良好,但令人难以置信的减慢计算速度,实际上是数量级(因数1000或更多)。我不明白为什么会发生这种情况,因为我认为最大半径的方式实际上应该减少计算时间,因为不是必须扫描整个空间。

有人可以解释出现了什么问题吗?或者为什么这是预期的行为?

重现行为的示例代码

library(data.table)
library(RANN)
N=50000
DT1=data.table(x=sample(0:300,N,replace=T),y=sample(301:600,N,replace=T))
DT2=data.table(x=sample(0:300,N,replace=T),y=sample(301:600,N,replace=T))

ptm=proc.time()
nnlistV1=nn2(DT1,DT2,k=1)
proc.time()-ptm

ptm=proc.time()
nnlistV2=nn2(DT1,DT2,k=1,searchtype="radius",radius=20)
proc.time()-ptm

1 个答案:

答案 0 :(得分:1)

来自ANNmanual

  

因为它访问了搜索半径中的所有点   如果数字一个接一个,搜索过程效率很低   半径范围内的点数很大。

我没有查看所有代码,但annkSearch是您的第一个nn2最终调用的标准代码,annkFRSearch(FR = Fixed Radius)是上面提到的慢代码。半径版本不是标准的约束,它完全不同。

运行它表示"半径范围内的点数很大"当试图找到k = 1时。

nrow(DT1[DT1$x >= 130 & DT1$x <= 170, ])
[1] 6711

运行一个更适合固定半径搜索的问题,其范围更加分散,并且k大于1但略小于该范围内可能出现的点:

N=50000
DT1=data.table(x=sample(0:30000,N,replace=T),y=sample(301:60000,N,replace=T))
DT2=data.table(x=sample(0:30000,N,replace=T),y=sample(301:60000,N,replace=T))

nrow(DT1[DT1$x >= 130 & DT1$x <= 170, ])
# I got 70 on my random sample
ptm=proc.time()
nnlistV1=nn2(DT1,DT2,k=50)
proc.time()-ptm

ptm=proc.time()
nnlistV2=nn2(DT1,DT2,k=50,searchtype="radius",radius=400)
proc.time()-ptm

你的代码给了我时间.11和1.81。根据上述变化,我得到的标准和半径分别为.69和.28。