Algorithm 如何利用最近邻搜索算法进行固定半径搜索?
最近邻搜索问题有很多工作要做,所以我想知道如果我想做,我可以利用这些算法进行最近邻搜索吗Algorithm 如何利用最近邻搜索算法进行固定半径搜索?,algorithm,nearest-neighbor,range-query,Algorithm,Nearest Neighbor,Range Query,最近邻搜索问题有很多工作要做,所以我想知道如果我想做,我可以利用这些算法进行最近邻搜索吗 也许我可以反复进行第k个最近邻搜索,直到找到半径范围以外的点,但我认为这可能会造成大量浪费。如果只有一个查询,那么这个问题就解决了O(n),其中n是无论如何的点数 若你们有多个查询,那个么这个问题是一个探索性很强的问题,然而它的解决方案比最近邻搜索更复杂。请参阅本文:以d为尺寸数,以r为半径,我知道至少可以使用两种不同的方法: 使用空间散列: 想象一下问题空间被一个大小为s的网格划分成超立方体,这样s=r/
也许我可以反复进行第k个最近邻搜索,直到找到半径范围以外的点,但我认为这可能会造成大量浪费。如果只有一个查询,那么这个问题就解决了O(n),其中n是无论如何的点数
若你们有多个查询,那个么这个问题是一个探索性很强的问题,然而它的解决方案比最近邻搜索更复杂。请参阅本文:以
d
为尺寸数,以r
为半径,我知道至少可以使用两种不同的方法:
使用空间散列:
想象一下问题空间被一个大小为s
的网格划分成超立方体,这样s=r/sqrt(d)
关于s=r/sqrt(d)
的有趣之处在于,这种大小的超立方体中的任意两点都保证位于小于等于r
的距离
您可以计算网格划分,这样每个超立方体都可以通过其一个角的索引形成的元组来识别。这些索引元组可以用作散列结构(空间散列)的键
现在,这是困难的部分,你必须注意到,对于网格A
中的任何超立方体,都有一组相邻的超立方体N=(N1,N2,…)
,它们到给定超立方体的最小距离等于或小于给定半径,几何上看起来像一个超球体。您可以将集合N
的元素表示为与A
相关的网格索引的增量。请注意,这些索引增量仅取决于d
例如,在二维情况下,具有以下几何结构:
NNN index deltas: (-1, 2) ( 0, 2) ( 1, 2)
NNNNN (-2, 1) (-1, 1) ( 0, 1) ( 1, 1) ( 2, 1)
NNANN (-2, 0) (-1, 0) ( 0, 0) ( 1, 0) ( 2, 0)
NNNNN (-2, -1) (-1, -1) ( 0, -1) ( 1, -1) ( 2, -1)
NNN (-1, -2) ( 0, -2) ( 1, -2)
因此,您已经具备了对超球体内的点进行有效搜索所需的一切:
p
,搜索的方法是确定它所放置的超立方体a
,然后使用索引增量集,获得可能包含比r
更近点的相邻超立方体N
集
N
的点,并检查哪些点足够接近p
p
相对于A
的位置执行N的预过滤
请注意,选择s=r/sqrt(d)
在拥有小超立方体和不太大的集合N
之间提供了一个很好的折衷方案
使用k-d树或四元/octo/…-树:
每次在树上向下移动一层时,都会检查它所表示的空间是否与查询超球体相交。如果是这样,你就继续往下看,否则你就完全放弃搜索。不仅“最近邻搜索问题有很多工作要做”,而且你的问题还有很多问题要问。最重要的是维度的数量
如果您不确定尺寸为什么重要,请确保检查我的尺寸
高维空间 假设你的点位于一个高维空间中,你应该选择。这个算法的一个很好的实现是。如果您想自己实现它或更好地了解所发生的事情,它们还提供。注意,E²LSH解决了随机版本的R-近邻问题,他们称之为(R,1)− δ) -近邻问题,其中δ与近似值有关,正如他们在中提到的 你也可以检查我关于LSH的回答。我在C++中使用过它,我强烈推荐它用于你想要执行的固定半径搜索!
低维空间 使用CGAL的。对于C++中的这个例子,我已经使用过很多次了。同样,如果您想自己实现,您可以在他们的优秀文档中找到大量信息,并进行相关的谷歌查询
顺便说一句,答案很好,所以你得到了我的+1.:) 一个简单的解决方案是在sklearn.neights.KDTree中使用query_radius函数: 格式为:
query_radius(X, r, return_distance=False, count_only=False, sort_results=False)
在这种情况下,请参考那篇文章,它对可能的算法进行了广泛的分析。你必须检查所有要点,至少要看看它们的价值观是什么。这是暴力,你可以做得更好。Riko下次,当你回复一条评论时,你可能想标记另一个人,以便他收到通知。使用@otherguy@G.Samaras不,对于一个查询,你做得再好不过了,因为你需要在所有点上迭代一次,只需要得到它们的变量。这就是为什么建立索引会有帮助。请看我的答案。似乎使用网格是最快的方法,但是,我怀疑当搜索半径相对较小或维度较高时,它是否需要大量内存使用。最糟糕的情况是,当每个点都位于不同的超立方体中,并且以包含与点一样多的条目的空间散列结束时,会发生内存使用情况。因此,没有巨大的内存使用。另一方面,集合
N
的大小随维数呈指数增长,导致计算成本为O(f(M)*exp(d))
,其中M
是点数和f
一些待定函数。网格大小不应该设置为r
而不是Ofr/sqrt(d)
?因为使用r
只需在8个相邻的超立方体中加上