給定乙個帶權有向圖(即有向網)g 和源點 v0,求 v0 到 g 中其他每個頂點的最短路徑。限定各邊上的權值大於或等於 0。
例如,在圖 4.1(a)中,假設源點為頂點 0,則源點到其他頂點的最短距離分別為:
頂點 0 到頂點 1 的最短路徑距離是:20,其路徑為 v0→v2→v1;
頂點 0 到頂點 2 的最短路徑距離是:5,其路徑為 v0→v2;
頂點 0 到頂點 3 的最短路徑距離是:22,其路徑為 v0→v2→v5→v3;
頂點 0 到頂點 4 的最短路徑距離是:28,其路徑為 v0→v2→v1→v4;
頂點 0 到頂點 5 的最短路徑距離是:12,其路徑為 v0→v2→v5。
這些最短路徑距離及對應的最短路徑是怎麼求出來的?
為求得這些最短路徑,dijkstra 提出按路徑長度的遞增次序,逐步產生最短路徑的演算法。首先求出長度最短的一條最短路徑,再參照它求出長度次短的一條最短路徑,依次類推,直到從源點v0 到其它各頂點的最短路徑全部求出為止。
例如在圖 4.1(a)中,要求頂點 0 到其他各頂點的最短距離分別是多少。其求解過程如圖 4.2所示。具體為:
1) 首先求出長度最短的一條最短路徑,即頂點 0 到頂點 2 的最短路徑,其長度為 5,其實就是頂點 0 到其他各頂點的直接路徑中最短的路徑(v0→v2)。
2) 頂點 2 的最短路徑求出來以後,頂點 0 到其他各頂點的最短路徑長度有可能要改變。例如從頂點 0 到頂點 1 的最短路徑長度由∞縮短為 20,從頂點 0 到頂點 5 的最短路徑長度也由∞縮短為 12。這樣長度次短的最短路徑長度就是在還未確定最終的最短路徑長度的頂點中選擇最小的,即頂點 0 到頂點 5 的最短路徑長度,為 12,其路徑為(v0→v2→v5)。
3) 頂點 5 的最短路徑求出來以後,頂點 0 到其他各頂點的最短路徑長度有可能要改變。例如從頂點 0 到頂點 3 的最短路徑長度由 30 縮短為 22,從頂點 0 到頂點 4 的最短路徑長度也由∞縮短為 30。這樣長度第三短的最短路徑長度就是在還未確定最終的最短路徑長度的頂點中選擇最小的,即頂點 0 到頂點 1 的最短路徑長度,為 20,其路徑為(v0→v2→v1)。
4) 此後再依次確定頂點 0 到頂點 3 的最短路徑(v0→v2→v5→v3),其長度為 22;以及頂點 0 到頂點 4 的最短路徑(v0→v2→v1→v4),其長度為 28。
在dijkstra 演算法裡,為了求源點 v0 到其他各頂點 vi 的最短路徑及其長度,需要設定 3 個陣列:
a) dist[n]:dist[i]表示當前找到的從源點 v0 到終點 vi 的最短路徑的長度,初始時,dist[i]為 edge[v0][i],即鄰接矩陣的第 v0 行。
b) s[n]:s[i]為 0 表示頂點 vi 還未加入到集合 s 中,s[i]為 1 表示 vi 已經加入到集合 s 中。初始時,s[v0]為 1,其餘為 0,表示最初集合 s 中只有頂點 v0。
c) path[n]:path[i]表示 v0 到 vi 的最短路徑上頂點 vi 的前乙個頂點序號。採用「倒向追蹤」的方法,可以確定 v0 到頂點 vi 的最短路徑上的每個頂點。在 dijkstra 演算法裡,重複做以下 3 步工作:
1) 在陣列 dist[n]裡查詢 s[i] != 1,並且 dist[i]最小的頂點 u;
2) 將 s[u]改為 1,表示頂點 u 已經加入進來了;
3) 修改 t 集合中每個頂點 vk 的 dist 及 path 陣列元素值:當 s[k] != 1,且頂點 u 到頂點 vk有邊(edge[u][k]**如下:
1 #include 2 #include該程式的執行示例如下:3#define inf 1000000 //
無窮大4
#define maxn 20 //
頂點個數的最大值56
int n; //
頂點個數
7int edge[maxn][maxn]; //
鄰接矩陣
8int visited[maxn]; //
用來劃分s,t集合的陣列(s:已訪問集合,t:未訪問集合)
9int dist[maxn]; //
儲存最短路徑
10int path[maxn]; //
儲存路徑
1112
void dijkstra(int v0) //
求頂點v0到其他頂點的最短路徑
1320 visited[v0] = 1;21
//dist[v0] = 0;
22//
從頂點v0確定n-1條最短路徑
23for(int i = 0; i < n-1; ++i) 31}
32 visited[u] = 1; //
將頂點u加入s集合,表示他的最短路徑已找到
33//
更新t集合中頂點的dist和path值
34for(int k = 1; k < n; ++k) 39}
40}41}
4243
intmain()
4452
for(int i = 0; i < n; ++i) 57}
58 dijkstra(0
);59
int shortest[maxn]; //
輸出最短路徑上的各個頂點時存放各個頂點的序號
60for(int i = 1; i < n; ++i)
68 ++k; shortest[k] = 0;69
for(int i = k; i > 0; --i)
70 printf("
%d->
", shortest[i]);
71 printf("
%d\n
", shortest[0
]);72}73
return0;
74 }
輸入:
60 2 5
0 3 30
1 0 2
1 4 8
2 5 7
2 1 15
4 3 4
5 3 10
5 4 18
-1 -1 -1
輸出:20 0→2→1
5 0→2
22 0→2→5→3
28 0→2→1→4
12 0→2→5
迪傑斯特拉演算法
if object id t test is not null drop table t test gocreate table dbo t test id int identity 1,1 not null primary key,自增字段,無意義 header varchar 500 第一點的名...
迪傑斯特拉演算法
dijkstra 迪傑斯特拉 演算法是典型的最短路徑路由演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。dijkstra演算法 能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。dijkstra演算法是很有代表性的最短...
迪傑斯特拉演算法
迪傑斯特拉演算法用來計算圖中某一點到其他點的最短距離,這個圖可以是加權,也可以是無權的,距離指的是從一點到其它點所經過的邊的權重和 假設現在有乙個加權無向圖,我們要求節點1到其他點的最短距離 初始化圖arr 用乙個鄰接矩陣來表示一張圖,矩陣元素 初始化一維向量d,這個向量儲存的是其他點的最短距離,初...