簡介
Floyd算法又稱為插點法,是一種利用動態規划的思想尋找給定的加權圖中多源點之間最短路徑的算法,與Dijkstra算法類似。該算法名稱以創始人之一、1978年圖靈獎獲得者、斯坦福大學計算機科學系教授羅伯特·弗洛伊德命名。
算法過程及優缺點
1,從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大。
2,對於每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比已知的路徑更短。如果是更新它。
把圖用鄰接矩陣G表示出來,如果從Vi到Vj有路可達,則G[i][j]=d,d表示該路的長度;否則G[i][j]=無窮大。定義一個矩陣D用來記錄所插入點的信息,D[i][j]表示從Vi到Vj需要經過的點,初始化D[i][j]=j。把各個頂點插入圖中,比較插點后的距離與原來的距離,G[i][j] = min( G[i][j], G[i][k]+G[k][j] ),如果G[i][j]的值變小,則D[i][j]=k。在G中包含有兩點之間最短道路的信息,而在D中則包含了最短通路徑的信息。
比如,要尋找從V5到V1的路徑。根據D,假如D(5,1)=3則說明從V5到V1經過V3,路徑為{V5,V3,V1},如果D(5,3)=3,說明V5與V3直接相連,如果D(3,1)=1,說明V3與V1直接相連。
優缺點:
Floyd算法適用於APSP(AllPairsShortestPaths),是一種動態規划算法,稠密圖效果最佳,邊權可正可負。此算法簡單有效,由於三重循環結構緊湊,對於稠密圖,效率要高於執行|V|次Dijkstra算法。
優點:容易理解,可以算出任意兩個節點之間的最短距離,代碼編寫簡單
缺點:時間復雜度比較高,不適合計算大量數據。
時間復雜度:O(n^3);空間復雜度:O(n^2);
任意節點i到j的最短路徑兩種可能:
- 直接從i到j;
- 從i經過若干個節點k到j。
實例
120 | 40 | |||
---|---|---|---|---|
120 | 40 | 20 | ||
30 | 20 | 30 | ||
40 | 20 | |||
20 | 30 |
clc,clear; n=5;sb=1;db=5; % sb起點標號,db終點標號 a=zeros(n); a(1,3)=40;a(1,2)=120; a(2,5)=20;a(2,4)=40; a(3,4)=20;a(3,5)=30; a = a+a'; a(a==0)=inf; a([1:n+1:n^2])=0; %對角線元素替換成0 path=zeros(n); for k=1:n for i=1:n for j=1:n if a(i,j)>a(i,k)+a(k,j) a(i,j)=a(i,k)+a(k,j); path(i,j)=k; end end end end %a,path dist=a(sb,db); parent=path(sb,:); parent(parent==0)=sb; mypath=db;t=db; while t~=sb p=parent(t);mypath=[p,mypath]; t=p; end path,mypath
Lingo
1.@text函數
該函數被用在數據部分用來把解輸出至文本文件中。它可以輸出集成員和集屬性值。其語法為
@text([’filename’])
這里filename是文件名,可以采用相對路徑和絕對路徑兩種表示方式。如果忽略filename,那么數據就被輸出到標准輸出設備(大多數情形都是屏幕)。@text函數僅能出現在模型數據部分的一條語句的左邊,右邊是集名(用來輸出該集的所有成員名)或集屬性名(用來輸出該集屬性的值)。
我們把用接口函數產生輸出的數據聲明稱為輸出操作。輸出操作僅當求解器求解完模型后才執行,執行次序取決於其在模型中出現的先后。
model: sets: nodes/c1..c5/; link(nodes,nodes):w,path; endsets data: path=0; w=0; @text(mydata1.txt)=@writefor(nodes(i):@writefor(nodes(j):@format(w(i,j),'10.0f')),@newline(1)); @text(mydata1.txt)=@write(@newline(1)); @text(mydata1.txt)=@writefor(nodes(i):@writefor(nodes(j):@format(path(i,j),'10.0f')),@newline(1)); enddata calc: w(1,3)=40;W(1,2)=120; w(2,5)=20;w(2,4)=40; w(3,4)=20;w(3,5)=30; @for(link(i,j):w(i,j)=w(i,j)+w(j,i)); @for(link(i,j):w(i,j)=@if(w(i,j) #eq# 0,1000,w(i,j))); @for(nodes(k):@for(nodes(i):@for(nodes(j): tm=@smin(w(i,j),w(i,k)+w(k,j)); path(i,j)=@if(w(i,j)#gt#tm,k,path(i,j));w(i,j)=tm))); endcalc end
mydata1.txt 內容如下:
C++
#include<fstream> #define Maxm 501 using namespace std; ifstream fin("APSP.in.txt"); ofstream fout("APSP.out.txt"); int p, q, k, m; int Vertex, Line[Maxm]; int Path[Maxm][Maxm], Map[Maxm][Maxm], Dist[Maxm][Maxm]; void Root(int p, int q) { if (Path[p][q] > 0) { Root(p, Path[p][q]); Root(Path[p][q], q); } else { Line[k] = q; k++; } } int main() { memset(Path, 0, sizeof(Path)); memset(Map, 0, sizeof(Map)); memset(Dist, 0, sizeof(Dist)); fin >> Vertex; for (p = 1; p <= Vertex; p++) for (q = 1; q <= Vertex; q++) { fin >> Map[p][q]; Dist[p][q] = Map[p][q]; } for (k = 1; k <= Vertex; k++) for (p = 1; p <= Vertex; p++) if (Dist[p][k] > 0) for (q = 1; q <= Vertex; q++) if (Dist[k][q] > 0) { if (((Dist[p][q] > Dist[p][k] + Dist[k][q]) || (Dist[p][q] == 0)) && (p != q)) { Dist[p][q] = Dist[p][k] + Dist[k][q]; Path[p][q] = k; } } for (p = 1; p <= Vertex; p++) { for (q = p + 1; q <= Vertex; q++) { fout << "\n==========================\n"; fout << "Source:" << p << '\n' << "Target " << q << '\n'; fout << "Distance:" << Dist[p][q] << '\n'; fout << "Path:" << p; k = 2; Root(p, q); for (m = 2; m <= k - 1; m++) fout << "-->" << Line[m]; fout << '\n'; fout << "==========================\n"; } } fin.close(); fout.close(); return 0; }
結果(APSP.out.txt):
========================== Source:1 Target 2 Distance:90 Path:1-->3-->5-->2 ========================== ========================== Source:1 Target 3 Distance:40 Path:1-->3 ========================== ========================== Source:1 Target 4 Distance:60 Path:1-->3-->4 ========================== ========================== Source:1 Target 5 Distance:70 Path:1-->3-->5 ========================== ========================== Source:2 Target 3 Distance:50 Path:2-->5-->3 ========================== ========================== Source:2 Target 4 Distance:40 Path:2-->4 ========================== ========================== Source:2 Target 5 Distance:20 Path:2-->5 ========================== ========================== Source:3 Target 4 Distance:20 Path:3-->4 ========================== ========================== Source:3 Target 5 Distance:30 Path:3-->5 ========================== ========================== Source:4 Target 5 Distance:50 Path:4-->3-->5 ==========================