Warshall傳遞閉包演算法的學習與實現

2021-08-28 09:29:02 字數 2215 閱讀 6073

warshall傳遞閉包演算法的學習與實現

1、問題引入

乙個有n個頂點的有向圖的傳遞閉包為:有向圖中的初始路徑可達情況可以參見其鄰接矩陣a,鄰接矩陣中a[i,j]表示i到j是否直接可達,若直接可達,則a[i,j]記為1,否則記為0;兩個有向圖中i到j有路徑表示從i點開始經過其他點(或者不經過其他點)能夠到達j點,如果i到j有路徑,則將t[i,j]設定為1,否則設定為0;有向圖的傳遞閉包表示從鄰接矩陣a出發,求的所有節點間的路徑可達情況,該矩陣就為所要求的傳遞閉包矩陣。。。

例如:有向圖為:

由該有向圖可以得到初始的鄰接矩陣為:

那麼warshall傳遞閉包演算法的目的就是由鄰接矩陣出發,進行探索求出最終的傳遞閉包:

2、動態規劃求解思路

動態規劃將問題分段,本例warshall演算法是通過一系列n階矩陣r(k)來構造最終階段n階傳遞閉包矩陣r(n)

r(k) 由它的前趨 r(k-1) 計算得到(分級推進計算)。

r(0) ——該矩陣不允許它的路徑中包含任何中間頂點,即從該矩陣的任意頂點出發的路徑不含有中間頂點,此即鄰接矩陣。

r(1) ——允許路徑中包含第1個頂點(本例編號 1)作為中間頂點。

r(2) ——允許路徑中包含前2個頂點(本例編號1 2)作為中間頂點。

r(k) ——允許路徑中包含前k個頂點作為中間頂點。

r(n) ——允許路徑中包含全部 n 個頂點作為中間頂點。

每個後繼矩陣 r(k) 對其前趨 r(k-1) 來說,在路徑上允許增加乙個頂點, 因此有可能包含更多的1(增加前為1的在增加後依然為1)。

3、具體的演算法描述

1 warshall(a[1...n,1

...n]

2 r(0)

3for(k=1;k<=n;k++)

4for(i=1;i<=n;i++)

5for(j=1;j<=n;j++)

6 r(k)[i,j]=r(k-1)[i,j] or(r(k-1)[i,k] and r(k-1

)[k,j]);

7return r(n);

4、具體實現**如下

說明:(1)有向圖的頂點個數和初始鄰接矩陣儲存在2.txt中(具體如下圖),其中4表示有向圖中有4 個頂點,其他表示初始鄰接矩陣。

(2)有向圖的頂點個數和初始鄰接矩陣個數可以隨意更改,,,,

具體**:

1 #include

2 #include

3void warshall(int,int**);

4void

main()

514 fscanf(p,"

%d",&num);

15int **r=(int**)malloc(sizeof(int*)*(num+1

));16

for(i=0;i1;i++)

17 r[i]=(int*)malloc(sizeof(int)*(num+1

));18

for(i=1;i1;i++)

19for(j=1;j1;j++)

20 fscanf(p,"

%d",&r[i][j]);

21 printf("

頂點個數為:%d\n

",num);

22 printf("

鄰接矩陣為:\n");

23for(i=1;i1;i++)

2429

warshall(num,r);

30 printf("

最終的傳遞閉包為\n");

31for(i=1;i1;i++)

323738}

39//

三重迴圈實現的warshall演算法

40//

r為鄰接矩陣,中間儲存初試的可達與非可達路徑情況,1表示可達,0表示不可達

41void warshall(int num,int**r)

4255}56

for(i=1;i<=num;i++)

57for(j=1;j<=num;j++)

58 r[i][j]=temp[i][j];59}

6061 }

5、結果如下:

6、參考文獻

(1)演算法導論

(2)資料結構 嚴蔚敏

warshall傳遞閉包演算法的學習與實現

傳遞閉包的計算 Warshall

o n 3 的高效閉包演算法 演算法內容 1.做出關係r的矩陣m 2.列舉每一列,以這一列對應的元素為中間元素去創造新的關係 一行一行來做,如果當前行對應的元素與列對應的元素有關係,例如arb,則考慮有無關係,若有關係則ar 具體實現就是m a m b 有點類似於多源最短路演算法,也是一種動態規劃的...

關係傳遞閉包Warshall演算法之思想的一種解說

關係傳遞閉包warshall演算法之思想的一種解說 周曉煒 西安郵電學院計算機系網路0407班 西安 710121 注 本文已發表在 中國科技 網 http www.kjlw.cn 為http www.kjlw.cn show2.asp?newsid 763 需註冊成為會員才能瀏覽 1 引言 war...

warShall演算法實現傳遞閉包的計算(C 版)

warshall通俗的講就是計算有向圖的傳遞閉包,進而轉化為乙個圖結構中任意兩點的可達情況 該演算法的時間複雜度為o n 3 include using namespace std int count 用來計算判斷次數 const int n 10 二維陣列可以沒有行,但必須有列,這裡假定最大階為1...