More Related Content
Similar to Part 6 2010 (20)
Part 6 2010
- 1. 現在排列整齊 y s,1 y s,2 y 1,2 y 1,3 y 2,4 y 4,3 y 3, t y 4, t
min + 2 + 1 + 3 + 3 + 1 + 2 + 2 + 5
s.t - 1 +1 +1 =0 node1
-1 -1 +1 =0 node2
-1 -1 + 1 =0 node3
-1 + 1 +1 =0 node4
+1 +1 = +1 node5
y i, j = 0,1 ∀edge(i, j)
注意上述 5 個式子加起來正好是 y s , t + y4 , t = 1 why?
註:也可以加上 之式子 ys ,t + y4,t = 1 (而去掉 node s 之式子 y s ,1 + y s , 2 = 1 )
Chapter 25. All-Pairs Shortest Paths
Directed graph 每一 edge 有一 weight wi
想求出每兩個 node i, j 間之 shortest path δ (i, j )
Naïve approach:
n
每兩個 node 間作一次 shortest path 共 = θ (n 2 ) 對
2
若 dij ≥ 0 ∀ edge ⇒ O(V 2 ⋅ V 2 ) = 4 )
O(V Dijkstra
若有些 edge dij <0 ⇒ O(V 2 ⋅ V 3 ) = 5 )
O(V Bellman-Ford
稍微想一下 當找到 s 到 t 的 shortest path 時(前述所有的 algorithm)也都順便找
出了. s 到所有其他 nodes 之 shortest path. 固此 上述”每兩個 node 間”作一次
可改為”每一個 node 作一次” (選定 node i 就可以一次找到 i 到所有其他 node 之
shortest path )
⇒ 前述 O(V 4 ) ↓ O(V 3 )
O(V 5 ) ↓ O(V 4 ) 利用好的 data structure 還可改進 見 p.682 p.686
O(V 2 E ) on sparse graph
下面要用 dynamic programming approach 來處理此問題,以下之 algorithm 並不限
dij ≥ 0 ∀ edge 可以有 dij <0
26
- 2. 若沒有 negative weight cycle 此 algorithm 會找出 optimal 解
若有 negative weight cycle 此 algorithm 會 detect 出來且可以指出一個如此 cycle
這個問題 用 dynamic programming 方式來解其 dynamic programming 想法可以
有四、五種 recursive idea. 先介紹目前最 efficient 的一種如下:
Floyd-Warshall algorithm p.693
他的基本想法是 先把 vertex 編好號 1,2,3,4,…,n
考慮由 i 到 j 之所有 path 中 其 intermediate vertices 只經過 {1, 2,3,...k}
(而未 用到 {k + 1,..., n} ) 這些之中 最短者
等一下再把 k+1 加入 再 k+2,k+3……
Initial 呢? 很容易處理 How?
圖示:中間之 node number 皆 ≤ k
Define optimal value function
dijk ) =weight of a shortest path from i to j with intermediate vertices in
(
{1,2,3,…k}
Recursive relation:
= min( dijk −1) , dikk −1) + d kjk −1) )
dijk )
( ( ( (
if k ≥ 1
圖示:
註: 這三”小段”所經過的
Intermediate vertex 皆 ≤ k − 1
Initial condition:
dij = wij
(0)
∀edge(i, j )
若 Graph 上原本無第一 edge 如何處理? 0
dii 呢?
27
- 3. Answer:
dijn )
(
∀ node i,j
一般人用 dynamic programming 所寫下的 recursive formula 皆口頭說一下其
正確性,而沒有嚴格証明. 但若要嚴謹証明,可以用歸納法証明之.
有了初步之 dynamic programming 之 recursive formula 接下來就可寫出其
algorithm (pseudo code) 見 p.695
再次提醒: 不可用 recursive 程式去 implement 必須用 button up 方式. 並且每算
一個 subproblem 就要把計算出來之值儲存在一個 table 上,以使後來查詢讀取 data
避免重複計算
看一個例子以了解 p.695 之 Floyd-Warshall(W)
0 3 8 ∞ −4
∞ 0 ∞ 1 7
Initialization D (0) = ∞ 4 0 ∞ ∞
2 ∞ −5 0 ∞
∞ ∞ ∞ 6 0
See page 696
P696 之計算過程由 D(0) D(1) D(2) … D(5), 由 D(5)可看出,每兩個 vertex 間的最
短路徑之長度 δ(i,j),但如 construct 出 actual path 呢?只需在此 algorithm 過程中
多記錄一點 information 即可。
建議
1.可記錄下 predecessor:例 dij(K) i ○→○→○ …○→○→○ j
(K) (K) (K)
則利用一個 matrix π = [πij ] 記下 πij = v,問如何 initialization?如何 update?
NIL if i = j or wi j = ∞
initial: π ij (0) =
i if i ≠ j and wij < ∞
28
- 4. π ij ( k −1)
if dij ( k −1) ≤ dik ( k −1) + d kj ( k −1)
update: π ij (k )
= ( k −1)
π kj
if dij ( k −1) > dik ( k −1) + d kj ( k −1)
圖示
看 P696 如何計算 π(0) π(1)…π(5)
例如要 construct 出 2 到 5 之 shortest path π2,5(5) = -1
由π2,5(5) = 1 → →
由π2,1(5) = 4 → →
由π2,4(5) = 2 停! → → →
_______________________
建議 2. 可記錄下 dij(K) 這個 path 上 intermediate vertex 編號最高的
那一個 node,記在 H(K) = (hij(K)) 中
Initial: hij(0) = NIL for all i,j
kij ( k −1)
if dij ( k −1) ≤ dik ( k −1) + d kj ( k −1)
update: hij (k )
=
k
if dij ( k −1) > dik ( k −1) + d kj ( k −1)
練習: 用建議 2 作一遍 p696 之例子 最後再試利用 H(5) 來 construct 出 d2,5(5) = -1
, ,
之 actual path
_______________________
time complexity Θ(V) 3 why? 想一下 p696 那些 table 如何計算出來的?
space complexity Θ(V) 2 why?
Best algorithm Ο(V 2lgV+VE) see section 25.3
_______________________
問:若有些 edge weight Wij < 0,則可能有 negative weight cycle 會發生什麼情
況?
29
- 5. 答案是在計算 matrix D(K) = [dij(K)] 時到了某一步 k 時若有某一對角線上之 entry
dij(K)變成負值,則 if and only if 有 negative weight cycle why?想一下
例:
對角線之 entry:
則在算到 D(47) 時 d89,89(47)<0
why?
負
問:若已發生某一 dii(K)<0,如何 construct 出 negative weight cycle?
問:如何在 implement 此 dynamic prog. 而用 recursive 程式,試問先只是 dij(n)這
一項會 recursive call 這個 subroutine 幾次?
T (n) 3T (n − 1) + 1
=
T (1) = 0
解:先解 homogeneous T(n) = 3T(n-1) → T(n) = C3(n)
1
找 non-homeg.的一個 particular sol.,試 T(n) = constant a 代入之 → a = -
2
1 1
general sol T(n) = C3(n)- ,由 T(1) = 0 → c =
2 6
1 1
T(n) = .3n-1 - = Θ(3 n),exponential number!
2 2
針對 all pairs shortest paths problem:
下面再提供幾種不同的 dynamic programming formulation (但都沒有前述的方式好,
1. A(K) = [aij ]
課本中就不會提到了)
(k)
aij
(k)
= 將 vertex 編號 1, 2, 3 ....n = |V|
30
- 6. 考慮 i j 中途經過的 node 編號 不超過 k 的這種 path 中最短者之長
time complexity O(V 3 ) space complexity(V 3 )
即 intermediate node C{1, 2, ...k}
2. B (k) = [bij ]
(k)
bij
(k)
= 將 edge 編號 1, 2, 3 ...m = |E|
......edge...................
time complexity? O(V 2 E) space complexity O(V 2 )
..edge C{1, 2, ...k}...............
3. C (k) = [cij ]
(k)
cij
(k)
= 完全不考慮 vertex 之編號 考慮 ij 中途頂多經過 K 個 vertices 的這
time ? O(V 4 ) space ? O(V 2 )
種 path 中最短者
4. D(k) = [dij ]
(k)
dij
(k)
= 完全不考慮 edge 之編號 考慮 ij 中途頂多經過 K 個 edges 的這種
time ? Θ(V 4 ) space ? Θ(V 2 )
path 中最短者 see 課本 P.623 (25.2) 式子
Transitive closure of a graph G P.697
一個 graph G 它的 transitive closure G∗定義如下:G∗與 G 有完全相同的 vertex。
若在 G 中的 vertex i 到 vertex j 有 path 相連 則 在G∗中(i j)就畫一 edge 相連
Edge 呢? 如下:
例
○
1 ○
2 ○
1 ← ○
2
31
- 7. G∗
↑ ↙ ↓↑ ↑ ↙↗ ↓↑
G ○
3 → ○
4 ←
○
3 → ○
4
如何算出一個 graph 的 transitive closure?
Warsha ll 首先提出一個 algorithm. 然後 Floyd 把此 algorithm 之精神推廣到解
all-pairs shortest path 因此 這個 algorithm 就叫 Floyd-Warshal algorithm.
看 P.698 的 algorithm: TRANSITIVE-CLOSURE(G)
它的想法與以前見過的 all-pairs shortest paths 完全類似 都可說是一種 Dynamic
Time complexity O(V 3 )
Programming 構想.
Johnson’s algorithm for spare graphs (all pairs shortest paths) P.700
先來點準備工作:
找 shortest path 最討厭的是遇到有些 edge 是 negative 的情況(更糟的是:若有
negative-weight edge 之情況=>找 shortest simple path 是 NP-complete!)。
如果所有 weight 皆為 nonnegative 則 all-pairs shortest path 可以對每一個 vertex
, 找
當起點,作一次 Dijkstra’s algorithm,並利用 Fibonacci Heap
(see P.661-662 ) => O(V)*O(VlogV+E)=O(V2 logV+VE)
在 spare graph 情況時,這比 Floyd-Warshall 的 all-pairs shortest path O(V3)好
註:所謂 spare graph 指|E|少於 O(V2)
即|E|=o(V2)
如果有些 edge weight 是 negative,下面有一個技巧可將 edge weight “調整”成全
部是 nonnegative,叫作 ”reweighting” (但有代價!)
所謂”reweighting”是有學問的,先看一些例子。
例:先看一個失敗的”調整”方式
-1 -4
S -4 T
找 S 到 T 之 shortest path (很明顯是”上面”那條)
32
- 9. 例:再看一個成功的小技巧
考慮一個 graph,有些 edge weight<0,要找 s 到 t 的 shortest path 技巧如下:
任意找一個 node X,任意選定一常數 c 標下
c -c +c
X -c X +c
-c
Reweighting 為
凡是進入此 node X 的 edge weight –c
出 +c
其它 edge 不變
則易知由 s 到 t 之任何 path 其總長不變 why?因為若某一 path 根本未經過此 node
X,當然總長不變。若某一 path 經過此 node X,一進一出剛好-c+c 互相抵銷,
總長仍不變。
但有一個小問題,若 node X 正好是起點’s’呢?那沒有關係=>每一條由 s 到 t 之
path 總長都"平移”+c,各個 path 之相對長短關係不變,大的仍大,小的仍小=>
想找的 shortest path 並不會找錯(只是總長+c 而已)。
問:若 node X 正好是終點 t 呢會不會影響
Ans:不會 (只是-c 而已)
既然挑一個 node X 可以如上處理一次,做完後又可以再挑另一個 node Y 又處理
一次 仍不影響真正的 shortest path 之路線。那何不乾脆一次玩的夠,把全部 node
,
一次全挑出,並可給不同之 node 選不同的常數 c,一次處理
例: P.703 每一 node 可任取一不同的常數,如圖示
34
- 10. �(u, v) = w(u, v) + h(u) − h(v)
w
上圖左,想找任兩點之間的 shortest path,例如由 s 到 t,就與右圖中,s 到 t 的
總長度調整了多少? Ans. +h(s) − h(t)
shortest path 是完全相同(這是指”路線完全一樣”,但總長度被調整了一點)。問,
奇妙的是:原本左圖中有 negative edge,check 一下,右圖中沒有 negative edge,
找 shortest path 就有比較 efficient 的 algorithm。例如 Dijkstra’s algorithm。
問題:如何能找到適當的”node number” c?
使得一調整後,所有的 edge weight 全 0?
答:方法有很多(但都有代價!time complexity 增高)
但只要代價比 Floyd-Warshall O(V 3 ) 低的話 就值得一試 等一下再看看怎麼做
, , 。
先把準備工作做一下。
Directed graph G,每一 edge 有一 edge weight w(u,v),可能有< 0。現在將每
P.701 Lemma25.1(上述 reweighting 不會改變 shortest paths)
一 node u 任選一個 real number h(u),叫 node number。
定義新的 edge weight w(u, v) = w(u, v) + h(u) − h(v),則
�
1. 在新的 edge weight 下,任兩點之 shortest path 與在”舊的”之下是完全一樣的
(路線相同)
2. 任何一個 direted cycle 其 cycle weight 不論在”新””舊”weight 之下是相同的
So:在舊的 edge weight 下有 negative weight cycle⇔ 在新的edge weight 下有
negative weight cycle。
Proof 見課本 P.701
舊的 total weight=新的 total weight+h(s) − h(t)
註:任一 path
註:w(u, v) + h(u) − h(v)就是以前看過的”relaxation”
35
- 11. w(u, v)就姑且可叫作 relaxation weight(或 relaxation cost)
�
回憶:”relaxation”是找 shortest path 的一個基本工具,找 s 到 t 的 shortest path,
在”algorithm”做完後必然會d(u) + w(u, v) ≥ d(v) ∀edge
調整 edge weight w(u, v) = w(u, v) + d(u) − d(v) ≥ (why? )0 , ∀edge
�
則取”node number”為這時的 d(u),每個 node 都有個 d(u)。
調整過後的 edge weight 全部≥ 0,太妙了!
- 原問題是要找 s 到 t 的 shortest path,但有些 edge weight< 0,目前所知的
但有一小問題:
algorithm 皆較不 efficient,所以希望調整一下 edge weight 使得全≥ 0。再利
用較 efficient 的 algorithm 找 shortest path。
但為了調整 edge weight 為正,反而大費周張先找出 shortest path 有了 node
number 再作調整 edge weight 然後再於新的 edge weight 之下找 shortest path,
, ,
這不是捨近求遠嗎? 不是的,理由如下:
1、 還可想其它方法找適當的 node number
2、 用 node number 調整 edge weight 這種技巧,在其它地還有更多更重的應用
舉例而言:凡是有關 weighted graph 相關的 optimization 問題都可以試用此調整
技巧。
例如 primal-dual algorithm 可視為 recursive 地調整 edge weight 及 node number,
最終可以很清楚的判斷 optimal solution。。
找 shortest path (例如 Dijkstras’ algorithm) 就可看成是在修正 node number,調整
edge weight,不斷地做下去直到最佳滿足了 optimal solution。。
3、 找 all-pairs shortest paths 還是值得調整 edge weight≧0
下面提供一方式找 node number h(u),滿足 w(u,v) + h(u) – h(v) ≧ 0 for all edge
How? See page 703
36
- 12. 原樣
s
-4 -5
外加一個 node s,與所有其它 node 相連,
方向是由 s 到其它 node
新加 edge 的 weight 為 0,原 graph 仍保持原樣
則用 Bellman-Ford algorithm O(VE) 找 s 到所有其它 node 的 shortest path。在
algorithm 終了,每一 node 就會得到一個 node number。
New edge weight w = w ( u , v ) + h ( u ) – h ( v )
�
且滿足 h( u ) + w( u , v )h( v ) edge
0 edge
代價? O ( VE )
在調整後的 edge weight 全部都 0
於是 , 找 all pair shortest paths 就容易了
可以對每一 node 用一次 Dijkstra’s algorithm
Dijkstra algo
↓
O( VE ) + O ( V ) O( VlogV + E ) = O( V2logV + VE )
↑ ↑
Bellman-Ford 每一 node 做一次
這比 Floyd –Warshall algorithm 的 all-pairs shortest paths algo. O( V3 ) 仍然好一
點 why?
因只要 |E| = o( |V|2 ) sparse graph
37
- 13. 細節的 algorithm 請看 P704 JOHNSON( G , w)
問 : 如何及時發現 原 graph 有 negative cycle ?
前頁新加一點 S 造成的新 graph 是否會產生新的 negative cycle ?
問 : 前頁新加一個 S 之作用和在 ? 不加它行嗎 ?
Ans : 恐怕不行哦 ?! why ?
想 : 你還能出怪招? 有無新招把 edge distance 調整成有趣的形式 ?
例子:
Dijkstra’s algorithm ( shortest path )
觀察 : 任取一個 vertex v
任取一個 vertex number c
將進入 v 之 edge weight 都一律減 c
離開 v 之 edge weight 都一律加 c
38
- 14. 做過調整 distance 後
則由 s 到 t 之 shortest path 不會改變 ( why? )
註 : 但 s 與 t 的 node number 會對 “path” 之長度有影響 ( 但 OK why? )
So 對每一 node 皆可來玩這麼一次
如何調整 distance ?
(i j) edge => wij + d( i ) – d( j )
注意 : “巧妙” 的選取了一組 vertex number 而使得調整過後的每一 edge
distance 皆 0
且走的 path 其 edge 全是 0 distance => shortest path
39