最短路徑:Dijkstra算法和Floyd算法

      最短路徑問題是圖論研究中的一個經典算法問題,旨在尋找圖(由結點和路徑組成的)中兩結點之間的最短路徑。算法具體的形式包括:

        1.確定起點的最短路徑問題:即已知起始結點,求最短路徑的問題。適合使用Dijkstra算法。

        2.確定終點的最短路徑問題:與確定起點的問題相反,該問題是已知終結結點,求最短路徑的問題。在無向圖中該問題與確定起點的問題完全等同,在有向圖中該問題等同於把所有路徑方向反轉的確定起點的問題。

        3.確定起點終點的最短路徑問題:即已知起點和終點,求兩結點之間的最短路徑。

        4.全局最短路徑問題:求圖中所有的最短路徑。適合使用Floyd算法。

        這裏只給出第1種和第四種情況下兩種算法的源代碼。

[objc] view plain copy
  1. #include "stdio.h"  
  2. #define MAX 99  
  3.   
  4. typedef struct                    //圖的鄰接矩陣存儲結構體定義  
  5. {  
  6.     int vexs[6];  
  7.     int arcs[6][6];  
  8.     int n, e;  
  9. }MGraph;  
  10.   
  11. void create(MGraph &G);                 //圖的創建  
  12. void Dijkstra(MGraph G, int u);         //Dijkstra算法  
  13. void Floyd(MGraph G);                   //Floyd算法  
  14.   
  15. int main()  
  16. {  
  17.     MGraph G;  
  18.     create(G);  
  19.     printf("最短路徑之Dijkstra算法:\n");  
  20.     Dijkstra(G, 0);  
  21.     printf("最短路徑之Floyd算法:\n");  
  22.     Floyd(G);  
  23.   
  24.     return 0;  
  25. }  
  26.   
  27. void create(MGraph &G)  
  28. {  
  29.     int i, j;  
  30.     printf("請輸入頂點數和邊數:\n");  
  31.     scanf("%d %d", &G.n, &G.e);  
  32.   
  33.     int b[10] = {0123456789};  
  34.     for(i = 0; i < G.n; ++i)  
  35.         G.vexs[i] = b[i];  
  36.     printf("頂點編號分別爲:\n");  
  37.     for(i = 0; i < G.n; ++i)  
  38.         printf("%d ", G.vexs[i]);  
  39.   
  40.     int a[6][6]={  
  41.         {03, MAX, MAX, MAX, MAX},  
  42.         {MAX, 02, MAX, 67},  
  43.         {MAX, MAX, 0134},   
  44.         {MAX, MAX, MAX, 01, MAX},  
  45.         {MAX, MAX, MAX, MAX, 01},   
  46.         {MAX, MAX, MAX, MAX, MAX, 0}  
  47.     };  
  48.     for(i = 0; i < 6; ++i)  
  49.         for(j = 0; j < 6; ++j)  
  50.               G.arcs[i][j]=a[i][j];  
  51.     printf("\n該圖的鄰接矩陣:\n");  
  52.     for(i = 0; i < G.n; ++i)  
  53.     {  
  54.         for(j = 0; j < G.n; ++j)  
  55.             printf("%d ", G.arcs[i][j]);  
  56.         printf("\n");  
  57.     }  
  58. }  
  59. //Dijkstra算法  
  60. void Dijkstra(MGraph G, int u)        //假設此處從頂點0開始  
  61. {  
  62.     int i, j, k, min;  
  63.     int pre[10], final[10], dist[10];  
  64.     for(j = 0; j < G.n; ++j)  
  65.     {  
  66.         dist[j] = G.arcs[u][j];  
  67.         if(G.arcs[u][j] == MAX)  
  68.             pre[j] = -1;  
  69.         else  
  70.             pre[j] = u;  
  71.         final[j] = 0;  
  72.     }  
  73.     for(i = 1; i < G.n; ++i)  
  74.     {  
  75.         min = MAX;  
  76.         for(j = 1; j < G.n; ++j)     //找出最小值的結點  
  77.             if( (!final[j]) && (min > dist[j]))  
  78.             {  
  79.                 min = dist[j];  
  80.                 k = j;  
  81.             }  
  82.         if(min == MAX)    //找不到  
  83.             break;  
  84.         final[k] = 1;   //加入該結點  
  85.         for(j = 1; j < G.n; ++j)  //更新最短路徑  
  86.         {  
  87.             if((!final[j]) && (dist[j] > (dist[k] + G.arcs[k][j])))  
  88.             {  
  89.                 dist[j] = dist[k] + G.arcs[k][j];  
  90.                 pre[j] = k;  
  91.             }  
  92.         }  
  93.     }  
  94.     for(i = 1; i < G.n; ++i)       //輸出路徑與距離  
  95.     {  
  96.         if(pre[i] == -1)  
  97.         {  
  98.             printf("頂點%d到源點%d不可達。\n", i, u);  
  99.             continue;  
  100.         }  
  101.         printf("(%d, %d) = %d\n", i, u, dist[i]);  
  102.         printf("路徑爲:");  
  103.         j = i;  
  104.         while(j)  
  105.         {  
  106.             printf("%d→", j);  
  107.             j = pre[j];  
  108.         }  
  109.         printf("0\n");  
  110.     }  
  111. }  
  112. //Floyd算法  
  113. void Floyd(MGraph G)  
  114. {  
  115.     int i, j, k, dist[10][10], pre[10];  
  116.     for(i = 0; i < G.n; ++i)  
  117.         for(j = 0; j < G.n; ++j)  
  118.         {  
  119.             dist[i][j] = G.arcs[i][j];  
  120.             if(dist[i][j] != MAX)  
  121.                 pre[j] = i;  
  122.             else  
  123.                 pre[j] = -1;  
  124.         }  
  125.               
  126.     for(k = 0; k < G.n; ++k)  
  127.         for(i = 0; i < G.n; ++i)  
  128.             for(j = 0; j < G.n; ++j)  
  129.                 if((i != j) && (dist[i][j] > dist[i][k] + dist[k][j]))  
  130.                 {  
  131.                     dist[i][j] = dist[i][k] + dist[k][j];  
  132.                     if(dist[i][j] != MAX)  
  133.                     {  
  134.                         pre[j] = k;  
  135.                         pre[k] = i;  
  136.                     }  
  137.                     else  
  138.                         pre[j] = -1;  
  139.                 }  
  140.     for(i = 0; i < G.n; ++i)  
  141.         for(j = 0; j < G.n; ++j)  
  142.         {  
  143.             if(dist[i][j] == MAX)  
  144.                 continue;  
  145.             else if(i != j)  
  146.                 printf("(%d, %d) = %d\n", i, j, dist[i][j]);  
  147.         }  
  148.     printf("其餘頂點之間不可達!\n");  
  149. }  

示例:(讀者可自行驗證)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章