Part 6 2010

1,178 views

Published on

  • Be the first to comment

  • Be the first to like this

Part 6 2010

  1. 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. 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. 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. 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. 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. 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 之編號 考慮 ij 中途頂多經過 K 個 vertices 的這  time ? O(V 4 ) space ? O(V 2 ) 種 path 中最短者 4. D(k) = [dij ] (k) dij (k) = 完全不考慮 edge 之編號 考慮 ij 中途頂多經過 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. 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
  8. 8. 若將”most negative edge”找出來:-m,把每一個 edge 全部加上 m=>當然 new edge weight 都≧0 -1+4 -4+4 S -4+4 T 則 S 到 T 之 shortest path 變成”下面”那條。完全破壞了原來的問題,失敗! 33
  9. 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. 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. 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. 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. 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. 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

×