我正在寻找一种更有效的算法来匹配两个列表之间的坐标。
给出两个带有纬度/经度值的列表。我的目标是为第一个列表中的每个坐标找到给定半径中另一个列表中的所有匹配坐标,例如500米。
现在,它只是被两个for循环强行使用,仅计算距离并检查每个坐标的距离是否在我的半径之内。但这使我陷入了O(n²)的复杂性。
为了改善这一点,我的第一个想法是做类似于Hashmap的操作: 通过在末尾删除一些小数,将第一个列表分类为更大的“字段”。一个例子是:
因此创建了一些“组”坐标。 现在,我只需要遍历第二个列表一次,然后查看特定坐标位于哪个组中,并使用该组中的所有坐标进行计算。 在视觉上,您可以描述在地图中创建作为我的哈希的正方形的想法。然后首先查看当前坐标位于什么哈希中,并将该哈希中的所有坐标与当前坐标进行比较。
像这样,我可以将复杂度从O(n²)降低到O(n + m *(average_size_of_groups)) 如果坐标位于某个组的边界,我也需要检查该组的邻居。
但是我相信以某种方式可以更有效地匹配这两个列表。我一直在寻找可解决此类问题的算法,但我的Google搜索未成功。
非常感谢:)
答案 0 :(得分:0)
您的算法相当不错,但是您的小组的最佳规模比您想像的要小,这意味着您进行了太多的比较。
您应该将点划分为与半径大小相同的正方形,而不是仅仅舍去小数位。
然后将每个点与其所属的点和8个相邻的点进行比较。
答案 1 :(得分:0)
这种事情的常见优化是对点数组进行预处理,并创建一个二维的“存储桶”数组,每个存储桶都包含一个点列表。一个维度是纬度,而其他是经度。如果您想要500米的粒度,那么每个存储桶都代表一个500x500米的正方形。
您将需要一种将纬度/经度值映射到矩阵的x / y值的方法。您可以决定对应于0,0矩阵平方的纬度/经度。然后,要计算任意点的纬度/经度,请减去偏移量(纬度/经度从0,0开始),然后将纬度和经度转换为米。然后将它们除以500,然后将点放入结果存储桶中。
这当然有些棘手,因为经度之间的距离取决于纬度,如https://gis.stackexchange.com/questions/142326/calculating-longitude-length-in-miles中所述。
现在,当有人说“给我奥斯丁500米以内的所有点”时,您可以获得奥斯丁的经/纬度,如上所述转换为存储桶坐标,然后将其与该存储桶中的所有点进行比较以及周围的8个水桶。
数组的大小是纬度范围,转换为米并除以500,再乘以经度范围,也转换为米并除以500。
大约40,100 km的地球周长为您提供了该阵列的最大估计尺寸:80,200 x 80,200,如果您想让桶长为500米,则大约为64.32亿个桶。如果要覆盖这么大的范围,则可能需要使用稀疏矩阵表示。