有效地找到距另一点最近的点

Posted

技术标签:

【中文标题】有效地找到距另一点最近的点【英文标题】:Efficiently find closest point from another point 【发布时间】:2017-04-11 19:56:38 【问题描述】:

我有一个坐标列表 A(纬度,十进制形式的经度),大约 10.000 点,第二个相同类型的坐标列表 B,大​​约 100 万点。

我想为列表 B 中的每个元素找到列表 A 中的最近点。

我已经做的是创建两个列表的笛卡尔积并使用haversine公式找到所有组合的距离。

然后我得到列表 A 中的点,这些点与列表 B 中的每个点具有最小距离。

由于组合总数超过100亿,计算距离的时间太长。

有没有办法确保列表 B 中的每个点都匹配列表 A 中的一个点,同时提高性能?

【问题讨论】:

我会考虑在问题中添加更多细节。比如预期的最小距离是多少?覆盖面积有多大?球体的哪个部分? A 的大小是否固定(或多或少)?您需要精确的解决方案吗?依此类推……最简单的方法是在较小的列表上构建 kdtree,并使用它来映射 RDD。 【参考方案1】:

如果您已经创建了叉积并计算了所有的半正弦距离,那么您已经完成了大部分工作,所以我假设问题是如果您有新的集合 A 和 B 该怎么办。

为了反复找到 A 中的最近点,我会构建某种包含 A 中的点的树结构,并将信息存储在树的每个节点上,这相当于一个包围盒或包含其所有后代的等效物。然后当试图找到 A 中的最近点时,您递归搜索包含 A 的树,当您到达一个节点时从递归调用返回,您可以从存储在那里的信息中计算出它的所有后代都离目标点更远比迄今为止最接近的匹配。

要使此代码正常工作,边界框信息需要准确,但如果树很笨,它会减慢搜索速度,但不会阻止它们找到正确答案。这意味着,特别是,当您构建树时,您可以放心地忽略绕圈经度为 180W = 180E 的不便习惯。您可以假设 lat-long 是一个矩形网格并构建一棵 k-d 树,您可以将纬度和经度组合起来并对它们进行位交错并在结果上构建一维搜索树,您可以计算 https://en.wikipedia.org/wiki/Geohash 并构建一个基于此的搜索树,或者您可以计算很多harsines并构建一个https://en.wikipedia.org/wiki/Cover_tree - 所有这些都应该工作,我不知道哪个是最好的 - 这可能取决于您的数据和您可用的库。

【讨论】:

【参考方案2】:

spatstat 包中的 nncross 函数可用于从两个不同的数据集中查找点的距离。使用此函数将在很大程度上减少所花费的时间。 https://www.rdocumentation.org/packages/spatstat/versions/1.53-2/topics/nncross

【讨论】:

以上是关于有效地找到距另一点最近的点的主要内容,如果未能解决你的问题,请参考以下文章

找到两组矩阵之间最近的点对

最近的点对算法

用于比较来自 2 个不同数组的点的最近对算法

获取离质心最近的点,scikit-learn?

求一条线段上与两点最近距离的点的位置的方法是啥?求与两个固定点的距离相等的点的方法是啥?

找到离给定点最近的点