最小路徑問題 | Dijkstra算法詳解(附代碼)

來源:AI蝸牛車 本文共3400字,建議閱讀6分鐘 本文對Dijkstra算法做了一個詳細的介紹。
一、最短路徑問題介紹
1、從圖中的某個頂點出發(fā)到達另外一個頂點的所經(jīng)過的邊的權(quán)重和最小的一條路徑,稱為最短路徑。

迪杰斯特拉算法(Dijkstra算法) 弗洛伊德算法(Floyd算法) SPFA算法
二、Dijkstra算介紹
算法特點
算法的思路
三、Dijkstra算法示例演示







四、Dijkstra算法的代碼實現(xiàn)(c++)
Dijkstra.h文件的代碼
/************************************************************//* 程序作者:Willam *//************************************************************///@盡量寫出完美的程序using namespace std;/*本程序是使用Dijkstra算法實現(xiàn)求解最短路徑的問題采用的鄰接矩陣來存儲圖*///記錄起點到每個頂點的最短路徑的信息struct Dis {string path;int value;bool visit;Dis() {visit = false;value = 0;path = "";}};class Graph_DG {private:int vexnum; //圖的頂點個數(shù)int edge; //圖的邊數(shù)int **arc; //鄰接矩陣Dis * dis; //記錄各個頂點最短路徑的信息public://構(gòu)造函數(shù)Graph_DG(int vexnum, int edge);//析構(gòu)函數(shù)~Graph_DG();// 判斷我們每次輸入的的邊的信息是否合法//頂點從1開始編號bool check_edge_value(int start, int end, int weight);//創(chuàng)建圖void createGraph();//打印鄰接矩陣void print();//求最短路徑void Dijkstra(int begin);//打印最短路徑void print_path(int);};
Dijkstra.cpp文件的代碼
//構(gòu)造函數(shù)Graph_DG::Graph_DG(int vexnum, int edge) {//初始化頂點數(shù)和邊數(shù)this->vexnum = vexnum;this->edge = edge;//為鄰接矩陣開辟空間和賦初值arc = new int*[this->vexnum];dis = new Dis[this->vexnum];for (int i = 0; i < this->vexnum; i++) {arc[i] = new int[this->vexnum];for (int k = 0; k < this->vexnum; k++) {//鄰接矩陣初始化為無窮大arc[i][k] = INT_MAX;}}}//析構(gòu)函數(shù)Graph_DG::~Graph_DG() {delete[] dis;for (int i = 0; i < this->vexnum; i++) {delete this->arc[i];}delete arc;}// 判斷我們每次輸入的的邊的信息是否合法//頂點從1開始編號bool Graph_DG::check_edge_value(int start, int end, int weight) {if (start<1 || end<1 || start>vexnum || end>vexnum || weight < 0) {return false;}return true;}void Graph_DG::createGraph() {cout << "請輸入每條邊的起點和終點(頂點編號從1開始)以及其權(quán)重" << endl;int start;int end;int weight;int count = 0;while (count != this->edge) {cin >> start >> end >> weight;//首先判斷邊的信息是否合法while (!this->check_edge_value(start, end, weight)) {cout << "輸入的邊的信息不合法,請重新輸入" << endl;cin >> start >> end >> weight;}//對鄰接矩陣對應(yīng)上的點賦值arc[start - 1][end - 1] = weight;//無向圖添加上這行代碼//arc[end - 1][start - 1] = weight;++count;}}void Graph_DG::print() {cout << "圖的鄰接矩陣為:" << endl;int count_row = 0; //打印行的標(biāo)簽int count_col = 0; //打印列的標(biāo)簽//開始打印while (count_row != this->vexnum) {count_col = 0;while (count_col != this->vexnum) {if (arc[count_row][count_col] == INT_MAX)cout << "∞" << " ";elsecout << arc[count_row][count_col] << " ";++count_col;}cout << endl;++count_row;}}void Graph_DG::Dijkstra(int begin){//首先初始化我們的dis數(shù)組int i;for (i = 0; i < this->vexnum; i++) {//設(shè)置當(dāng)前的路徑dis[i].path = "v" + to_string(begin) + "-->v" + to_string(i + 1);dis[i].value = arc[begin - 1][i];}//設(shè)置起點的到起點的路徑為0dis[begin - 1].value = 0;dis[begin - 1].visit = true;int count = 1;//計算剩余的頂點的最短路徑(剩余this->vexnum-1個頂點)while (count != this->vexnum) {//temp用于保存當(dāng)前dis數(shù)組中最小的那個下標(biāo)//min記錄的當(dāng)前的最小值int temp=0;int min = INT_MAX;for (i = 0; i < this->vexnum; i++) {if (!dis[i].visit && dis[i].valuemin = dis[i].value;temp = i;}}//cout << temp + 1 << " "<//把temp對應(yīng)的頂點加入到已經(jīng)找到的最短路徑的集合中dis[temp].visit = true;++count;for (i = 0; i < this->vexnum; i++) {//注意這里的條件arc[temp][i]!=INT_MAX必須加,不然會出現(xiàn)溢出,從而造成程序異常if (!dis[i].visit && arc[temp][i]!=INT_MAX && (dis[temp].value + arc[temp][i]) < dis[i].value) {//如果新得到的邊可以影響其他為訪問的頂點,那就就更新它的最短路徑和長度dis[i].value = dis[temp].value + arc[temp][i];dis[i].path = dis[temp].path + "-->v" + to_string(i + 1);}}}}void Graph_DG::print_path(int begin) {string str;str = "v" + to_string(begin);cout << "以"<"為起點的圖的最短路徑為:" << endl;for (int i = 0; i != this->vexnum; i++) {if(dis[i].value!=INT_MAX)cout << dis[i].path << "=" << dis[i].value << endl;else {cout << dis[i].path << "是無最短路徑的" << endl;}}}
main.cpp文件的代碼
//檢驗輸入邊數(shù)和頂點數(shù)的值是否有效,可以自己推算為啥://頂點數(shù)和邊數(shù)的關(guān)系是:((Vexnum*(Vexnum - 1)) / 2) < edgebool check(int Vexnum, int edge) {if (Vexnum <= 0 || edge <= 0 || ((Vexnum*(Vexnum - 1)) / 2) < edge)return false;return true;}int main() {int vexnum; int edge;cout << "輸入圖的頂點個數(shù)和邊的條數(shù):" << endl;cin >> vexnum >> edge;while (!check(vexnum, edge)) {cout << "輸入的數(shù)值不合法,請重新輸入" << endl;cin >> vexnum >> edge;}Graph_DG graph(vexnum, edge);graph.createGraph();graph.print();graph.Dijkstra(1);graph.print_path(1);system("pause");return 0;}
6?81 3 101 5 301 6 1002 3 53 4 504 6 105 6 605 4 20
輸出:

評論
圖片
表情
