最短路徑——迪傑斯坷垃演算法(有向圖、單源最短路徑)
阿新 • • 發佈:2019-02-06
最短路徑的演算法有兩種:迪傑斯坷垃演算法和弗洛伊德演算法。
但是兩種演算法各有優劣:
迪傑斯坷垃演算法適合單源點最短路徑的獲取,
弗洛伊德演算法適合各點間最短路徑的獲取,即多源點最短路徑的獲取;
今天主要講解迪傑斯坷垃演算法。
一、演算法步驟:
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