Dijkstra演算法詳解

2021-09-28 19:26:34 字數 2434 閱讀 7837

** :

迪傑斯特拉(dijkstra)演算法是典型最短路徑演算法,用於計算乙個節點到其他節點的最短路徑。 

它的主要特點是以起始點為中心向外層層擴充套件(廣度優先搜尋思想),直到擴充套件到終點為止

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

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

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

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

從u中選出」距離最短的頂點k」,並將頂點k加入到s中;同時,從u中移除頂點k。

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

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

單純的看上面的理論可能比較難以理解,下面通過例項來對該演算法進行說明。

以上圖g4為例,來對迪傑斯特拉進行演算法演示(以第4個頂點d為起點)。注:以下圖中所有b(23)應改為b(13)。

初始狀態:s是已計算出最短路徑的頂點集合,u是未計算除最短路徑的頂點的集合!

第1步:將頂點d加入到s中。 

此時,s=, u=。 注:c(3)表示c到起點d的距離是3。

第2步:將頂點c加入到s中。 

上一步操作之後,u中頂點c到起點d的距離最短;因此,將c加入到s中,同時更新u中頂點的距離。以頂點f為例,之前f到d的距離為∞;但是將c加入到s之後,f到d的距離為9=(f,c)+(c,d)。 

此時,s=, u=。

第3步:將頂點e加入到s中。 

上一步操作之後,u中頂點e到起點d的距離最短;因此,將e加入到s中,同時更新u中頂點的距離。還是以頂點f為例,之前f到d的距離為9;但是將e加入到s之後,f到d的距離為6=(f,e)+(e,d)。 

此時,s=, u=。

第4步:將頂點f加入到s中。 

此時,s=, u=。

第5步:將頂點g加入到s中。 

此時,s=, u=。

第6步:將頂點b加入到s中。 

此時,s=, u=。

第7步:將頂點a加入到s中。 

此時,s=。

此時,起點d到各個頂點的最短距離就計算出來了:a(22) b(13) c(3) d(0) e(4) f(6) g(12)。

// 鄰接矩陣

typedef struct _graph

graph, *pgraph;

// 邊的結構體

typedef struct _edgedata

edata;

迪傑斯特拉演算法

/** dijkstra最短路徑。

* 即,統計圖(g)中"頂點vs"到其它各個頂點的最短路徑。

** 引數說明:

*        g -- 圖

*       vs -- 起始頂點(start vertex)。即計算"頂點vs"到其它頂點的最短路徑。

*     prev -- 前驅頂點陣列。即,prev[i]的值是"頂點vs"到"頂點i"的最短路徑所經歷的全部頂點中,位於"頂點i"之前的那個頂點。

*     dist -- 長度陣列。即,dist[i]是"頂點vs"到"頂點i"的最短路徑的長度。

*/void dijkstra(graph g, int vs, int prev, int dist)

// 對"頂點vs"自身進行初始化

flag[vs] = 1;

dist[vs] = 0;

// 遍歷g.vexnum-1次;每次找出乙個頂點的最短路徑。

for (i = 1; i < g.vexnum; i++)}}

// 列印dijkstra最短路徑的結果

printf("dijkstra(%c): \n", g.vexs[vs]);

for (i = 0; i < g.vexnum; i++)

printf("  shortest(%c, %c)=%d\n", g.vexs[vs], g.vexs[i], dist[i]);

}

Dijkstra演算法詳解

在解決單源點最短路徑的問題時,常常用到經典的dijkstra演算法,其演算法的本質思想是 按路徑長度遞增依次產生最短路徑。下面給出演算法的大致流程 1.初始化所有結點並將起始點設為標記,進入以下迴圈 2.在到達某點的最短路徑中找最小且未標記的點 可以用一維陣列表示 如 陣列下標 0 1 2 3 4 ...

Dijkstra演算法詳解

dijkstra演算法是由e.w.dijkstra於1959年提出,又叫迪傑斯特拉演算法,它應用了貪心演算法模式,是目前公認的最好的求解最短路徑的方法。演算法解決的是有向圖中單個源點到其他頂點的最短路徑問題,其主要特點是每次迭代時選擇的下乙個頂點是標記點之外距離源點最近的頂點。但由於dijkstra...

Dijkstra演算法詳解

前幾天研究的bellman ford演算法雖然可以算負權,可是時間複雜度高達o nm 即使是採用了佇列優化,也有可能被網格圖卡回o nm 所以今天我們就來研究乙個新的,更快的,但同時只能在正權圖上執行的演算法 dijkstra 樸素dijkstra演算法 我們首先需要以下幾個陣列 dist,vis,...