最近的顶点搜索

时间:2013-01-14 15:25:27

标签: algorithm data-structures nearest-neighbor kdtree closest-points

我正在寻找有效的算法来找到最接近点P(x,y,z)的顶点。顶点集合是固定的,每个请求都带有新的点P.我尝试了kd-tree和其他已知的方法,我到处都遇到同样的问题:如果P更接近那么一切都很好,只对几个树节点执行搜索。但是如果P足够远,那么应该扫描越来越多的节点,最后速度变得不可接受。在我的任务中,我无法指定一个小的搜索半径。这种情况的解决方案是什么?

由于 伊戈尔

2 个答案:

答案 0 :(得分:1)

加快搜索速度的一种可能方法是将空间离散成大量以规则间隔分开的矩形棱镜。例如,您可以将空间分成许多1×1×1个单位的立方体。然后,您将空间中的点分配到这些卷中。这为您提供了一种“散列函数”,用于将点分布到包含它们的卷中。

完成此操作后,请执行快速预计算步骤,并为每个卷找到最接近的非空卷。您可以通过检查距离卷一步的所有卷,然后两步之遥等来完成此操作。

现在,要进行最近邻搜索,您可以执行以下操作。首先将空间中的点散列到包含它的卷。如果该卷包含任何点,则迭代所有点以查找哪一个最接近。然后,对于您在此过程的第一步中找到的每个卷,迭代这些点以查看它们中的任何一个是否更接近。得到的最近点是测试点的最近邻居。

如果您的卷最终包含太多点,则可以通过将这些卷细分为更小的卷并重复此相同的过程来优化此方法。您也可以创建一堆较小的k-d树,每个卷一个,以进行最近邻搜索。通过这种方式,每个k-d树保持的点数比原始k-d树少得多,并且每个体积内的点都是最近邻居的合理候选者。因此,搜索应该更快,更快。

此设置在精神上类似于八叉树,除了您将空间划分为一堆较小的区域而不是八个。

希望这有帮助!

答案 1 :(得分:0)

嗯,这不是所使用的索引结构的问题,而是您的查询的问题:

离您的数据集越远,最近的邻居变得更加模糊。

所以我怀疑任何其他指数对你有多大帮助。

但是,您可以在搜索中插入阈值。即“找到最近的邻居,但只在最大距离x内。”

对于具有欧氏距离的静态,内存中,3-d点双向量数据,k-d树实际上很难被击败。它只是非常快速地分割数据。八叉树有时可能更快,但主要用于窗口查询我想。

现在,如果你真的只有很少的对象,但数以百万计的查询,你可以尝试做一些混合方法。大概是这样的:计算数据集的凸包上的所有点。计算中心和半径。每当查询点距离x倍时(您需要自己进行3d数学计算得出正确的x),它的最近邻居必须是凸包之一。然后再使用一个k-d树,但只包含一个船体点。

甚至更简单。找到每个维度中的最小/最大点。也许添加一些额外的极值(在x + y,x-y,x + z,x-y,y + z,y-z等)。所以你得到一小部分候选人。所以我们现在假设是8分。预先计算这6个点的中心和距离。设m是从中心到这8个点的最大距离。对于查询,计算到中心的距离。如果这大于m,则首先计算这6个候选中最接近的候选者。然后查询k-d-tree,但将搜索范围限制在此距离。这会花费您1(关闭)和7(远端邻居)距离计算,并且可以通过尽早提供好的候选人来显着加快您的搜索速度。为了进一步加速,也可以在k-d树中组织这6-26名候选人,以便快速找到最佳约束。

相关问题