演算法分析與設計課程設計-Dijkstra最短路徑演算法
演算法分析與設計課程設計報告書
設計人:張欽穎
班級:14計科2班 學號:1414080901218
一、 實驗環境:
1、硬體環境:個人機,CPU主頻:4.01Ghz 記憶體:16G
2、軟體環境:作業系統:win10
程式語言:C++
二、 實驗任務解決方案:
1、 Dijkstra最短路徑演算法的流程圖。
(1) 建立一組sptSet(最短路徑陣列),它存的是已經在SPT裡的節點,也就是這些是已經計算過的,確定的最小值,一開始這裡是空的。
(2) 給所有的給定圖中的節點一個指定的距離值。將所有的距離值初始化為無限,將源節點初始為0。
(3) 當另一個(儲存未放入SPT的節點的那個)不為空時:
① 選擇一個不在SPTset中一個離源點距離最小的節點
② 把它加入SPTset
③ 更新所有於這個節點臨近的節點的距離值。為了更距離值,遍歷這個點所有的相鄰點。對於每一個相鄰的節點,如果這臨近點u
例如:
一開始SPTset是空的,並且它初始化的距離值是{0,無限,無限,無限,無限,無限,無限,無限}。現在選擇最小距離值的頂點。我們選了節點0,將它加入到sptSet。所以sptSet變為{0}。加入0至sptSet後,更新其相鄰頂點的距離值。0相鄰的節點為1和6,他們的距離值便被更新成3和4。圖中標示出在SPT的頂點顯示為綠色。
然後我們選擇一個不包含在SPT裡一個路徑值為最小的一個節點,節點1被選了而且被加入到了sptSET,所以sptSET現在變為了{0,1}更新1臨近節點的距離值,臨近節點為2跟8,節點
像上面一樣選一個,我們選了節點6,加入到sptSet,所以sptSet變成了{0,1,6},更新節點6的臨近節點的距離值,臨近節點是5和7,更新後5:4+20=24,7:4+10=14
然後我們再選一個2加入,sptSet又新來了一個數字2,2的臨近節點3和8便更新為11和26.
一直重複這些事兒直到sptset包含所有的節點:
最後,我們終於得到了一棵完整的最短路徑樹
2、Dijkstra最短路徑演算法實現的關鍵程式碼。
#include <stdio.h>
#include <limits.h>
// Number of vertices in the graph
#define V 9
// A utility function to find the vertex with minimum distance value,from
// the set of vertices not yet included in shortest path tree
int minDistance(int dist[], bool sptSet[])
{
// Initialize min value
int min = INT_MAX,min_index;
for (int v = 0; v < V;v++)
if (sptSet[v] == false&& dist[v] < min)
min = dist[v],min_index = v;
return min_index;
}
// A utility function to print the constructed distance array
void printSolution(int dist[], int n)
{
printf("頂點\t\t距離源點的最短路徑\n");
for (int i = 0; i < V;i++)
printf("%d\t\t%d\n", i, dist[i]);
}
// Funtion that implements Dijkstra's single source shortest pathalgorithm
// for a graph represented using adjacency matrix representation
void dijkstra(int graph[V][V], int src)
{
int dist[V]; // The output array. dist[i] will hold the shortest
// distance from src to i
bool sptSet[V]; // sptSet[i]will true if vertex i is included in shortest
// path tree or shortestdistance from src to i is finalized
// Initialize all distancesas INFINITE and stpSet[] as false
for (int i = 0; i < V;i++)
dist[i] = INT_MAX,sptSet[i] = false;
// Distance of source vertexfrom itself is always 0
dist[src] = 0;
// Find shortest path forall vertices
for (int count = 0; count< V - 1; count++)
{
// Pick the minimumdistance vertex from the set of vertices not
// yet processed. u isalways equal to src in first iteration.
int u =minDistance(dist, sptSet);
// Mark the pickedvertex as processed
sptSet[u] = true;
// Update dist value ofthe adjacent vertices of the picked vertex.
for (int v = 0; v < V; v++)
// Update dist[v]only if distance to v is not in sptSet, there
// is an edgefrom u to v, and total weight of path from src to
// v through u issmaller than dist[v]
if (!sptSet[v]&& graph[u][v] && dist[u] + graph[u][v] < dist[v])
dist[v] = dist[u]+ graph[u][v];
}
// print the constructeddistance array
printSolution(dist, V);
}
// driver program to test above function
int main()
{
/* Let us create the examplegraph discussed above */
int graph[V][V] = {
{ 0, 3, 0, 0, 0, 0, 4,0, 0 },
{ 3, 0, 6, 0, 0, 0, 0,0, 16 },
{ 0, 6, 0, 2, 0, 0, 0,0, 17 },
{ 0, 0, 2, 0, 4, 0, 0,0, 9 },
{ 0, 0, 0, 4, 0, 11, 0,7, 0 },
{ 0, 0, 0, 0, 11, 0,20, 0, 0 },
{ 4, 0, 0, 0, 0, 20, 0,10, 0 },
{ 0, 0, 0, 0, 7, 0, 10,0, 1 },
{ 0, 16, 17, 9, 0, 0,0, 1, 0 }
};
dijkstra(graph, 0);
return 0;
}
三、 Dijkstra最短路徑演算法的計算複雜度分析(最好、最差、平均情況複雜度):
(1) 最好的情況:每個頂點第一次檢測到就是路徑值就是最短路徑。複雜度最低。
複雜度為:2n²+6n
(2) 最壞情況:頂點被檢測了1次以上,並且每次檢測都更新路徑值為最小,即每次找的都不是最短路徑,直到最後一次檢測。複雜度最高
複雜度為:3n²+6n
(3) 平均情況複雜度:時間複雜度為O(n²)
四、 總結綜合實驗心得體會:
本次的Dijkstra最短路徑演算法在資料結構的課程上也接觸過,所以感覺這個不成問題,選用的例子是自己隨手畫出來的,然後按照Dijkstra最短路徑演算法把流程步驟分別畫了出來。然後其他部分參考了一下wiki以及geek論壇等國外大神的論文。還有很多東西老師在課堂上也給我們又講了一遍,所以從演算法思想上就不成多大問題了,主要是程式碼,而且必須得了解了演算法才能mark得出程式碼來,否則根本無從下手。