本文将介绍另外一种最短路径算法——Floyd-Warshall算法,简称为Floyd算法,该算法的发明者为1978年图灵奖获得者斯坦福大学计算机科学系教授罗伯特·弗洛伊德(Robert W.Floyd)。不同于单源点最短路径算法——Dijkstra算法,Floyd算法可以求出一张图中任意两点的最短路径,且允许图中存在负权重边的情况。
Floyd算法是一种利用动态规划思想寻找给定的加权图(有向图和无向图均可)中多源点之间最短路径的算法。思想也很简单:即两点之间的最短距离为两点之间的当前距离和引入中介节点后的距离之中取最短,所以Floy算法的状态转移方程可以表示为:
因此,我们只需要维护一个图中各顶点之间的距离矩阵即可,初始状态下,每对直接相连的顶点之间的距离为两者之间的边的权重。通过依次引入图中其他的点作为中介顶点,根据状态转移方程不断更新距离矩阵。这样最终我们可以得到图中任意两点之间的最短路径(All Pairs Shortest Paths)。Floyd算法的伪代码如下:
public static void main(String[] args) {
//图中顶点数量
int V = 100;
//距离矩阵,需要初始化,可以直接复制图的邻接矩阵作为初始化结果
int[][] d = new int[V][V];
for (int v = 0; v < V; v++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
//状态转移方程
d[i][j] = Math.min(d[i][j], d[i][v] + d[v][j]);
}
}
}
}
我们以一个图为例,以图形化的方式展示Floyd算法的大致过程。
initialize step 1 step 2 step 3 step 4 step 5 step 6 step 7Floyd算法可以算出图中任何两个顶点之间的最短路径,时间复杂度为,而单源点最短路径算法Dijstra的时间复杂度为。Floyd算法原理简单,且比较容易理解,代码编写也相对简单,而且可以处理有向图和无向图,对存在负权重边的图也能很好适用。但是由于其的时间复杂度,因此并不适合大规模图数据的场景,大规模图场景下,可以考虑其他方法进行计算。
参考:
网友评论