弗洛伊德(Floyd)算法
-
用于寻找给定的加权图中各个顶点间的最短路径,时间复杂度较高:立方阶,将每个顶点都看作是出发点,求到其它点的最短距离
-
狄杰斯特拉算法是计算图中某一个顶点到其它顶点的最短路径,选定被访问顶点
算法思路
- 设置顶点vi到顶点vk的最短路径已知Lik,顶点vk到vj的最短路径已知为Lkj,顶点vi到vj的路径为Lij,则vi到vj的最短路径为:min((Lik+Lkj),Lij),vk的取值为图中所有顶点,则可获得vi到vj的最短路径
- 至于vi到vk的最短路径Lik或者vk的最短路径Lkj,是以同样的方式获得
中间顶点 出发顶点 终点
代码
-
创建图类class Graph{} 定义变量 构造器 展示pre和dis数组的方法
class Graph{ private char[] vertex; // store vertex private int[][] dis; // store distance of each vertex to other vertexes private int[][] pre; // store pre vertex of arrived target vertex /** * constructor * @param length size * @param matrix preliminary matrix * @param vertex */ public Graph(int length,int[][] matrix,char[] vertex){ this.vertex = vertex; this.dis = matrix; this.pre = new int[length][length]; // initialize pre array (index of pre vertex) for(int i = 0;i<length;i++){ Arrays.fill(pre[i],i); } } // show pre and dis public void show(){ char[] vertex = {'A','B','C','D','E','F','G'}; for(int k = 0; k < dis.length;k++){ // output one row of pre for(int i = 0;i<dis.length;i++){ System.out.print(vertex[pre[k][i]]+" "); } System.out.println(); // output one row of dis for(int i = 0;i<dis.length;i++){ System.out.print("(shortest dis of "+vertex[k]+" and B: "+ dis[k][i]+") "); } System.out.println(); System.out.println(); } } }
-
主函数测试图
public static void main(String[] args) { // test graph char[] vertex = {'A','B','C','D','E','F','G'}; // preliminary matrix int[][] matrix = new int[vertex.length][vertex.length]; final int N = 65535; matrix[0] = new int[]{0,5,7,N,N,N,2}; matrix[1] = new int[]{5,0,N,9,N,N,3}; matrix[2] = new int[]{7,N,0,N,8,N,N}; matrix[3] = new int[]{N,9,N,0,N,4,N}; matrix[4] = new int[]{N,N,8,N,0,5,4}; matrix[5] = new int[]{N,N,N,4,5,0,6}; matrix[6] = new int[]{2,3,N,N,4,6,0}; // create graph object Graph graph = new Graph(vertex.length, matrix, vertex); graph.show(); }
-
弗洛伊德(class Graph{}中)
public void floyd(){ int len = 0; // store dis // traverse middle vertex, k is the index of middle vertex; ['A','B','C'...] for(int k = 0;k<dis.length;k++){ // // start from vertex i['A','B','C'...] for(int i = 0;i<dis.length;i++){ // end vertex for(int j = 0;j<dis.length;j++){ len = dis[i][k] + dis[k][j]; // distance: start from i, pass by k, arrive at j if(len<dis[i][j]){ dis[i][j] = len; // update dis pre[i][j] = pre[k][j]; // update pre } } } } }
-
主函数中调用弗洛伊德方法