1. 程式人生 > >Dijkstra演算法實現從一個源點到其他各點的最短路徑

Dijkstra演算法實現從一個源點到其他各點的最短路徑

最短路徑問題與現實生活中的問題息息相關,所以最短路徑問題一定要掌握,這是書上的介紹
這裡寫圖片描述
怎麼理解呢?還是給個例子會比較清楚,比如下面這個圖:
這裡寫圖片描述

初始時,集合s={a}(假設a為源點),t={b,c,d,e}
然後從t中選取到a路徑長度最短的頂點:
a-b ->6
a-c ->2
a-d ->無窮大(a和d之間不能直接連線)
a-e ->無窮大
可以看到,a-c路徑最短,所以選取c到s中,a-c路徑記錄下來

  s={a,c},t={b,d,e}
  現在比較 “原來t中b,d,e各點的最短路徑長度” 和 ”通過上次記錄下來的路徑再到達各點的路徑長度",
  a-b ->6   <  a-c-b  -> 無窮大
  //所以當前a到b的最短路徑為a-b ->6
  a-d ->無窮大 > a-c-d  -> 3
  //所以當前a-d的最短路徑為a-c-d ->3
  a-e->無窮大 > a-c-e  ->9
  //所以當前a-e的最短路徑為a-c-e ->9

現在t中a-c-d 路徑最短,將d選進s
s={a,c,d} t={b,e}

a-b ->6 > a-c-d-b ->5
//所以當前a到b的最短路徑為a-c-d-b ->6
a-c-e ->9 < a-c-d-e
//所以當前a-e的最短路徑為a-c-e ->9

現在t中a-c-d-b路徑最短,將b選進s
s={a,c,d,b},t={e}

a-c-e ->9 < a-c-d-b-e ->13
//所以當前a-e的最短路徑為a-c-e ->9
將e選進s,s={a,b,c,d,e}現在圖中所有頂點都在s中,演算法結束

已上就是Dijkstra演算法的一個具體例子,應該很明白了,那就實現它吧

dijkstra成員函式

void adjaMultiList::dijkstra(int v0)//顯示v0到其他各點的最短路徑
{
    //構造兩個集合S和U,S儲存已經找到的最短路徑的點,U儲存還未找到的點,初始時    S只有V0,S
    //為剩餘的所有點,不妨用vector來表示路徑,比如路徑0-1-2,,vector相應的就包含3個元素,0,1,2
    map<int, vector<int>> path;//第一個表示某頂點編號,第二個表示v0到該頂點的路徑
    vector<int
>
s = { v0 };//初始時s中只有v0 vector<int> u;//初始時u中為剩下所有點 for (int i = 0; i < iVertex - 1; ++i) { if (i < v0) u.push_back(i); else u.push_back(i + 1); } vector<int> u1 = u; vector<double> path_weight; for (int i1 = 0; i1 < iVertex; ++i1) path_weight.push_back(0); //vector<double> path_weight1;//儲存最終的最短路徑長度 int selected=v0;//每次迴圈後選進s的點,初始時從v0開始 int u_size = iVertex - 1;//初始時u中頂點個數總個數減1 int s_size = 1;//初始時s中頂點個數為1 double min; vector<int> selectedMinPath; for (int i = 0; i < iVertex - 1; ++i) { for (int k = 0; k<u_size; ++k) { if (i == 0)//第一次迴圈 { path_weight[u[k]]=getWeight(v0,u[k]); path[u[k]].push_back(v0); path[u[k]].push_back(u[k]); } else { //如果從之前選中的頂點那條路徑距離加上再走向某點的距離小於原來的距離,更新 if (min + getWeight(selected, u[k])<path_weight[u[k]]) { path[u[k]] = selectedMinPath; path[u[k]].push_back(u[k]); path_weight[u[k]] = min + getWeight(selected, u[k]); } } } //選取u中路徑長度最小的,min為最小路徑長度,selectedMinPath為最小路徑,num為選中的頂點 min = path_weight[u[0]]; int num = u[0];//v0到某點的路徑最短,u為該點編號 int m = 1; for (; m < u_size; ++m) { if (min > path_weight[u[m]]) { min = path_weight[u[m]]; num = u[m]; } } selected = num; selectedMinPath = path[num]; ++s_size; s.push_back(num); --u_size; //刪除u中編號為num的頂點 for (vector<int>::iterator it = u.begin(); it != u.end(); ++it) { if (*it == num) { u.erase(it); break; } } } cout << "頂點" << vertexElem[v0].data << "到其他各頂點的最短路徑及長度分別為:" << endl; for (int i2 = 0; i2 < iVertex - 1; i2++) { cout << vertexElem[u1[i2]].data << ": 長度:"<<path_weight[u1[i2]]<<" 路徑:"; for (auto it = path[u1[i2]].begin(); it != path[u1[i2]].end(); ++it) cout << vertexElem[*it].data << "-"; cout << "\b "<<endl;//注意加個空格,相當於游標定位到前一個,然後寫入空格代替了- } }

這裡寫圖片描述
換個開始點,比如換成D看看
這裡寫圖片描述

相關推薦

Dijkstra演算法實現一個其他路徑

最短路徑問題與現實生活中的問題息息相關,所以最短路徑問題一定要掌握,這是書上的介紹 怎麼理解呢?還是給個例子會比較清楚,比如下面這個圖: 初始時,集合s={a}(假設a為源點),t={b,c,d,e} 然後從t中選取到a路徑長度最短的頂點:

一個例子讓你明白一個演算法-Dijkstra(求頂點路徑

演算法思想 1.在一個圖中,把所有頂點分為兩個集合P,Q(P為最短路徑集合,Q為待選集合),用dis陣列儲存源點到各個頂點的最短路徑(到自身為0)。 2.初始化P集合,就是加入源點到該集合,並在ma

hdu2066 dijkstra多終點求路徑

dijkstra演算法的思路: (1)找到最短距離已經確定的頂點,從它出發更新相鄰頂點的最短距離 (2)此後不再關心(1)中最短距離已經確定的頂點 最開始時只有起點的最短距離是確定的,而在未使用過的頂點中,距離d[i]最小的頂點就是最短距離已經確定的頂點,在不存在負邊的情況下d[i]不會

hdu2066 dijkstra多終點求路徑

dijkstra演算法的思路: (1)找到最短距離已經確定的頂點,從它出發更新相鄰頂點的最短距離 (2)此後不再關心(1)中最短距離已經確定的頂點 最開始時只有起點的最短距離是確定的,而在未使用過的頂點中,距離d[i]最小的頂點就是最短距離已經確定的頂點,在不存在負邊的

有權圖的路徑 Dijkstra演算法(證明不能解決負權邊)7.1.2

單源最短路徑問題,即在圖中求出給定頂點到其它任一頂點的最短路徑。  Dijkstra演算法 假設存在G=<V,E>,源頂點為0,U={0+已確定的最短路徑頂點},dist[i]記錄頂點0到頂點i的最短距離(包括確定的和估算的),path[i]記錄從0到i路徑上的

圖 實驗七 采用Dijkstra算法求帶權有向圖的路徑

圖解 初始 -s 由於 mic spa 初始化 mil dijkstra Dijkstra算法圖解 說明:初始化:S = { 0 }, U = { 1, 2, 3, 4, 5, 6 }, dist[ ] = { 0, 4, 6, 6, ∞, &in

問題 1708: 演算法7-15:迪傑斯特拉路徑演算法

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 可將迪傑斯特拉演算法描述如下: 在本題中,讀

演算法7-15:迪傑斯特拉路徑演算法

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 可將迪傑斯特拉演算法描述如下:

演算法7-15:迪傑斯特拉路徑演算法(c語言)

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 可將迪傑斯特拉演算法描述如下: 在本題中,讀入

利用graphviz來實現無向圖視覺化(求路徑

1.首先下載graphviz,並安裝。 2.將輸入的邊儲存起來。 3.將最短路徑求出,並存儲每個頂點的前驅。 4.在程式中將建邊的程式碼寫入一個dot檔案中。 5.將dot檔案轉化為.png形式。 6.利用system函式開啟.png。 程式碼如下: #include &

演算法7-15:迪傑斯特拉路徑演算法(模板)

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 在本題中,讀入一個有向圖的帶權鄰接矩陣(即陣列

問題 F: 演算法7-15:迪傑斯特拉路徑演算法

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 在本題中,讀入一個有向圖的帶權鄰接矩陣(

演算法導論 | 第25章 所有結點對的路徑問題

零、前言 前面講了單源最短路徑問題,指定一個原點一個終點,找到最短路徑。但是如果我們要求所有結點對呢? 方案一:可以對每一個結點呼叫一次單源最短路徑演算法,一共呼叫|V|次。(每指定一個原點,可以求出其他任何點到該原點的舉例) 對於權值為非負的圖,可以呼叫Dijkstra

圖(有向圖,無向圖)的鄰接矩陣表示C++實現(遍歷,拓撲排序,路徑小生成樹) Implement of digraph and undigraph using adjacency matrix

本文實現了有向圖,無向圖的鄰接矩陣表示,並且實現了從建立到銷燬圖的各種操作。 以及兩種圖的深度優先遍歷,廣度優先遍歷,Dijkstra最短路徑演算法,Prim最小生成樹演算法,有向圖的拓撲排序演算法。 通過一個全域性變數控制當前圖為有向圖還是無向圖。 若為無向圖,則生成的

資料結構實驗34——求賦權圖中一個結點到所有結點的路徑的長度

Description給一個賦權圖(無向圖),求0號結點到其餘所有結點的最短路徑的長度。Input先輸入一個小於等於100的正整數n,然後輸入賦權圖的鄰接矩陣(10000表示無窮大,並且任意一條簡單路徑

演算法導論筆記:25所有節點對的路徑問題

       本章考慮在給定的有向加權圖G=(V, E),對於所有的節點u,v∈V,找到一條從節點u到節點v的最短路徑。希望以表格的形式表示輸出:第u行第v列給出的是節點u到節點v的最短路徑權重。  

(BFS11.1.1)POJ 3126 Prime Path(計算初始素數到目標素數的路徑長度)

/* * POJ_3126.cpp * * Created on: 2013年11月7日 * Author: Administrator */ #include <ios

遞迴演算法深入淺出五:深度搜索尋找圖路徑

如果你看到這篇文章並不是在我的CSDN部落格釋出,同時文章裡面的圖片、URL全沒了的,那麼,很有可能你上了一個爬蟲網站! 在此,我建議你馬上關閉該頁面!因為爬蟲或多或少都會出現內容的紕漏,對讀者

Dijkstra一個其他路徑

#include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int vertex[MAXSIZE]; int edges[MAXSIZE][MAXSIZE]; }Gra

dijkstra演算法(單路徑) python實現

用例圖: 程式碼1: 用最原始的方式實現dijkstra,就是每次從costs裡面找最短路徑的點,再遍歷這個點的邊,更新最短路徑。由於每次都要從costs裡面找最短路徑,時間複雜讀為O(n^2)。 # dijjkstra演算法(原生最短路徑,還未優化) def dij(start,