當前位置:首頁 » 操作系統 » 實現floyd演算法

實現floyd演算法

發布時間: 2022-10-23 18:30:26

1. 用你熟悉的語言實現Floyd演算法,對於具有下面權重矩陣的有向圖求解完全最短路徑,截圖給出運行結果

Floyd的關鍵是三重循環和鬆弛式d[i][j] = min(d[i][j], d[i][k] + d[k][j]),代碼和注釋如下所示:

#include<bits/stdc++.h>
usingnamespacestd;

constintINF=1000000000;

constintn=5;

//鄰接矩陣
intd[][n]={
{0,2,INF,1,8},
{6,0,3,2,INF},
{INF,INF,0,4,INF},
{INF,INF,2,0,3},
{3,INF,INF,INF,0}
};
intmain()
{
//floyd
for(intk=0;k<n;++k)
for(inti=0;i<n;++i)
for(intj=0;j<n;++j)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);

//輸出結果
for(inti=0;i<n;++i){
for(intj=0;j<n;++j){
if(j>0)printf("");
if(d[i][j]==INF)printf("INF");
elseprintf("%3d",d[i][j]);
}
puts("");
}
return0;
}

運行結果圖:

2. Floyd演算法的介紹

Floyd演算法又稱為插點法,是一種用於尋找給定的加權圖中多源點之間最短路徑的演算法。該演算法名稱以創始人之一、1978年圖靈獎獲得者、斯坦福大學計算機科學系教授羅伯特·弗洛伊德命名。

3. matlab floyd 演算法注釋

A矩陣是鄰接矩陣,對角線上為o,其餘位置數字表示的是兩點之間距離,比如A(1,2)=2,表示從第一個點到第二個點的距離為2.inf是無窮大的意思,這里表示沒有直接溝通這兩點的路。
n=length(D);設定n為D矩陣的長度。
接下來的兩重循環,得到的R矩陣是n*n的矩陣,它每個數據表示的是路徑,比如:R(1,3)=1;表示路徑為:1-1-3.這里是初始化路徑了。
後面的三重循環是floyd演算法的關鍵所在,就是更新路線了。裡面的那個判斷指的是:
假設有3個點,1 2 3;如果我從1-2-3之間總距離小於1-3的距離,那麼我R(1,3)=2;這就是選取更近的路線了。
最後的兩個判斷是為了不讓曾經走過的點再次被遍歷。就是不回頭的意思了,這個一般都可以忽略了,你照打上去就是了。
不知道這樣的解釋你是否滿意。

4. floyd演算法

這是由其演算法本身所決定的,其每一步求出任意一對頂點之間僅通過中間節點1,2,...,k的最短距離,當1,2,...,k擴展到所有頂點時,演算法解出任意一對頂點間的最短距離,故順序自然是:
for(k=1;k<n;++k)
//枚舉任意一對頂點
由其狀態轉移方程來看,這個演算法的順序也很清晰,應該是先計算較小的k時任意ij之間的最短距離:
dij(k) = wij 如果k=0
min(dij(k-1),dik(k-1)+dkj(k-1)) 如果k>=1
其中i,j表示點對,k表示第1,2,...,k時的最短路徑

5. Floyd演算法的參考代碼

function Floyd(w,router_direction,MAX)
%w為此圖的距離矩陣
%router_direction為路由類型:0為前向路由;非0為回溯路由
%MAX是數據輸入時的∞的實際值
len=length(w);
flag=zeros(1,len);
%根據路由類型初始化路由表
R=zeros(len,len);
for i=1:len
if router_direction==0%前向路由
R(:,i)=ones(len,1)*i;
else %回溯路由
R(i,:)=ones(len,1)*i;
end
R(i,i)=0;
end
disp('');
disp('w(0)');
dispit(w,0);
disp('R(0)');
dispit(R,1);
%處理端點有權的問題
for i=1:len
tmp=w(i,i)/2;
if tmp~=0
w(i,:)=w(i,:)+tmp;
w(:,i)=w(:,i)+tmp;
flag(i)=1;
w(i,i)=0;
end
end
%Floyd演算法具體實現過程
for i=1:len
for j=1:len
if j==i || w(j,i)==MAX
continue;
end
for k=1:len
if k==i || w(j,i)==MAX
continue;
end
if w(j,i)+w(i,k)<w(j,k) %Floyd演算法核心代碼
w(j,k)=w(j,i)+w(i,k);
if router_direction==0%前向路由
R(j,k)=R(j,i);
else %回溯路由
R(j,k)=R(i,k);
end
end
end
end
%顯示每次的計算結果
disp(['w(',num2str(i),')'])
dispit(w,0);
disp(['R(',num2str(i),')'])
dispit(R,1);
end
%中心和中點的確定
[Center,index]=min(max(w'));
disp(['中心是V',num2str(index)]);
[Middle,index]=min(sum(w'));
disp(['中點是V',num2str(index)]);
end
function dispit(x,flag)
%x:需要顯示的矩陣
%flag:為0時表示顯示w矩陣,非0時表示顯示R矩陣
len=length(x);
s=[];
for j=1:len
if flag==0
s=[s sprintf('%5.2f ',x(j,:))];
else
s=[s sprintf('%d ',x(j,:))];
end
s=[s sprintf(' ')];
end
disp(s);
disp('---------------------------------------------------');
end
% 選擇後按Ctrl+t取消注釋號%
%
% 示例:
% a=[
% 0,100,100,1.2,9.2,100,0.5;
% 100,0,100,5,100,3.1,2;
% 100,100,0,100,100,4,1.5;
% 1.2,5,100,0,6.7,100,100;
% 9.2,100,100,6.7,0,15.6,100;
% 100,3.1,4,100,15.6,0,100;
% 0.5,2,1.5,100,100,100,0
% ];
%
% b=[
% 0,9.2,1.1,3.5,100,100;
% 1.3,0,4.7,100,7.2,100;
% 2.5,100,0,100,1.8,100;
% 100,100,5.3,0,2.4,7.5;
% 100,6.4,2.2,8.9,0,5.1;
% 7.7,100,2.7,100,2.1,0
% ];
%
% Floyd(a,1,100)
% Floyd(b,1,100) program floyd;
var
st,en,f:integer;
k,n,i,j,x:integer;
a:array[1..10,1..10] of integer;
path:array[1..10,1..10] of integer;
begin
readln(n);
for i:=1 to n do
begin
for j:=1 to n do
begin
read(k);
if k<>0 then
a[i,j]:=k
else
a[i,j]:=maxint;
path[i,j]:=j;
end;
readln;
end;
for x:=1 to n do
for i:=1 to n do
for j:=1 to n do
if a[i,j]>a[i,x]+a[x,j] then
begin
a[i,j]:=a[i,x]+a[x,j];
path[i,j]:=path[i,x];
end;
readln(st,en);
writeln(a[st,en]);
f:=st;
while f<> en do
begin
write(f);
write('-->');
f:=path[f,en];
end;
writeln(en);
end. //以無向圖G為入口,得出任意兩點之間的路徑長度length[i][j],路徑path[i][j][k],//途中無連接得點距離用0表示,點自身也用0表示publicclassFLOYD{int[][]length=null;//任意兩點之間路徑長度int[][][]path=null;//任意兩點之間的路徑publicFLOYD(int[][]G){intMAX=100;introw=G.length;//圖G的行數int[][]spot=newint[row][row];//定義任意兩點之間經過的點int[]onePath=newint[row];//記錄一條路徑length=newint[row][row];path=newint[row][row][];for(inti=0;i<row;i++)//處理圖兩點之間的路徑for(intj=0;j<row;j++){if(G[i][j]==0)G[i][j]=MAX;//沒有路徑的兩個點之間的路徑為默認最大if(i==j)G[i][j]=0;//本身的路徑長度為0}for(inti=0;i<row;i++)//初始化為任意兩點之間沒有路徑for(intj=0;j<row;j++)spot[i][j]=-1;for(inti=0;i<row;i++)//假設任意兩點之間的沒有路徑onePath[i]=-1;for(intv=0;v<row;++v)for(intw=0;w<row;++w)length[v][w]=G[v][w];for(intu=0;u<row;++u)for(intv=0;v<row;++v)for(intw=0;w<row;++w)if(length[v][w]>length[v][u]+length[u][w]){length[v][w]=length[v][u]+length[u][w];//如果存在更短路徑則取更短路徑spot[v][w]=u;//把經過的點加入}for(inti=0;i<row;i++){//求出所有的路徑int[]point=newint[1];for(intj=0;j<row;j++){point[0]=0;onePath[point[0]++]=i;outputPath(spot,i,j,onePath,point);path[i][j]=newint[point[0]];for(ints=0;s<point[0];s++)path[i][j][s]=onePath[s];}}}voidoutputPath(int[][]spot,inti,intj,int[]onePath,int[]point){//輸出i//到j//的路徑的實際代碼,point[]記錄一條路徑的長度if(i==j)return;if(spot[i][j]==-1)onePath[point[0]++]=j;//System.out.print(+j+);else{outputPath(spot,i,spot[i][j],onePath,point);outputPath(spot,spot[i][j],j,onePath,point);}}publicstaticvoidmain(String[]args){intdata[][]={{0,27,44,17,11,27,42,0,0,0,20,25,21,21,18,27,0},//x1{27,0,31,27,49,0,0,0,0,0,0,0,52,21,41,0,0},//1{44,31,0,19,0,27,32,0,0,0,47,0,0,0,32,0,0},//2{17,27,19,0,14,0,0,0,0,0,30,0,0,0,31,0,0},//3{11,49,0,14,0,13,20,0,0,28,15,0,0,0,15,25,30},//4{27,0,27,0,13,0,9,21,0,26,26,0,0,0,28,29,0},//5{42,0,32,0,20,9,0,13,0,32,0,0,0,0,0,33,0},//6{0,0,0,0,0,21,13,0,19,0,0,0,0,0,0,0,0},//7{0,0,0,0,0,0,0,19,0,11,20,0,0,0,0,33,21},//8{0,0,0,0,28,26,32,0,11,0,10,20,0,0,29,14,13},//9{20,0,47,30,15,26,0,0,20,10,0,18,0,0,14,9,20},//10{25,0,0,0,0,0,0,0,0,20,18,0,23,0,0,14,0},//11{21,52,0,0,0,0,0,0,0,0,0,23,0,27,22,0,0},//12{21,21,0,0,0,0,0,0,0,0,0,0,27,0,0,0,0},//13{18,41,32,31,15,28,0,0,0,29,14,0,22,0,0,11,0},//14{27,0,0,0,25,29,33,0,33,14,9,14,0,0,11,0,9},//15{0,0,0,0,30,0,0,0,21,13,20,0,0,0,0,9,0}//16};for(inti=0;i<data.length;i++)for(intj=i;j<data.length;j++)if(data[i][j]!=data[j][i])return;FLOYDtest=newFLOYD(data);for(inti=0;i<data.length;i++)for(intj=i;j<data[i].length;j++){System.out.println();System.out.print(From+i+to+j+pathis:);for(intk=0;k<test.path[i][j].length;k++)System.out.print(test.path[i][j][k]+);System.out.println();System.out.println(From+i+to+j+length:+test.length[i][j]);}}}

6. floyd演算法

核心思路

通過一個圖的權值矩陣求出它的每兩點間的最短路徑矩陣。
從圖的帶權鄰接矩陣A=[a(i,j)] n×n開始,遞歸地進行n次更新,即由矩陣D(0)=A,按一個公式,構造出矩陣D(1);又用同樣地公式由D(1)構造出D(2);……;最後又用同樣的公式由D(n-1)構造出矩陣D(n)。矩陣D(n)的i行j列元素便是i號頂點到j號頂點的最短路徑長度,稱D(n)為圖的距離矩陣,同時還可引入一個後繼節點矩陣path來記錄兩點間的最短路徑。
採用的是(鬆弛技術),對在i和j之間的所有其他點進行一次鬆弛。所以時間復雜度為O(n^3);
其狀態轉移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]}
map[i,j]表示i到j的最短距離
K是窮舉i,j的斷點
map[n,n]初值應該為0,或者按照題目意思來做。
當然,如果這條路沒有通的話,還必須特殊處理,比如沒有map[i,k]這條路
編輯本段
演算法過程

把圖用鄰接矩陣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,D(3,1)=2,D(2,1)=1則說明從V5到V1經過V3,從V3到V1經過V2,V2到V1直接相連,路徑為{V5,V3,V2,V1},如果D(5,3)=3,說明V5與V3直接相連,如果D(3,1)=1,說明V3與V1直接相連。
編輯本段
時間復雜度

O(n^3)
編輯本段
優缺點分析

Floyd演算法適用於APSP(All Pairs Shortest Paths),是一種動態規劃演算法,稠密圖效果最佳,邊權可正可負。此演算法簡單有效,由於三重循環結構緊湊,對於稠密圖,效率要高於執行|V|次Dijkstra演算法。
優點:容易理解,可以算出任意兩個節點之間的最短距離,代碼編寫簡單;
缺點:時間復雜度比較高,不適合計算大量數據。

7. matlab floyd 演算法注釋

A矩陣是鄰接矩陣,對角線上為o,其餘位置數字表示的是兩點之間距離,比如A(1,2)=2,表示從第一個點到第二個點的距離為2.inf是無窮大的意思,這里表示沒有直接溝通這兩點的路。
n=length(D);設定n為D矩陣的長度。
接下來的兩重循環,得到的R矩陣是n*n的矩陣,它每個數據表示的是路徑,比如:R(1,3)=1;表示路徑為:1-1-3.這里是初始化路徑了。
後面的三重循環是floyd演算法的關鍵所在,就是更新路線了。裡面的那個判斷指的是:
假設有3個點,1
2
3;如果我從1-2-3之間總距離小於1-3的距離,那麼我R(1,3)=2;這就是選取更近的路線了。
最後的兩個判斷是為了不讓曾經走過的點再次被遍歷。就是不回頭的意思了,這個一般都可以忽略了,你照打上去就是了。
不知道這樣的解釋你是否滿意。

8. matlab實現floyd演算法 已知距離矩陣和權值矩陣 求最短路徑

希望可以幫到你。

function [D,path]=floyd(a)
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

function [L,R]=router(D,path,s,t)
L=zeros(0,0);
R=s;
while 1
if s==t
L=fliplr(L);
L=[0,L];
return
end
L=[L,D(s,t)];
R=[R,path(s,t)];
s=path(s,t);
end

9. 51單片機不能實現弗洛伊德a*演算法嗎

不能
從根本而言,51單片機不適合做這種運算。Floyd演算法又稱為插點法,是一種利用動態規劃的思想尋找給定的加權圖中多源點之間最短路徑的演算法,與Dijkstra演算法類似。該演算法名稱以創始人之一、1978年圖靈獎獲得者、斯坦福大學計算機科學系教授羅伯特·弗洛伊德命名。在計算機科學中,Floyd-Warshall演算法是一種在具有正或負邊緣權重(但沒有負周期)的加權圖中找到最短路徑的演算法。演算法的單個執行將找到所有頂點對之間的最短路徑的長度(加權)。雖然它不返迴路徑本身的細節,但是可以通過對演算法的簡單修改來重建路徑。該演算法的版本也可用於查找關系R的傳遞閉包,或(與Schulze投票系統相關)在加權圖中所有頂點對之間的最寬路徑。在計算機科學中,Floyd-Warshall演算法是一種在具有正或負邊緣權重(但沒有負周期)的加權圖中找到最短路徑的演算法。演算法的單個執行將找到所有頂點對之間的最短路徑的長度(加權)。雖然它不返迴路徑本身的細節,但是可以通過對演算法的簡單修改來重建路徑。該演算法的版本也可用於查找關系R的傳遞閉包,或(與Schulze投票系統相關)在加權圖中所有頂點對之間的最寬路徑。

10. matlab實現弗洛伊德演算法的代碼,。

function
[d,r]=floyd(a)
%floyd.m
%採用floyd演算法計算圖a中每對頂點最短路
%d是矩離矩陣
%r是路由矩陣
n=size(a,1);
d=a;
for
i=1:n
for
j=1:n
r(i,j)=j;
end
end
r
for
k=1:n
for
i=1:n
for
j=1:n
if
d(i,k)+d(k,j)

評論
0

0

0

載入更多

熱點內容
python文件刪除一行 發布:2025-05-14 08:06:58 瀏覽:721
如何下載奧特曼高級化3安卓版 發布:2025-05-14 07:47:31 瀏覽:346
qml文件修改後編譯未生效 發布:2025-05-14 07:31:00 瀏覽:331
內到內演算法 發布:2025-05-14 07:29:11 瀏覽:34
文件夾名字不顯示 發布:2025-05-14 07:27:47 瀏覽:775
oracle的資料庫驅動jar 發布:2025-05-14 07:23:20 瀏覽:556
我的世界電腦版伺服器手機版能進嗎 發布:2025-05-14 07:22:01 瀏覽:679
達內培訓php多少錢 發布:2025-05-14 07:19:10 瀏覽:27
python位元組轉字元串 發布:2025-05-14 07:06:35 瀏覽:423
subplotpython 發布:2025-05-14 06:53:51 瀏覽:662