赞
踩
成功,没有捷径。
最短路问题是生活中比较常见的问题了,比如交通运输规划、出行线路规划等,都需要用到最短路算法。那么常用的最短路算法有哪些?它们分别是如何实现的?
我们不妨按照全局最短路、单源最短路和点对点最短路对算法进行分类如下:
全局最短路:Floyd
单源最短路:Dijkstra、Bellman-ford、SPFA
点对点最短路:DFS/BFS
Dijkstra算法 Dijkstra(迪杰斯特拉)算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,解决的是有向图中的单源最短路径问题。其基本思想是以起始点为中心,每次选一个距离起始点最近的点,然后扩展该点相连边相接的直达点,扩展点数-1次算法终止。注意,迪杰斯特拉算法无法计算带复权的图。算法流程图如下图所示,时间复杂度为O(V^2)。
Bellman-ford算法 该算法由美国数学家理查德•贝尔曼(Richard Bellman, 动态规划的提出者)和小莱斯特•福特(Lester Ford)发明,可以计算上述迪杰斯特拉算法无法计算的带复权的情形,能识别出复权回路。其算法思想分如下三步,时间复杂度为O(VE)。
1> 初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达);
2> 进行循环,循环下标为从1到n-1(n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算(边优化点距离);
3> 遍历途中所有的边edge(u, v),判断是否存在这样情况:d(v) > d (u) + w(u, v)。则返回false,表示途中存在从源点可达的权为负的回路。
流程图如下:
SPFA算法 该算法的全称是Shortest Path Faster Algorithm,由西南交通大学段凡丁于1994年提出。由于Bellman-ford算法的松弛计算每次都需要遍历所有边,因此算法复杂度偏高,尤其是当边数趋于饱和的情况下。而SPFA算法是Bellman-ford算法的队列优化版本,其通过队列优化加速松弛操作。具体方法是用邻接表存储边,外层点循环改为队列,每次松弛操作依据邻接表只取相关的边松弛,如果点的距离有更新,则将该点重新加入队尾,直到队列为空。当然,SPFA遇到复权回路也会无限松弛下去。这里值得一提的是,SPFA在解决网络流问题中效果不错。
敬请期待下节内容 线段树。
感谢各位的耐心阅读,后续文章于每周日奉上,欢迎大家关注小斗公众号 对半独白!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。