floyd算法學習

一、問題引入java

  帶權有向圖中單源點的最短路徑問題能夠用地傑斯特拉算法求解,若是要求解圖中每一對頂點之間的最短路徑,相似能夠想到的方法爲:每次以一個頂點爲源點,重複執行地傑斯特拉算法算法n次,這樣,即可以求得每一對頂點之間的最短路徑,總的執行時間爲O(n3)。算法

  這裏能夠採用另一種求解算法:Floyd算法。數組

二、Floyd的基本思想爲:spa

  從鄰接矩陣a開始進行n次迭代,第一次迭代後a[i,j]的值是從vi到vj且中間不通過變化大於1的頂點的最短路徑長度;第k次迭代後a[i,j]的值是從vi到vj且中間不通過變化大於k的頂點的最短路徑長度 第n次迭代後a[i,j]的值就是從vi到vj的最短路徑長度。code

三、算法描述:orm

  (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]的值不變。it

四、具體實現:io

  帶權有向圖以下:class

在b.txt文件中保存的帶權有向圖的數據爲:import

其中第一個數據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();
		}
	}

}
相關文章
相關標籤/搜索