2D,C ++中的所有k个最近邻居

Posted

技术标签:

【中文标题】2D,C ++中的所有k个最近邻居【英文标题】:All k nearest neighbors in 2D, C++ 【发布时间】:2011-05-09 12:17:14 【问题描述】:

我需要为数据集的每个点找到它所有最近的邻居。数据集包含大约。 1000 万个二维点。数据接近网格,但没有形成精确的网格……

此选项排除(在我看来)使用 KD 树,其中基本假设是没有任何点具有相同的 x 坐标和 y 坐标。

我需要一个快速算法 O(n) 或更好的算法(但实现起来不太难:-)))来解决这个问题......由于 boost 没有标准化,我不想使用它...

感谢您的回答或代码示例...

【问题讨论】:

你能提供一个例子来说明你在寻找什么吗? Suitable choice of data structure and algorithm for fast k-Nearest Neighbor search in 2D的可能重复 我不太明白为什么你不能使用 kd-trees。我会总结一下我认为你在说什么:让我知道我哪里出错了。您有一组 10M 不同的点。它们不在整数网格上,但很接近,例如,有一个点 (2.01, 1.05) 和另一个 (1.99,1.03)。你不能缩放这些点,使它们都位于一个整数网格上,然后使用 kd-trees?例如,上面的 2 点可能是 (201,105) 和 (199,103)。 有些点在网格上,有些不在,其余的靠近网格... 【参考方案1】:

我会做以下事情:

    在点的顶部创建一个更大的网格。

    线性遍历这些点,并为每个点找出它属于哪个大“单元格”(并将这些点添加到与该单元格关联的列表中)。

    (这可以在每个点的恒定时间内完成,只需对点的坐标进行整数除法。)

    现在再次线性地遍历这些点。要查找最近的 10 个邻居,您只需查看相邻的较大单元格中的点。

    由于您的点分布相当均匀,因此您可以根据每个(大)单元格中的点数按比例执行此操作。

这是描述情况的(丑陋的)图片:

单元格必须足够大,以便(中心)和相邻单元格包含最近的 10 个点,但又要足够小以加快计算速度。您可以将其视为“哈希函数”,您可以在其中找到同一个存储桶中最近的点。

(请注意,严格来说不是O(n),而是通过调整较大单元格的大小,您应该足够接近。:-)

【讨论】:

不幸的是,不仅仅是相邻的(例如,考虑到单元格 2 中向东的点可能比单元格中正向东北的点更接近;这个问题在更高维度上会变得更糟)。另外,如果相邻单元格中的点恰好少于 10 个呢?在实践中,您将需要“盘旋”。 在这种特殊情况下不是:数据接近网格,但没有形成精确的网格......。通过选择足够大的单元格,您可以这样解决。 @Ian,听起来很像这种方法。 LHS、几何散列、四叉树、kd-tree、k-means 树、R-Tree 比您的算法更快。 所以你否决了我的答案,因为它不是最好的?【参考方案2】:

我使用了一个名为ANN(近似最近邻)的库并取得了巨大的成功。它确实使用了 Kd-tree 方法,尽管有不止一种算法可供尝试。我将它用于三角曲面上的点定位。你可能有一些运气。它是最小的,只需放入它的源代码就可以很容易地包含在我的库中。

祝这项有趣的任务好运!

【讨论】:

以上是关于2D,C ++中的所有k个最近邻居的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB实现K-近邻算法(源码)

KNN实现图像验证码识别

有没有办法使用用户定义的距离度量来选择 scikits 学习中的 k 个最近邻居?

R语言学习笔记—K近邻算法

机器学习:KNN算法Python实现

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