1、问题引入
带权有向图中单源点的最短路径问题可以用地杰斯特拉算法求解,如果要求解图中每一对顶点之间的最短路径,类似可以想到的方法为:每次以一个顶点为源点,重复执行地杰斯特拉算法算法n次,这样,便可以求得每一对顶点之间的最短路径,总的执行时间为O(n3)。
这里可以采用另外一种求解算法:Floyd算法。
2、Floyd的基本思想为:
从邻接矩阵a开始进行n次迭代,第一次迭代后a[i,j]的值是从vi到vj且中间不经过变化大于1的顶点的最短路径长度;第k次迭代后a[i,j]的值是从vi到vj且中间不经过变化大于k的顶点的最短路径长度 第n次迭代后a[i,j]的值就是从vi到vj的最短路径长度。
3、算法描述:
(1) 用数组d[i][j]来记录i,j之间的最短距离。初始化d[i][j],若i=j则d[i][j]=0,
若i,j之间有边连接则d[i][j]的值为该边的权值,否则d[i][j]的值为max 。
(2) 对所有的k值从1到n,修正任意两点之间的最短距离,计算d[i][k]+d[k][j]的值,
若小于d[i][j],则d[i][j]= d[i][k]+d[k][j],否则d[i][j]的值不变。
4、具体实现:
带权有向图如下:
在b.txt文件中保存的带权有向图的数据为:
其中第一个数据4表述图中有4个节点,其他的四行四列数据表示各个节点之间的路径长度,9999表示两个节点之间不可达。
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Floyd {
public static int N;
public static int[][] f;
public static int[][] path;
public static void floyd(){
int i,j,k;
i = j = k = 0;
for(i = 0; i < N; ++i)
for(j = 0; j < N; ++j)
for(k = 0; k < N; ++k)
if(f[i][j] > f[i][k] + f[k][j]){
f[i][j] = f[i][k] + f[k][j];
path[i][j] = k;
}
print();
}
public static void print(){
for(int i = 0; i < N; ++i){
for(int j = 0; j < N; ++j){
printPath(i, j);
System.out.print("="+f[i][j]+"\t");
}
System.out.println();
}
}
public static void printPath(int i, int j){
if(i == j || path[i][j] == -1)
System.out.print(i+"->"+j);
else{
printPath(i,path[i][j]);
System.out.print("->"+j);
}
}
public static void main(String[] args) {
String p = "d:/b.txt";
try {
Scanner s = new Scanner(new File(p));
while(s.hasNext()){
N = s.nextInt();
f = new int[N][N];
path = new int[N][N];
for(int i = 0; i < N; ++i){
for(int j =0; j < N; ++j){
f[i][j] = s.nextInt();
path[i][j] = -1;
}
}
floyd();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
来源:oschina
链接:https://my.oschina.net/u/1182234/blog/272735