最短路徑—Floyd算法


Floyd算法

所有頂點對之間的最短路徑問題是:對於給定的有向網絡G=(V,E),要對G中任意兩個頂點v,w(v不等於w),找出v到w的最短路徑。當然我們可以n次執行DIJKSTRA算法,用FLOYD則更為直接,兩種方法的時間復雜度都是一樣的。

 

1.定義概覽

Floyd-Warshall算法(Floyd-Warshall algorithm)是解決任意兩點間的最短路徑的一種算法,可以正確處理有向圖或負權的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。Floyd-Warshall算法的時間復雜度為O(N3),空間復雜度為O(N2)。

 

2.算法描述

1)算法思想原理:

     Floyd算法是一個經典的動態規划算法。用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規划的角度看問題,我們需要為這個目標重新做一個詮釋(這個詮釋正是動態規划最富創造力的精華所在)

      從任意節點i到任意節點j的最短路徑不外乎2種可能,1是直接從i到j,2是從i經過若干個節點k到j。所以,我們假設Dis(i,j)為節點u到節點v的最短路徑的距離,對於每一個節點k,我們檢查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,證明從i到k再到j的路徑比i直接到j的路徑短,我們便設置Dis(i,j) = Dis(i,k) + Dis(k,j),這樣一來,當我們遍歷完所有節點k,Dis(i,j)中記錄的便是i到j的最短路徑的距離。

2).算法描述:

a.從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大。   

b.對於每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比己知的路徑更短。如果是更新它。

以下面的有向網絡為例:

 

 

 1 #include<stdio.h>
 2 #define n 5   //結點數目
 3 #define maxsize 160  //表示兩點間不可達
 4 int path[n][n];//路徑矩陣
 5 void floyd(int A[][n],int C[][n]);  //A是路徑長度矩陣,C是有向網絡G的帶權鄰接矩陣
 6 void main()  7 {  8  printf(" ——所有頂點對之間的最短路徑:Floyd算法——\n");  9  printf("(160為無窮遠,不可達)\n");  10  int A[n][n],C[n][n]={  11   {0,10,maxsize,30,100},  12   {maxsize,0,50,maxsize,maxsize},  13   {maxsize,maxsize,0,maxsize,10},  14   {maxsize,maxsize,20,0,60},  15   {maxsize,maxsize,maxsize,maxsize,0}  16  };  17  floyd(A,C);  18 }  19 void floyd(int A[][n],int C[][n])  //A是路徑長度矩陣,C是有向網絡G的帶權鄰接矩陣
 20 {  21  int i,j,k,next;  22  int max=160;  23  for(i=0;i<n;i++)//設置A和path的初值
 24  {  25   for(j=0;j<n;j++)  26  {  27    if(C[i][j]!=max)  28     path[i][j]=j;   //j是i的后繼
 29    else
 30     path[i][j]=0;  31    A[i][j]=C[i][j];  32  }  33  }  34  for(k=0;k<n;k++)  35  //做n次迭代,每次均試圖將頂點k擴充到當前求得的從i到j的最短路徑Pij上
 36  {  37   for(i=0;i<n;i++)  38  {  39    for(j=0;j<n;j++)  40  {  41     if(A[i][j]>(A[i][k]+A[k][j]))  42  {  43      A[i][j]=A[i][k]+A[k][j];  //修改長度
 44      path[i][j]=path[i][k];    //修改路徑
 45  }  46  }  47  }  48  }  49  for(i=0;i<n;i++)//輸出所有頂點對i,j之間的最短路徑Pij的長度及路徑
 50  {  51   for(j=0;j<n;j++)  52  {  53    if(i!=j)  54  {  55     printf("%d到%d的最短距離為",i+1,j+1);  56     printf("%d\n",A[i][j]);   //輸出Pij的長度
 57     next=path[i][j];        //next為起點i的后繼頂點
 58     printf("輸出路徑:\n");  59     if(next==0)  60      printf("%d到%d不可達\n",i+1,j+1);  61     else//Pij存在
 62  {  63      printf("%d",i+1);  64      while(next!=j)  65  {  66       printf("——>%d",next+1);  //打印后繼點
 67       next=path[next][j];        //繼續找下一個后繼點
 68  }  69      printf("——>%d\n",j+1);       //打印終點
 70  }  71     printf("****************************************************\n");  72  }  73  }  74  }  75 }  76  
 77  
 78 運行結果:  79  ——所有頂點對之間的最短路徑:Floyd算法——  80 (160為無窮遠,不可達)  81 1到2的最短距離為10  82 輸出路徑:  83 1——>2
 84 ****************************************************
 85 1到3的最短距離為50  86 輸出路徑:  87 1——>4——>3
 88 ****************************************************
 89 1到4的最短距離為30  90 輸出路徑:  91 1——>4
 92 ****************************************************
 93 1到5的最短距離為60  94 輸出路徑:  95 1——>4——>3——>5
 96 ****************************************************
 97 2到1的最短距離為160  98 輸出路徑:  99 2到1不可達 100 ****************************************************
101 2到3的最短距離為50 102 輸出路徑: 103 2——>3
104 ****************************************************
105 2到4的最短距離為160 106 輸出路徑: 107 2到4不可達 108 ****************************************************
109 2到5的最短距離為60 110 輸出路徑: 111 2——>3——>5
112 ****************************************************
113 3到1的最短距離為160 114 輸出路徑: 115 3到1不可達 116 ****************************************************
117 3到2的最短距離為160 118 輸出路徑: 119 3到2不可達 120 ****************************************************
121 3到4的最短距離為160 122 輸出路徑: 123 3到4不可達 124 ****************************************************
125 3到5的最短距離為10 126 輸出路徑: 127 3——>5
128 ****************************************************
129 4到1的最短距離為160 130 輸出路徑: 131 4到1不可達 132 ****************************************************
133 4到2的最短距離為160 134 輸出路徑: 135 4到2不可達 136 ****************************************************
137 4到3的最短距離為20 138 輸出路徑: 139 4——>3
140 ****************************************************
141 4到5的最短距離為30 142 輸出路徑: 143 4——>3——>5
144 ****************************************************
145 5到1的最短距離為160 146 輸出路徑: 147 5到1不可達 148 ****************************************************
149 5到2的最短距離為160 150 輸出路徑: 151 5到2不可達 152 ****************************************************
153 5到3的最短距離為160 154 輸出路徑: 155 5到3不可達 156 ****************************************************
157 5到4的最短距離為160 158 輸出路徑: 159 5到4不可達 160 ****************************************************
View Code

 參考:http://blog.sina.com.cn/s/blog_686d0fb001012r05.html

http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM