1. 程式人生 > >dijkstra算法--尋找最短路徑

dijkstra算法--尋找最短路徑

記錄 -h 兩個 In amp clas 通過 ant pan

轉自https://blog.csdn.net/heroacool/article/details/51014824

基本思想

  1. 通過Dijkstra計算圖G中的最短路徑時,需要指定起點s(即從頂點s開始計算)。

  2. 此外,引進兩個集合S和U。S的作用是記錄已求出最短路徑的頂點(以及相應的最短路徑長度),而U則是記錄還未求出最短路徑的頂點(以及該頂點到起點s的距離)。

  3. 初始時,S中只有起點s;U中是除s之外的頂點,並且U中頂點的路徑是”起點s到該頂點的路徑”。然後,從U中找出路徑最短的頂點,並將其加入到S中;接著,更新U中的頂點和頂點對應的路徑。 然後,再從U中找出路徑最短的頂點,並將其加入到S中;接著,更新U中的頂點和頂點對應的路徑。 … 重復該操作,直到遍歷完所有頂點。

操作步驟

  1. 初始時,S只包含起點s;U包含除s外的其他頂點,且U中頂點的距離為”起點s到該頂點的距離”[例如,U中頂點v的距離為(s,v)的長度,然後s和v不相鄰,則v的距離為∞]。

  2. 從U中選出”距離最短的頂點k”,並將頂點k加入到S中;同時,從U中移除頂點k。

  3. 更新U中各個頂點到起點s的距離。之所以更新U中頂點的距離,是由於上一步中確定了k是求出最短路徑的頂點,從而可以利用k來更新其它頂點的距離;例如,(s,v)的距離可能大於(s,k)+(k,v)的距離。

  4. 重復步驟(2)和(3),直到遍歷完所有頂點。

多謝博主的敘述,我其實一直對於dijkstra算法有疑惑 就是關於集合s,u的作用 搞清楚了就明白了 下面是我寫的一個例子

#include<iostream>
using namespace std;
#define INF 100
//0:北區宿舍
//1:第二食堂
//2:2區
//3:3區
//4:4區
//5:5區
//6:6區
//7:7區
//8:8區
//9:圖書館

//圖的鄰接矩陣
int matrix[10][10] = {
    0,1,3,23,INF,15,6,7,28,12,
    0,0,12,2,13,3,14,6,INF,10,
    0,0,0,11,1,21,INF,24,5,38,
    0,0,0,0,11,13,4,25,6,38,
    0,0,0,0,0,22,12,14,INF,18,
    0,0,0,0,0,0,INF,12,4
,48, 0,0,0,0,0,0,0,22,24,18, 0,0,0,0,0,0,0,0,21,26, 0,0,0,0,0,0,0,0,0,26, 0,0,0,0,0,0,0,0,0,0 }; //各個景點名字 char name[10][100] = { "北區宿舍", "第二食堂", "二區教學樓", "三區教學樓", "四區教學樓", "五區教學樓", "六區教學樓", "七區教學樓", "八區教學樓", "圖書館" }; //景點的詳細內容 char content[10][500] = { "提供住宿", "提供飲食", "教學區2", "教學區3", "教學區4", "教學區5", "教學區6", "教學區7", "教學區8", "提供閱讀,書籍借閱與歸還" }; //S的作用是記錄已求出最短路徑的頂點(以及相應的最短路徑長度), //而U則是記錄還未求出最短路徑的頂點(以及該頂點到起點s的距離)。 int s[10], u[10]; bool flag[10] = { false };//用以標誌已經存儲在s[]中的點 //找到與i節點相連路徑的最短節點 返回其下標 int min(int i) { int min = INF; int tag = 0; for (int j = 0; j < 10; j++) { if (j == i) //不能返回自身 即權重為0的點 continue; else if(!flag[j]) //如果沒被標誌 { if (min > matrix[i][j]) { min = matrix[i][j]; tag = j; } } } return tag; } //介紹圖景 void serveintroduce() { int i; cout <<endl<< "please input your choice to get more information:"; cin >> i; while (i > 9 || i < 0) { cout << "please input the true number!!!"; cout << "please input your choice to get more information:"; cin >> i; } cout << "the number you have input is :" << i << endl; cout << "the building of the number is :" << name[i] << endl; cout << "this building‘s function is :" << content[i] << endl; } //找到最短路徑 輸入出發點與目的地 輸出最短路徑長度 void findtrade() { int st, en; //開始節點st 結束節點en int pre[10]; //用以記錄起始點到各點最短路徑的前驅 memset(s, 0, sizeof(s)); memset(u, 0, sizeof(u)); cout << endl << "please input the start point and destination:" << endl; cin >> st; cin >> en; while (st > 9 || st < 0 || en>9 || en < 0) { cout << "please input the true number!!!"; cout << endl << "please input the start point and destination:" << endl; cin >> st; cin >> en; } if (st == en) { cout << "原地踏步"; return; } for (int i = 0; i < 10; i++) { s[i] = u[i] = matrix[st][i]; pre[i] = st; //前驅 flag[i] = false; //刷新標誌位 每次執行findtrade()函數都需要刷新標誌 } //Dijkstra算法 int m = st; flag[st] = true; for (int i = 0; i < 10; i++) { if (m == en) break; if (s[min(m)] > s[m] + matrix[m][min(m)]) { pre[min(m)] = m; s[min(m)] = s[m] + matrix[m][min(m)]; } m = min(m); flag[m] = true; } cout << name[st] << "" << name[en] << "的最短距離為" << s[en] << endl; //輸出最短距離 m = en; cout << name[en]; while (pre[m] != st) //打印最短路徑 { cout << "<---" << name[pre[m]]; m = pre[m]; } cout << "<---" << name[st] << endl; } int main() { int i = 0; cout << "plaese read the review to choose what you want to know" << endl; for (i = 0; i < 10; i++) { cout << i << " :"; cout << name[i] << " " << endl; } for (int i = 0; i < 10; i++) { for (int j = 9; j > i; j--) matrix[j][i] = matrix[i][j]; } //for(int i = 0; i < 10; i++) //{ // for (int j = 0; j < 10; j++) // cout << matrix[i][j]<<" "; // cout << endl; //} while (i) { cout << endl<<"please input the num to choose the following choice:" << endl; cout << "1, service of introduce; 2, find the trade" << endl; cin >> i; while (i != 1 && i != 2) { cout << endl<<"please input the true number!!!" << endl; cout << "please input the num to choose the following choice:" << endl; cout << "1, service of introduce; 2, find the trade" << endl; cin >> i; } if (i == 1) serveintroduce(); else findtrade(); } return 0; }

dijkstra算法--尋找最短路徑