演算法導論 第25章 所有結點對的最短路徑問題

2021-06-22 17:32:14 字數 2340 閱讀 8931

前面講了單源最短路徑問題,指定乙個原點乙個終點,找到最短路徑。但是如果我們要求所有結點對呢?

方案一:可以對每乙個結點呼叫一次單源最短路徑演算法,一共呼叫|v|次。(每指定乙個原點,可以求出其他任何點到該原點的舉例)

對於權值為非負的圖,可以呼叫dijkstra演算法,不同的優先佇列實現得到不同的時間複雜度:①線性陣列,o(v^3 + ve) = o(v^3)。②二叉堆,o(velgv),在稀疏圖的情況下是乙個較大的改進。③斐波那契堆,o(v^2lgv + ve)。

如果有權重為負的邊,就要使用bellman-ford演算法。時間複雜度為o(v^2e),在稀疏圖的情況下,時間為o(v^4)。

顯然上述方法時間複雜度較大,我們可以利用floyd-warshall演算法和johnson演算法(用於稀疏圖)來求解。

floyd-warshall演算法用鄰接矩陣表示,johnson演算法用鄰接表表示。

1、權重的表示:

2、返回的是乙個矩陣,dij表示從i結點到j結點的最短路徑權重。注意,dij和dji不一樣。為了能求出最短路徑,我們還要儲存父節點資訊,pij表示從i結點到j結點時,j的父節點的位置。那麼到時候通過修改22章的print-path演算法就能得到想要的結果。

3、最短路徑和矩陣乘法

(1)利用動態規劃來分析,lij(m)為在結點i和結點j之間最多有m條邊的最小權重。而求lij(m)的時候利用lij(m-1)和在其中任意選一點k得到兩段權值之和的最小值進行比較,取最小值,即

那麼對於n個結點來說,求得lij(n-1)就已經達到了最優化,因此有

(2)自底向上實現

偽**

通過對比矩陣乘法

兩者結構很相似,因此我們對最短路徑求解的時候,可以按照矩陣的方程來求解:l(n-1) = w(n-1)。主迴圈為:

時間複雜度為o(n^4)。

------->優化

對於矩陣或者數的n次方來說,可以通過重複平方的方法來講時間複雜度將為o(n^3 logn)。

又因為有公式

可以不用考慮越界問題,於是得到**如下:

這裡使用的動態演算法不是上面提到的那種,可以講時間複雜度壓縮到o(v^3)。上面的是按照從i到j的邊的個數來遞迴定義的。這裡是按照中間點的個數來定義的,其實質也差不多,但是遞迴的方式發生了變化。

從頂點vi到vj有一條長度為arcs[i][j]的路徑,但不一定是最短的,需要經過n次試探,中間節點依次從v0、v1....vn-1增加,步驟如下:

(1)先考察路徑(vi,v0,vj)師傅存在,如果存在比較(vi,vj)和(vi,v0)+(vi,vj)的大小,取最小值為,中間節點序號不大於0的最短路徑。

(2)再增加乙個節點v1,判斷路徑(vi...v1)和(v1...vj)是否存在,注意,vi到v1和v1到vj之間的節點序號最多只有v0乙個,然後將二者的和與剛求得的新的(vi,vj)比較,取最小值更新。

(3)依次增加,比如增加節點k那麼判斷(vi....vk)+(vk...vj)之和的路徑值與最新的(vi,vj)比較取最小值更新。注意(vi....vk)和(vk...vj)之間的節點取值序號必須在0-- k-1之間。

遞迴公式為:

}構建一條最短路徑

沒看太懂,詳細參考演算法導論p409

演算法導論 第25章 每對頂點間的最短路徑

每對頂點間的最短路徑的演算法有三種,每一種都可以檢測圖是否存在weighg小於0的cycle。前兩種演算法用了動態規劃的方法,最後一種演算法對每個定點計算單源最短路徑。與求單源最短路徑的演算法不同,求每對頂點間的最短路徑的演算法採用網的矩陣表示法 除了最後一種演算法,最後一種演算法採用圖的鄰接表表示...

《演算法導論》筆記 第3章 函式的增長

第3章 函式的增長 漸進記號 記號對任乙個函式f n 若存在正常數c1,c2,使當n充分大時,f n 能被夾在c1g n 和c2g n 中間,則f n 屬於集合 g n 因為 g n 是乙個集合,可以寫成 f n g n 表示f n 是 g n 的元素。g n 的定義需要每個成員f n g n 都是...

資料結構的擴張 演算法導論第14章(194)

偽 解釋 為明白os select是如何操作的,在上圖所示的順序統計圖上查詢第17小元素的查詢過程。以x為根開始,其關鍵字為26。i 17.因為在26的左子樹大小為12,故他的秩為13,因此,秩為17的節點是26的右子樹第17 13 4小得瑟元素。遞迴呼叫後,x為關鍵字41的節點,i 4,因為41的...