1. 程式人生 > >演算法分析與設計課程設計-Dijkstra最短路徑演算法

演算法分析與設計課程設計-Dijkstra最短路徑演算法

演算法分析與設計課程設計報告書      

 

題目:Dijkstra最短路徑演算法

設計人:張欽穎

班級:14計科2班    學號:1414080901218

 

一、     實驗環境:

1、硬體環境:個人機,CPU主頻:4.01Ghz  記憶體:16G

2、軟體環境:作業系統:win10

程式語言:C++

 

二、     實驗任務解決方案:

1、         Dijkstra最短路徑演算法的流程圖。

(1)  建立一組sptSet(最短路徑陣列),它存的是已經在SPT裡的節點,也就是這些是已經計算過的,確定的最小值,一開始這裡是空的。

(2)  給所有的給定圖中的節點一個指定的距離值。將所有的距離值初始化為無限,將源節點初始為0

(3)  當另一個(儲存未放入SPT的節點的那個)不為空時:

① 選擇一個不在SPTset中一個離源點距離最小的節點

② 把它加入SPTset

③ 更新所有於這個節點臨近的節點的距離值。為了更距離值,遍歷這個點所有的相鄰點。對於每一個相鄰的節點,如果這臨近點u

的距離值(從源節點開始的和)比v(新 加入的)小,就把v的距離值更新

例如:


一開始SPTset是空的,並且它初始化的距離值是{0無限無限無限無限無限無限無限}。現在選擇最小距離值的頂點。我們選了節點0,將它加入到sptSet。所以sptSet變為{0}。加入0sptSet後,更新其相鄰頂點的距離值。0相鄰的節點為16,他們的距離值便被更新成34。圖中標示出在SPT的頂點顯示為綠色。


然後我們選擇一個不包含在SPT裡一個路徑值為最小的一個節點,節點1被選了而且被加入到了sptSET,所以sptSET現在變為了{0,1}更新1臨近節點的距離值,臨近節點為28,節點

28的距離值便變成了3+6=93+16=19


像上面一樣選一個,我們選了節點6,加入到sptSet,所以sptSet變成了{0,1,6},更新節點6的臨近節點的距離值,臨近節點是57,更新後54+20=2474+10=14

 

然後我們再選一個2加入,sptSet又新來了一個數字22的臨近節點38便更新為1126.


一直重複這些事兒直到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得出程式碼來,否則根本無從下手。