迪傑斯特拉(Dijkstra)算法思想
按路徑長度遞增次序產生最短路徑算法:
把結點V分成兩組:
(1)S:已求出最短路徑的頂點的集合
(2)V-S=T:尚未確定最短路徑的頂點集合
將T中頂點按最短路徑遞增的次序加入到S中.
保證:
(1)從源點V0到S中各頂點的最短路徑長度都不大於從V0到T中任何頂點的最短路徑長度
(2)每個頂點對應一個距離值
S中頂點:從V0到此頂點的最短路徑長度
T中頂點:從V0到此頂點的只包括S中頂點作中間頂點的最短路徑長度
import java.util.*;
public class Main {
private int numNode; //結點的個數
private int[][] matrix; //存放結點之間的權值
private int startVertex; //開始結點
private int[] distance; //存放開始結點到其他結點的最短距離
private int[] preVertex; //存放路徑的前一個結點
public Main(int[][] matrix,int numNode,int startVertex) {
this.matrix = matrix;
this.numNode = numNode;
this.startVertex = startVertex;
distance = new int[numNode];
preVertex = new int[numNode];
}
public void Dijstra(){
//創建一個數組,用來標記結點是否已經在集合S中
boolean[] isInS = new boolean[numNode];
//初始化distance和preVertex
for(int i =0;i<numNode;i++){
distance[i] = matrix[startVertex][i];
if(matrix[startVertex][i]<Integer.MAX_VALUE){
preVertex[i] = startVertex;
}
else
preVertex[i] = -1; //-1表示該結點的前一結點尚未找到或者沒有前一結點
}
preVertex[startVertex] = -1;
//先把開始結點加入集合S中
isInS[startVertex] = true;
//nextVertex表示下一個最新加入S中的結點,該結點到開始結點的距離在非集合S中是最小的
int nextVertex = startVertex;
for(int i =0;i<numNode;i++){
int tmMinDistance = Integer.MAX_VALUE;
//找到不在S中且到開始結點的距離最小的結點,tmMinDistance表示開始結點到結點nextVertex的最小值
for(int j = 0;j<numNode;j++){
if(isInS[j]==false && distance[j]<tmMinDistance){
nextVertex = j;
tmMinDistance = distance[j];
}
}
isInS[nextVertex] = true;
//更新開始結點到其他結點的距離
for(int j = 0;j<numNode;j++){
if(isInS[j]==false && matrix[nextVertex][j]<Integer.MAX_VALUE){
int temp = matrix[nextVertex][j]+tmMinDistance;
if(temp<distance[j]){
distance[j] = temp;
preVertex[j] = nextVertex;
}
}
}
}
}
public void print(){
for(int i =0;i<numNode;i++){
int index = i ;
Stack<Integer> trace = new Stack<Integer>();
while(preVertex[index]!=-1){
trace.push(preVertex[index]);
index = preVertex[index];
}
System.out.print("Path: ");
while(!trace.empty()){
System.out.print(trace.pop()+" --> ");
}
System.out.print(""+i);
System.out.println(" Distance: "+distance[i]);
}
}
public static void main(String[] args) {
final int INT_MAX = Integer.MAX_VALUE;
int graph[][] = {
{INT_MAX,INT_MAX,INT_MAX,INT_MAX,2,5},
{INT_MAX,INT_MAX,5,INT_MAX,4,INT_MAX},
{INT_MAX,INT_MAX,INT_MAX,2,INT_MAX,INT_MAX},
{5,INT_MAX,INT_MAX,INT_MAX,INT_MAX,4},
{INT_MAX,INT_MAX,6,2,INT_MAX,INT_MAX},
{INT_MAX,4,3,INT_MAX,INT_MAX,INT_MAX}
};
Main gr = new Main(graph, 6, 1);
gr.Dijstra();
gr.print();
}
}
輸出:
Path: 1 –> 4 –> 3 –> 0 Distance: 11
Path: 1 Distance: 2147483647
Path: 1 –> 2 Distance: 5
Path: 1 –> 4 –> 3 Distance: 6
Path: 1 –> 4 Distance: 4
Path: 1 –> 4 –> 3 –> 5 Distance: 10