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

Posted

技术标签:

【中文标题】用于比较来自 2 个不同数组的点的最近对算法【英文标题】:Closest pair algorithm for comparing points from 2 different arrays 【发布时间】:2014-09-24 12:32:23 【问题描述】:

我想将一个数组中的点与另一个数组中的点进行比较,并找到最接近的对。到目前为止,我遇到的只是一个数组。我不想比较来自同一个数组的点。 蛮力算法有效,但速度太慢。 有没有使用分治法的算法或实现?

编辑 1:一个点被定义为地球表面上的一对(纬度,经度)。

【问题讨论】:

这里的point 是什么? (x,y) 二维空间中点的坐标还是? @PhamTrung 一个点被定义为地球表面上的一对(纬度,经度)。 其他人已经为您指出了如何有效地找到最近邻居的好方法。将经度/纬度对转换为空间点可能是个好主意,例如Earth-centred, Earth-fixed 坐标系,因为经度与距离的比率在所有纬度上并不是恒定的。 (您可以在最近邻搜索之前进行一次转换。) @MOehm 非常感谢。我将实现它并让你知道它是如何工作的。 如果您的搜索域被限制在一个相对较小的区域内,那么 lat/lng 值的失真可以忽略不计,您不必使用笛卡尔坐标。但是巴黎大约在 49°N,这意味着一个单位的经度只覆盖了大约 cos(49°) ~ 0.66 倍的同一纬度单位的距离。因此,我建议在您的距离计算中引入一个常数因子:d² = (a*lng)² + lat²,其中a = 1/cos(lat_m)lat_m 是您搜索域的平均纬度。 【参考方案1】:

您可以为第一个点数组构建一个 kd 树,然后使用该树为第二个数组的每个点从第一个数组中找到最近的点。它在平均 O(n log n) 上工作(n 是两个数组中最大的数组的大小)。要使用 kd-tree,您可以将初始坐标转换为 3D 空间坐标。

【讨论】:

感谢您的回答。我会实施它并回复你。 我有一个关于将纬度和经度转换为空间坐标的问题。如果我们正在处理像巴黎这样的小区域,是否有必要进行转换? @Lawrence 这取决于您需要的精度、点的距离等等。也许您可以尝试在有或没有转换的情况下运行它,看看是否有任何问题。 好的。我会试试看。谢谢。【参考方案2】:

您可以使用 kd-tree、octo tree、rtree、rtree*。 所有这些算法 O(log n) 来搜索最近点。 boost库中有一个rtree的实现

【讨论】:

但是 rtee 没有函数构建,只有插入(更慢)。我编写了我的实现,但现在它是如此原始。如果你愿意,你可以通过邮件给我写信,我可以把我的实现发给你。 我正在尝试使用 kd-tree。如果您不反对这个想法,将它与您的实现进行比较会很有趣。如果您允许我在哪里与您联系? 构建一棵树我使用就地计数排序。我们可以通过电子邮件联系。 chapaev28@ya.ru @ConstantineKuznetsov:这不是真的,可以以自上而下的方式创建 R-tree,例如来自一系列几何图形。它被称为批量加载或包创建,通常它也是“分而治之”算法,在本地执行“排序”,就像在 kd 树的情况下一样。特别是,Boost.Geometry R-tree 实现从 Boost 1.55 开始就支持这种方法。

以上是关于用于比较来自 2 个不同数组的点的最近对算法的主要内容,如果未能解决你的问题,请参考以下文章

最近的点对算法

dijkstra算法---通过边实现松弛

从顶点数组生成三角形网格的算法

分类 :kNN(k nearest neighbour)最近邻算法(Python)

最短路径算法专题2----Dijkstra

2016级算法第六次上机-E.Bamboo之吃我一拳