Java資料結構:單源最短路徑問題---Dijkstra演算法
阿新 • • 發佈:2018-12-16
嚶擊長空
如圖:
思路:先任意找一個根節點,然後開始迴圈找連線該點所有邊,然後找到權值最小的一項,標記被訪問,然後再次迴圈找除了根節點和被訪問過的結點的邊,找到權值最小的。具體開註釋,非常詳細喲。
上程式碼:
public void shortesPath(int i) { int n = this.vertexCount(); // 圖的結點數 boolean[] vset = new boolean[n]; // 已求出最短路徑的頂點集合,初始全為false; vset[i] = true; // 當前的開始結點為true int[] dist = new int[n]; // 最短路徑的長度 int[] path = new int[n]; // 最短路徑終點的前一結點 for (int j = 0; j < n; j++) { // 初始化dist和path dist[j] = this.weight(i, j); path[j] = (j != i && dist[j] < MAX_WEIGHT) ? i : -1; } for (int j = (i + 1) % n; j != i; j = (j + 1) % n) { // 開始尋找從i到各個結點的最短路徑,取餘為了使防止出現j比結點數i大的情況 int mindist = MAX_WEIGHT, min = 0; // 定義路徑最小值和其下標 for (int k = 0; k < n; k++) { // 開始尋找最小路徑 if (!vset[k] && dist[k] < mindist) {// 如果沒有訪問過並且有路徑小於當前路徑的最小路徑 mindist = dist[k]; // 跟新最小路徑和最小路徑的下標 min = k; } } if (mindist == MAX_WEIGHT) {// 如果沒有其他最短路徑則此演算法結束。 break; } vset[min] = true; // 設定最小結點訪問過 for (int k = 0; k < n; k++) {// 更新i到其他結點的路徑 if (!vset[k] && this.weight(min, k) < MAX_WEIGHT && dist[min] + this.weight(min, k) < dist[k]) {// 如果沒有被訪問,並且小於初始路徑權值,更新路徑。 dist[k] = dist[min] + this.weight(min, k); //最小路徑+最小路徑結點到目的結點的權《=》i直接到目的結點的權。決定是否替換。 path[k] = min; } } } }