1. 程式人生 > >最短路徑——迪傑斯坷垃演算法(有向圖、單源最短路徑)

最短路徑——迪傑斯坷垃演算法(有向圖、單源最短路徑)

最短路徑的演算法有兩種:迪傑斯坷垃演算法和弗洛伊德演算法。

但是兩種演算法各有優劣:

迪傑斯坷垃演算法適合單源點最短路徑的獲取,

弗洛伊德演算法適合各點間最短路徑的獲取,即多源點最短路徑的獲取;

今天主要講解迪傑斯坷垃演算法。

一、演算法步驟:

1、獲取鄰接矩陣,確定起始點start;

2、找到起始點到所有點的距離最短的點k;

3、從k點出發找到距離其他所有點的距離,判斷start-->k+k-->i是否小於start-->i,如果成立,則將start到i的最短路徑換成start-->k+k-->i

4、重複2、3步,知道每個點都被遍歷;

二、程式碼展示:

public class d4 {
	static int M=10000;//此路不通,此處絕對不可為Integer的最大值或與鄰接矩陣中任意一個點的距離相加超出Integer範圍的值
	public static void main(String[] args) {
		int[][] weith={
		    {0,10,M,30,100},  
	            {M,0,50,M,M},  
	            {M,M,0,M,10},  
	            {M,M,20,0,60},  
	            {M,M,M,M,0} 
		};
		int start=0;
		int[] shortpath=dijkstra(weith,start);
		for(int i=0;i<shortpath.length;i++){
			System.out.println("從"+start+"到"+i+"的距離為:"+shortpath[i]);
		}
	}
	private static int[] dijkstra(int[][] weith, int start) {
		// TODO Auto-generated method stub
		int n=weith.length;//獲取頂點個數
		String[] path=new String[n];//記錄最短路徑經過的頂點
		int[] shortpath=new int[n];//記錄最短路徑的距離
		int[] visited=new int[n];//記錄是否被求出,若被求出值為1
		for(int i=0;i<n;i++){
			path[i]=new String(start+"-->"+i);
		}
		shortpath[start]=0; 
		visited[start]=1;
		for(int count=1;count<n;count++){
			int k=-1;//從未被標記的點中找出最短路徑的點
			int dmin=Integer.MAX_VALUE;//獲取start到k點的最短路徑的距離
			for(int i=0;i<n;i++){
				if(visited[i]!=1&&weith[start][i]<dmin){
					k=i;
					dmin=weith[start][i];
				}
			}
			shortpath[k]=dmin;
			visited[k]=1;
			for(int i=0;i<n;i++){
				if(visited[i]!=1&&weith[start][k]+weith[k][i]<weith[start][i]){
					path[i]=path[k]+"-->"+i;
					weith[start][i]=weith[start][k]+weith[k][i];
				}
			}
		}
		for(int i=0;i<shortpath.length;i++){
			System.out.println("從"+start+"到"+i+"的最短路徑為:"+path[i]);
		}
		System.out.println("=====================================");
		return shortpath;
	}
	
}

三、結果:

從0到0的最短路徑為:0-->0
從0到1的最短路徑為:0-->1
從0到2的最短路徑為:0-->3-->2
從0到3的最短路徑為:0-->3
從0到4的最短路徑為:0-->3-->2-->4
=====================================
從0到0的距離為:0
從0到1的距離為:10
從0到2的距離為:50
從0到3的距離為:30
從0到4的距離為:60