Algorithm 什么算法计算地图上从A点到B点的方向?

Algorithm 什么算法计算地图上从A点到B点的方向?,algorithm,path-finding,Algorithm,Path Finding,地图提供商(如谷歌或雅虎地图)如何建议方向 我的意思是,他们可能有某种形式的真实数据,当然包括距离,但也可能包括行驶速度、人行道的存在、火车时刻表等。但假设数据的格式更简单,比如一个非常大的有向图,边权重反映距离。我希望能够快速计算从一个任意点到另一个任意点的方向。有时这些点会很近(在一个城市内),而有时它们会相隔很远(越野) 像Dijkstra算法这样的图算法将无法工作,因为图是巨大的。幸运的是,像A*这样的启发式算法可能会起作用。然而,我们的数据是非常结构化的,也许某种分层方法可以工作?(例

地图提供商(如谷歌或雅虎地图)如何建议方向

我的意思是,他们可能有某种形式的真实数据,当然包括距离,但也可能包括行驶速度、人行道的存在、火车时刻表等。但假设数据的格式更简单,比如一个非常大的有向图,边权重反映距离。我希望能够快速计算从一个任意点到另一个任意点的方向。有时这些点会很近(在一个城市内),而有时它们会相隔很远(越野)

像Dijkstra算法这样的图算法将无法工作,因为图是巨大的。幸运的是,像A*这样的启发式算法可能会起作用。然而,我们的数据是非常结构化的,也许某种分层方法可以工作?(例如,在相距较远的某些“关键”点之间以及某些局部方向之间存储预计算的方向。然后,两个较远点的方向将涉及到到一个关键点的局部方向、到另一个关键点的全局方向,然后再是局部方向。)

实际使用的算法是什么

这个问题的动机是发现在线地图方向的怪癖。与三角形不等式相反,有时谷歌地图认为这比使用中间点(如中所示)需要更长的时间和更远的距离。但也许他们的行走方向也优化了另一个参数

PPS。这是另一个违反三角不等式的情况,它(对我来说)表明他们使用某种分层方法:对。前者似乎使用了著名的塞巴斯托波尔大道,尽管它有点偏僻


编辑:这两个例子似乎都不起作用了,但在最初发表文章时两者都起作用了。

这纯粹是我的猜测,但我想他们可能会使用影响图数据结构覆盖定向图,以缩小搜索范围。这将允许搜索算法在所需行程较长时将路径指向主要路线

考虑到这是一个谷歌应用程序,我们也可以合理地假设大量的魔法是通过广泛的缓存实现的如果缓存前5%最常见的GoogleMapRoute请求允许通过简单的查找来回答大量(20%?50%?)请求,我不会感到惊讶

像Dijkstra算法这样的图算法将无法工作,因为图是巨大的

这个论点不一定成立,因为Dijkstra通常不会看完整的图,而只是看一个很小的子集(图的连通性越好,这个子集就越小)

Dijkstra实际上可能在表现良好的图中表现得相当好。另一方面,经过仔细的参数化,A*的性能总是一样好,甚至更好。您是否已经尝试过它在您的数据上的表现


也就是说,我也很想听听其他人的经历。当然,像谷歌地图搜索这样的突出例子特别有趣。我可以想象有向最近邻启发法。

我看到了OP中的地图是怎么回事:

查看指定了中间点的路线:由于道路不直,路线稍微向后移动


如果他们的算法不回溯,它就看不到更短的路线。

作为一个在地图公司工作了18个月的人来说,这包括在路由算法方面的工作。。。是的,确实有效,但需要进行一些修改:

    不要从源头到第二次做一次,你从两端开始,扩大两边,直到它们在中间相遇。这大约消除了一半的工作量(2*pi*(r/2)^2与pi*r^2)
  • 为了避免探索源地和目的地之间每个城市的后巷,可以使用几层地图数据:只包含高速公路的“高速公路”层,只包含次要街道的“次要”层,等等。然后,只探索更详细层的较小部分,并根据需要展开。显然,这个描述遗漏了很多细节,但你明白了

按照这些思路进行修改后,您甚至可以在非常合理的时间范围内进行跨国路由。

这一问题在过去几年中一直是一个活跃的研究领域。主要思想是对图形进行一次预处理,以加速所有后续查询。有了这些额外的信息,可以非常快速地计算出行程。尽管如此,Dijkstra的算法是所有优化的基础

Arachnid描述了基于层次信息的双向搜索和边缘修剪的用法。这些加速技术工作得很好,但最新的算法在所有方面都优于这些技术。使用当前算法,在大陆道路网络上,计算最短路径的时间比一毫秒要短得多。快速实现未经修改的Dijkstra算法需要大约10秒

本文概述了该领域的研究进展。有关更多信息,请参阅该文件的参考资料

已知最快的算法不使用数据中有关道路层次状态的信息,即如果是公路或本地道路。相反,他们在预处理步骤中计算自己的层次结构,从而优化以加快路线规划。这种预计算可以用来删减搜索:在Dijkstra的算法中,不需要考虑远离起点和终点的慢行道路。这些好处是非常好的性能,并为结果提供了正确性保证

冷杉
f(n) = k*h(n) + g(n)