1. 程式人生 > >Floyd演算法求最短路問題

Floyd演算法求最短路問題

Floyd演算法適用於APSP(All Pairs Shortest Paths,多源最短路徑),是一種動態規劃演算法,稠密圖效果最佳,邊權可正可負。此演算法簡單有效,由於三重迴圈結構緊湊,對於稠密圖,效率要高於執行|V|次Dijkstra演算法,也要高於執行V次SPFA演算法。

優點:容易理解,可以算出任意兩個節點之間的最短距離,程式碼編寫簡單。
缺點:時間複雜度比較高,不適合計算大量資料。

給出兩個通用的程式

  • 程式1
%floyd演算法通用程式,輸入a為賦權鄰接矩陣
%輸出為距離矩陣D,和最短路徑矩陣path
clc
clear
a=[Inf,Inf,10,Inf,30
,100;Inf,Inf,5,Inf,Inf,Inf;Inf,Inf,Inf,50,Inf,Inf;Inf,Inf,Inf,Inf,Inf,10;Inf,Inf,Inf,20,Inf,60;Inf,Inf,Inf,Inf,Inf,Inf]
;%鄰接矩陣 s=1; t=6;%這裡設定哪到哪的最短路 n=size(a,1); D=a; path=zeros(n,n); for i=1:n for j=1:n if D(i,j)~=inf path(i,j)=j; end end end for k=1:n for i=1:n for
j=1:n if D(i,k)+D(k,j)<D(i,j) D(i,j)=D(i,k)+D(k,j); path(i,j)=path(i,k); end end end end %% 配合floyd演算法的後續程式,s為源點,t為宿點 %L為長度,R為路由 %若出現提示形如“試圖訪問 D(0,2);索引必須為正整數或邏輯值”提示說明不存在最短路 L=zeros(0,0); R=s; while 1 if s==t L=fliplr
(L); L=[0,L]; return end if D(s,t)==Inf L=Inf;break; else L=[L,D(s,t)]; R=[R,path(s,t)]; s=path(s,t); end end a;%a為輸入的鄰接矩陣 D;%輸出兩點間的最短路長 path;%輸出路由矩陣,即最短路徑矩陣,雖然我也不懂是啥 L=L(length(L))%L的最後一位即為s到t的最短路長 key R%這裡輸出最短路的路徑 key
  • 程式2
clear;
clc;
n=6; 
a=zeros(n);
a(1,2)=50;
a(1,4)=40;
a(1,5)=25;
a(1,6)=10; 
a(2,3)=15;
a(2,4)=20;
a(2,6)=25;
a(3,4)=10;
a(3,5)=20; 
a(4,5)=10;
a(4,6)=25; 
a(5,6)=55;
a=a+a';
M=max(max(a))*n^2; 
%M為充分大的正實數 
a=a+((a==0)-eye(n))*M;
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
  • 另外,求一個城市到另一個城市的最短路還可以用如下方法:
%求第一個城市到其它城市的短路徑的 Matlab 程式如下:
clc,clear
a=zeros(6); 
a(1,2)=50;
a(1,4)=40;
a(1,5)=25;
a(1,6)=10; 
a(2,3)=15;
a(2,4)=20;
a(2,6)=25; 
a(3,4)=10;
a(3,5)=20; 
a(4,5)=10;
a(4,6)=25;
a(5,6)=55;
a=a+a'; 
a(find(a==0))=inf;
pb(1:length(a))=0;
pb(1)=1;index1=1;
index2=ones(1,length(a)); 
d(1:length(a))=inf;
d(1)=0;temp=1; 
while sum(pb)<length(a)   
    tb=find(pb==0);    
    d(tb)=min(d(tb),d(temp)+a(temp,tb));
    tmpb=find(d(tb)==min(d(tb)));   
    temp=tb(tmpb(1));   
    pb(temp)=1;    
    index1=[index1,temp];  
    temp2=find(d(index1)==d(temp)-a(temp,index1));
    index2(temp)=index1(temp2(1)); 
end
d, index1, index2