離散数学 最小全域木と最大流問題 落合 秀也 今日の内容 • 最小全域木 • プリムのアルゴリズム • 最大流問題 • フォード・ファルカーソンのアルゴリズム 2 今日の内容 • 最小全域木 • プリムのアルゴリズム • 最大流問題 • フォード・ファルカーソンのアルゴリズム 3 最小全域木を考える Minimum Spanning Tree Problem • ラベル付(重み付) グラフ G(V, E)が与えられたとき、ラ ベルの和が最小となる全域木を作りたい • 全域木 G(V, T) • Vのすべての頂点で構成される木 ∑ e∈T Ce を最小にする T で作られる G(V,T) (Ceは辺eのラベル) 8 2 • 最小全域木 2 2 2 9 4 5 3 5 1 6 例:ラベルを地点間の配線コストとする このとき、全地点がつながるネットワークを 最小コストで配線したい 4 1 4 7 1 3 8 8 4 8 4 5 プリム法による最小全域木の作成 ※ 考え方 a 3 • 任意の頂点を選び開始点sとする c • Tを辺の集合とする (開始時は空と 7 4 2 する) b 5 d • Hの領域まで最小全域木の一部を s 6 作っているとする。 3 6 • Hから出る辺のうち、そのコストが 7 5 最小の辺で接続する頂点をHに取 e り込む ・・・ (*) 8 f 8 H • その辺をTに追加する 5 h 3 g • H=Vとなるまで(*)を繰り返す • G(V,T) が最小全域木となる 5 プリムのアルゴリズム: 素直な実装 a H := {s} T := {} 2 While H ≠ V 5 min_length := ∞, min_edge := null s Foreach (u,v) : u∈H, v∈H-V 6 If min_length > length(u,v) Then, 7 min_length := length(u,v) e 8 min_edge := (u,v) EndIf 5 EndFor T.add ( min_edge ) g H.add( min_edge.right ) 時間計算量 O(nm) EndWhile 3 c b 7 4 d 6 3 5 f ※ この疑似コードの場合 8 h 3 6 練習 • プリム法により、以下のグラフに対する最小全域木 を作成せよ 5 8 2 3 2 5 2 2 9 4 4 1 5 4 7 8 1 8 3 4 1 6 8 7 1.開始点を選ぶ s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 8 2.コストが最小の辺を選び 接続する頂点を取り込む (1/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 9 2.コストが最小の辺を選び 接続する頂点を取り込む (2/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 10 2.コストが最小の辺を選び 接続する頂点を取り込む (3/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 11 2.コストが最小の辺を選び 接続する頂点を取り込む (4/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 12 2.コストが最小の辺を選び 接続する頂点を取り込む (5/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 13 2.コストが最小の辺を選び 接続する頂点を取り込む (6/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 14 2.コストが最小の辺を選び 接続する頂点を取り込む (7/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 15 2.コストが最小の辺を選び 接続する頂点を取り込む (8/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 16 2.コストが最小の辺を選び 接続する頂点を取り込む (9/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 17 2.コストが最小の辺を選び 接続する頂点を取り込む (10/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 18 2.コストが最小の辺を選び 接続する頂点を取り込む (11/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 19 2.コストが最小の辺を選び 接続する頂点を取り込む (12/12) s 2 8 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 20 3.最小全域木の完成 8 2 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 21 プリムのアルゴリズム(改良版) ダイクストラ法で工夫したように、 ダイクストラ法とよく似た形に実装できる H := {s} T := {} While H ≠ V min_length := ∞, min_edge := null Foreach (u,v) : u∈H, v∈H-V If min_length > length(u,v) Then, min_length := length(u,v) min_edge := (u,v) EndIf EndFor T.add ( min_edge ) H.add( min_edge.right ) EndWhile 改良前 Foreach v ∈V (v≠s) c[v] :=∞, prev[v]:=null Q.add(v) EndFor c[s] :=0 While Q is not empty u := Q.extractMin() Foreach v in Adj[u] If c[v] > length(u,v) Then, c[v] := length(u,v) prev[v] := u ( Q.changeKey() ) EndIf EndFor EndWhile 改良後 While Q is not empty u := Q.extractMin() Foreach v in Adj[u] If c[v] > length(u, v) Then, c[v] := length(u, v) prev[v] := u EndIf EndFor EndWhile 確認 • プリム法(改良版)により、以下 のグラフに対する最小全域木 を作成してみよ 8 2 2 3 2 2 9 4 5 1 4 1 8 8 4 1 6 5 4 7 3 5 8 23 プリム法: 計算量の考察 • While文の内部は n回実行される。 • Foreach文の内部は nm回実行される。 実装によっては O(nm) となりえる。 • Q に リストや配列を使う場合 While Q is not empty u := Q.extractMin() Foreach v in Adj[u] If c[v] > length(u, v) Then, c[v] := length(u, v) prev[v] := u ( Q.changeKey() ) EndIf EndFor EndWhile • Q.extractMin()に O(n) の時間を要する • Q.extractMin()は n回 呼び出される O(n2) • Q に 2分ヒープを使う場合 • • • • Q.extractMin()に O(log n)の時間を要する Q.extractMin()の呼び出しはn回ある O(n log n) c[v]の更新に伴うヒープの組換え処理に、O(log n)の時間を要する c[v]の更新は、m回発生する O(m log n) O( (n+m) log n ) 24 今日の内容 • 最小全域木 • プリムのアルゴリズム • 最大流問題 • フォード・ファルカーソンのアルゴリズム 25 最大流問題 Maximum Flow Problem • ラベル付(重み付) グラフ G(V, E)が与えられたとき、流入点 sから流出点tまでの総流量を最大化したい • 辺のラベルの意味: 流量の容量(最大量) 8 55 • 運べる荷物の量 • 流せる水の量 • 送れるパケット数 22 22 10 • このとき、 s 5 2 4 9 4 2 1 3 4 5 7 1 5 1 1 1 8 8 3 4 1 4 3 8 6 3 1 1 4 4 5 5 t 10 sに流れ込む流量 = tから流れ出る流量 (グラフの外から見た場合) sから流れ出す流量 = tに流れ込む流量 (グラフの中で見た場合) である。 26 この量の最大値(とそのときのフロー)をどう求めればよいか? 最大流問題:解決へのアプローチ • s-t間の適当な道を考え、その流 量上限(最小容量)を算出す る・・・赤色のケース u 10 10 20 s 30 20 10 t 20 v • 赤色のフローを流しても余って いる別のs-t間の道を考える(逆 向きは押し戻すと考える)。この 際の、流量上限を算出する・・・ 青色のケース • 上記を繰り返していけば、徐々 に総流量が増えてやがてそれ 以上流せなくなる。これにより、 ネットワーク全体の最大流が求 27 まるのではないか?? フローの定式化 • 辺を流れるフロー f(u,v) u C(u,v) C(v,u) v f(u, v) ≦ C(u, v) f(v, u) = - f (u, v) ∴ -C(v, u) ≦ f(u, v) ≦ C(u, v) ただし C(u, v) = C(v, u)とは限らない • 頂点への流入量と流出量 v 流入量: fin(v) = ∑ u∈V, f(u,v)>0 f(u,v) 流出量: fout (v) = ∑ w∈V, f(v,w)>0 f(v,w) v≠s,t であれば fin(v) = fout(v) 総流量: total(f)= fout(s) = fin(t) 28 フォード・ファルカーソン法 Ford-Fulkerson Algorithm ※ 考え方 u 20 10 10 20 30 s 10 10 30 20 t 20 v フローに沿って -20 u 0 10 10 s 40 50 10 10 20 10 • s-t間の何らかの道を考え、その流量の上限 を算出する • そのフローfを容量Cから引いた値(残余容 量)を計算し、グラフから差し引く ・・・そのグ ラフをGfとする • Gfに対して、同様のことをする(つまり、s-t 間の何らかの道を考え、その流量の上限を 算出し、総フローを算出し、容量から差し引 いて・・・) • s-t間の道が無くなれば、終了 u 0 10 20 t 0 0 s 40 40 0 40 v フローに沿って(さらに) 20 -10 v 20 0 s-t間の道がなくなった (容量>0の弧についてのみ考える) t 40 このとき差し引いている 総フローが求める最大流 29 練習 • フォード・ファルカーソン法を用いて、以下のフロー グラフにおける sから t への最大流を求めよ。 10 20 10 10 20 s 30 10 30 50 40 10 20 t 10 20 10 (*) 辺のラベルは、 容量(向きは問わない)を 表している。 30 50 20 20 30 s 容量を、まず有向グラフに置き換える 10 20 10 10 10 20 30 10 t 30 10 50 10 20 10 30 50 10 20 10 30 50 20 50 40 20 20 40 20 30 10 10 10 10 20 30 20 20 20 s s-t間の適当な道を考え、その流量の上限を算出する。 10 20 10 10 10 20 30 10 t 30 10 50 10 20 20 10 30 50 10 20 10 30 50 20 50 40 20 20 40 20 30 10 10 10 10 20 30 20 20 20 s 残余容量 Cf(u,v) = C(u,v) - f(u,v) とし、Gfを作成する 10 20 10 10 10 20 30 10 t 30 10 50 10 20 10 30 50 10 20 10 30 30 20 70 40 20 20 40 20 10 10 10 10 10 0 50 40 0 40 s Gfにおいて、s-t間の適当な道を考え、その流量の上限を算出する。 10 20 10 10 10 20 30 10 t 30 10 50 10 20 20 10 30 50 10 20 10 30 30 20 70 40 20 20 40 20 10 10 10 10 10 0 50 40 0 40 s 残余容量 Cf(u,v) = C(u,v) - f(u,v) とし、Gfを作成する 10 (*) 本来は f(u,v)はフローの総和 道Pによって作られるフローではない 20 10 10 10 20 30 10 t 30 10 50 10 20 10 30 50 10 20 10 30 10 40 90 20 0 0 60 40 10 10 10 10 10 0 50 40 0 40 s Gfにおいて、s-t間の適当な道を考え、その流量の上限を算出する。 10 20 10 10 10 20 30 10 t 30 10 50 10 10 20 30 10 50 10 20 10 30 10 40 90 20 0 0 60 40 10 10 10 10 10 0 50 40 0 40 s 残余容量 Cf(u,v) = C(u,v) - f(u,v) とし、Gfを作成する 10 (*) 本来は f(u,v)はフローの総和 道Pによって作られるフローではない 20 10 10 10 20 30 10 t 30 10 50 10 20 10 40 50 10 20 10 20 10 40 90 10 0 0 70 40 0 20 0 10 10 0 60 40 0 40 s Gfにおいて、s-t間の適当な道を考え、その流量の上限を算出する。 10 (ここでは複数回まとめて表示) 20 10 10 10 10 20 30 10 10 t 10 30 10 10 10 50 10 20 10 40 50 10 20 10 20 10 40 90 10 0 0 70 40 0 20 0 10 10 0 60 40 0 40 s 残余容量 Cf(u,v) = C(u,v) - f(u,v) とし、Gfを作成する 0 (*) 本来は f(u,v)はフローの総和 道Pによって作られるフローではない 0 20 20 0 40 10 20 50 0 0 0 20 60 0 100 20 20 20 0 40 0 0 0 80 40 0 20 0 10 10 0 60 40 0 40 t 10 90 s Gfにおいて、 s-t間の(Cf>0の辺で作られる)道が存在しないので、終了 0 0 20 20 0 40 10 20 50 0 0 0 20 60 0 100 20 20 20 0 40 0 0 0 80 40 0 20 0 10 10 0 60 40 0 40 t 10 90 s 最大流は以下のフローの総和である。 10 10 10 10 t 10 10 20 20 各辺が以下のフローを通すとき、sからtに対して最大流 が得られる。その流量は100 10 10 s 10 10 10 20 s 30 10 30 50 10 20 10 20 20 t 10 40 30 40 20 10 20 t 10 10 20 42 フォード・ファルカーソンの アルゴリズム Max-Flow(G(V,E), s, t) ∀e∈E, f(e)=0 While any paths from s to t exist in residual graph Gf 道の発見には P := simple-path(s,t) in Gf 「幅優先探索」「深さ優先探索」 などが用いられる f’ := augment(f, P) フロー f に道Pを流れるフローの上限分を Update f to be f’ 追加し、それを f’ に代入する処理 Update Gf to be Gf’ EndWhile ※ このアルゴリズムの停止性について Return f 考察してみよ 43 今日の内容 • 最小全域木 • プリムのアルゴリズム • 最大流問題 • フォード・ファルカーソンのアルゴリズム 44 今後の予定 • 6月26日: 分散ハッシュテーブル • Chord アルゴリズム • 7月3日: 平面的グラフ、地図 • 7月10日: スキップグラフ • 7月17日: 試験 13:00 – 14:30 @241講義室 45
© Copyright 2024 ExpyDoc