图的最短路径算法-弗洛伊德算法
什么是Floyd-Warshall算法
如果有一个带权图,怎么才能求出图中所有顶点两两之间的最短距离?
使用之前介绍的Dijkstra算法,针对图中每一个顶点都使用一次,也可以做到求出所有顶点之间的最短距离。
但由于Dijkstra算法的代码逻辑较为复杂,所以可以使用Floyd-Warshall(弗洛伊德算法)算法做同样的事情,代码逻辑更简洁,而且两个算法求多源最短路径的总时间复杂度也相同,均为O(n^3)。
弗洛伊德算法的英文名称是Floyd-Warshall(不是心理学大师弗洛伊德),专门用于寻找带权图中多源点之间的最短路径。算法的思路是根据图实例中所有顶点,不断引入新的顶点作为中继顶点,借由一个个中继顶点,一步步推导求出所有顶点之间的最短距离。
Floyd-Warshall算法详细步骤
以下算法详细步骤图,均来自公众号”程序员小灰”的文章——《漫画:图的 “多源” 最短路径》
假设有这样一个带权图的邻接矩阵。
假设按图实例的顶点顺序,以A开始作为邻接矩阵的中继顶点:
顶点B与顶点C之间距离为无限大,此时缩短为顶点A到顶点B距离+顶点B到顶点C的距离=5+2=7。
再假设,现在接着引入新的中继顶点,以A、B作为邻接矩阵的中继顶点:
顶点A与顶点D之间距离为无限大,以顶点B作为中继顶点,此时缩短为顶点A到顶点B距离+顶点B到顶点D的距离=5+1=6。
顶点A与顶点E之间距离为无限大,以顶点B作为中继顶点,此时缩短为顶点A到顶点B距离+顶点B到顶点E的距离=5+6=11。
再假设,接着引入新的中继顶点,以A、B、C作为邻接矩阵的中继顶点:
顶点A与顶点F之间距离为无限大,以顶点C作为中继顶点,此时缩短为顶点A到顶点C距离+顶点C到顶点F的距离=2+8=10。
(注:为了简化理解,以上图解过程演示情况仅考虑了顶点A到某个顶点之间的距离,未演示其他任意顶点到某个顶点之间的距离)
重复上面的步骤,不断引入新的中继顶点,刷新邻接矩阵中的临时距离
最终得到如下图实例的距离表:
此时,距离表中记录着图中某一个顶点,到任意另外一个顶点的最短距离。
代码实现
1 |
|
代码实例
假如有这样一个图实例:
1 |
|
加入将数组下标转换成对应顶点的辅助常量numberToChar
1 |
|
取消上述代码实现中的注释部分,并将图实例(graphdemo)传入弗洛伊德算法(floydWarshall)可以得到如下过程结果:
1 |
|