1.基本思想
通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。
初始时,矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。然后,对矩阵S进行更新,如果"a[i][j]的距离" > "a[i][k]+a[k][j]",则更新a[i][j]为"a[i][k]+a[k][j]"。
2.弗洛伊德算法和迪杰斯特拉算法的区别
1)迪杰斯特拉是计算单源到所有点的最短路径,弗洛伊德算法是计算所有点到点之间的最短距离
2)迪杰斯特拉算法属于贪心算法,弗洛伊德算法属于动态规划(迪杰斯特拉算法不能应用于带有负权的图)
3)迪杰斯特拉算法的时间复杂度为O(n^2),弗洛伊德算法的时间复杂度为O(n^3)
3.弗洛伊德算法图解
参考自博客:http://www.cnblogs.com/skywang12345/p/3711532.html
4.弗洛伊德算法的Java代码
public class FloydGraph {
private static int INF=Integer.MAX_VALUE;
private int size;
private int[][] distance;//保存i到j的最小路径值
private int[][] path; //保存i到j的中间节点
public int getSize() {
return size;
}
public FloydGraph(int size){
this.size=size;
distance=new int[size][size];
path=new int[size][size];
}
public void initial(int[][] matrix){ //对输入的邻接矩阵的图初始化
for(int i=0;i
distance[i][x]+distance[x][j]){
distance[i][j]=distance[i][x]+distance[x][j];
path[i][j]=x;
}
}
}
}
}
public String getShortestPath(int start,int end){
StringBuilder sb=new StringBuilder();
int next=path[start][end];
if(next!=-1){
sb.append(start).append("->");
while(next!=end){
sb.append(next).append("->");
next=path[next][end];
}
sb.append(end);
}else{
sb.append("shortest path no exist!");
}
return sb.toString();
}
public int getShortestDistance(int start,int end){
return distance[start][end];
}
}
public class Main {
private static int INF=Integer.MAX_VALUE;
public static void main(String[] args) {
FloydGraph graph=new FloydGraph(7);
int[][] matrix={
/*{0,3,8,Integer.MAX_VALUE,4},
{Integer.MAX_VALUE,0,Integer.MAX_VALUE,1,7},
{Integer.MAX_VALUE,4,0,Integer.MAX_VALUE,Integer.MAX_VALUE},
{2,Integer.MAX_VALUE,5,0,Integer.MAX_VALUE},
{Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,6,0}*/
{0,12,INF,INF,INF,16,14},
{12,0,10,INF,INF,7,INF},
{INF,10,0,3,5,6,INF},
{INF,INF,3,0,4,INF,INF},
{INF,INF,5,4,0,2,8},
{16,7,6,INF,2,0,9},
{14,INF,INF,INF,8,9,0}
};
graph.initial(matrix);
System.out.println(graph.getShortestPath(6, 1));
System.out.println(graph.getShortestDistance(6, 1));
}
}
运行结果:
6->5->1
16
16