路径规划算法进阶

路径规划算法进阶

    最早是在大学期间学习路径规划算法,严蔚敏_吴伟民的《数据结构》讲的最短路径。当时感到有些晦涩难懂,并没有理解算法思想。回头看,主要是因为应付考试,没有和实际应用场景建立连接,所以体会不深。毕业后,因为从事地图有关工作,又想到这些内容,然后复习、研究,总算明白其中道理。这些算法能解决我们生活中遇到的实际问题,所以感到其价值很大。

   原本早就想把路径规划算法做个总结,想把用到的典型路径规划算法从头到尾梳理一遍,后来发现越写越大,结构因此变得臃肿而混乱。而且,这些算法的原理、实现步骤、使用场景等等都可以在网上找到,故茅塞顿开,何必再去重复做这些东西呢,既然很多资料已经很丰富,我再洋洋洒洒罗列一大堆,实在没啥意义。因此,我改变思路,想结合这几年工作经验,把一些对算法的理解、体会写出来,兴许能给需要的人一些些帮助。

   这次,我主要分享三个典型算路算法。从算法原理到简单应用,再到系统应用,体现的是不同使用阶段,所以这篇文章题为“进阶”。有关公式推导和示例代码请自行查阅其他资料。

  • 迪杰斯特拉算法----经典

迪杰斯特拉算法是典型的最短路径算法,用来计算一个节点到其他各节点的最短路径,解决有权图的最短路径问题。“权”可以指代距离、费用、时间、拥堵等。

对于图G,也即路网,建立集合S和U,并使起点为v0。S中存放的是G中已求出最短路径的节点,即,该集合从v0到其他节点的最短路径均已确定,也可以理解成被访问过节点的边界范围;U中存放的是G中还没有求出最短路径的节点。将S中节点按路径长度由短到长进行排序。接下来就要通过遍历方式找到下一个从起点v0到U集合中存在最短路径的一个节点,判断的规则是从S中路径短的节点开始,找到其与U中所有直接相连的节点,计算v0到这些节点的路径长度,选定长度最短的节点v。这里要注意,找到v并不一定表示这就是v0到v的最短路径,还要计算S中是否还有其他节点连接到v,如果有,则计算路径长度,并与前面找到的路径长度对比,如果长度比之长,则直接把v从U移到S,否则,选定该路径为v0到v的最短路径,并把v从U移到S。通过不断遍历前进,知道把U中所有节点转移到S中,算法结束,至此,从v0到G中其余各节点的最短路径均已产生。

上述过程描述可能不直观,同学可以网上查阅其他材料,借助图文解释更容易理解。算法的核心思想是从指定点开始,逐个扩散到与其相连节点,并判断所有遍历过的节点中是否有到达该点的更短距离,并以此为起点继续扩散。因此,迪杰斯特拉算法采用广度优先策略,是一种典型的贪心算法。

很多同学在求最短路径时都是从学习迪杰斯特拉算法开始的,如同路径规划界的启蒙教育,所以它是一个非常经典的算法。但是,由于算法计算过程中需要遍历各节点,导致效率低,所以比较适合在数据量小的静态场景中使用,而难以在工程上实用。

                                                                        路径规划算法进阶_第1张图片

 

  • A星(A-Star----潇洒

迪杰斯特拉算路采用广度优先策略,是一种无序搜索,这样做了很多无用功。如何变得聪明些呢?

先说说BFS(最佳优先搜索)。BFS用了启发式函数,可以评估出当前点到终点的代价,它关注的是终点的位置。比如,终点在当前点东北方向,BFS会沿着这个方向前进。如果这条路上没有障碍,BFS会很快到达终点,但如果路上有严重障碍,BFS依然会朝这个方向走,直到遇到障碍才做出避让。因此,BFS可能找不到最短路径,但是计算很快,迪杰斯特拉可以找到最短路径,但是计算慢。

A-Star吸收了迪杰斯特拉和BFS算法各自有点,即能算出最短路径,又可以加快计算速度。这其中的关键是引入了代价函数:F(n) = G(n) + H(n),G(n)表示节点n到起点的代价,H(n)表示n到终点的代价。G可以精确算出,H可以理解为启发函数。A-Star算路时,根据F评判n节点是否为最短路径节点。判断的逻辑和迪杰斯特拉算法相同,只是把最短路径的评判依据改为F。引入代价函数,算法可以动态衡量已经花费的代价和预计代价,然后根据总代价最小原则找到最短路径。可以看出,当G值更大时,A-Star更像迪杰斯特拉算法,当H更大时,A-Star更像BFS,所以设计准确的代价表达是能否又快又准计算出最短路径的关键。

工程应用时,常常采用双向A星算路,同时从起点和终点出发,进行对向算路,当双方相遇时,即表示得到一条合适结果。举个形象的比喻:算路的查询过程就像散开的树,距离越长,树越大(如果F函数定义准确,搜索范围偏差并不大);采用双向算路就像散开的两颗小树,两颗小树的范围加起来不会大于一颗大树,原因就是在可能扩大搜索范围时两者就相遇了,因此双向算路比单向算路更快,达到1+1>2的效果。

详情参考:http://theory.stanford.edu/~amitp/GameProgramming/

                                                                         路径规划算法进阶_第2张图片

 

  • 加速算法----力士

        Star算法已经比较聪明了,但是在大规模工程应用中就显得单薄了,比如用于导航算路的全国地图数据,道路里程在百万公里量级,其拓扑信息是千万级,规模极其庞大,如果还要A-Star算路,一旦距离很长,比如从北京到广州,算路过程会消耗很长时间,这是灾难性的体验。然而,我们在用各种互联网地图服务时,并没有明显感觉到因距离长短导致算路时长的变化。这其中关键是做了算法加速!

       加速算法有很多,典型的如CH算法(Contraction Hierarchies)、HH算法(Highway Hierarchies)、CRP算法(Customizable Route Planning),文末提供相关文章下载链接。

      以CH为例,将所有节点按重要程度预先生成一个多层结构,按优先级由低到高排序,形成金字塔形。比如,从北京某地开始到天津某地结束,进行路径规划时,可以先从起点算到北京高速入口,采用双向搜索方式,从终点算到天津高速入口,而北京到天津的这段高速路是提前算好的,所以这个过程就变成了计算起点到北京高速入口及终点到天津高速入口,然后再直接读取这段高速历程,这样就加快了算路速度。这里的核心是通过预处理计算出北京到天津存在的这条关键路径(不一定最短,比如考虑实时路况),两地算路时可直接调取。这两个高速出入口就是收缩后的高等级节点。也可以得出,低等级节点首先向高等级节点拓扑,再通过高等级节点进行拓扑计算。高等级节点数明显减少,其拓扑关系并不复杂,所以可以实现长距离算路。

      如何判断该收缩哪些节点呢?一个直观的理解是:去掉这个节点后,会不会影响两点间最短路径,如果不影响,这个点就可以被收缩掉。实际计算中会判断边的差分等等。

     以上就是算法加速的思想,非常符合我们日常认知,试想,我们长距离出行首先会选择走高速,而不是先拿各种乡县省道进行距离量算比较一番,然后再决定走哪条路。一定程度上,它是拿空间换取时间策略。当然,这仅仅是算法加速,为了提高响应速度,实际应用中,各家图商还会对数据做编译,手机流量约束,集群环境等等。

下载链接:https://pan.baidu.com/s/1j19rxiWHY9ojTENWs5hfDg

提取码:4dyc

                                                                          路径规划算法进阶_第3张图片

你可能感兴趣的:(路径规划算法进阶)