RCO アルゴリズムイントロダクション輪読会 26. 最大フロー 2
先週のページ
kenkoooo.hatenablog.com
少し被りがあります。
先週のまとめ
- G の任意のフロー f の値は G の任意のカット容量によって上から抑えられる。
定理 26.6 最大フロー最小カットの定理
- fはGの最大フローである。
- 残余ネットワーク Gf は増加可能経路を含まない。
- Gのあるカット(S,T)に対して|f|=c(S,T) である。
証明
最大フローであるにも関わらず増加可能経路を持つと仮定すると、 が定まり、|f| より値が大きいGのフローが得られるので矛盾する。
Gf が増加可能経路を持たないとき、Gfにはsからtへの道が存在しない。
と定義する。
明らかにであり、
にはsからtへの道が存在しないので
である。よって、この分割(S,T)はカットである。
かつ
かつ
であるようなu, v を考える。
ならば
であり、
となり矛盾する。よって
である。
ならば
で
だから
となり矛盾する。よって
全てのカット(S, T) に対してである。よって
はfが最大フローであるための十分条件である。
Ford-Fulkersonのアルゴリズム
Ford-Fulkerson(G, s, t) for (u, v) in G.E (u, v).f = 0 while 残余ネットワーク G_f に s から t への道 p が存在する c_f(p) = min([c_f(u, v) for (u, v) in p]) for (u, v) in p if (u, v) in G.E (u, v).f = (u, v).f + c_f(p) else (v, u).f = (v, u).f - c_f(p)
基本 Ford-Fulkerson の解析
増加可能経路を見つけるための DFS が O(E)
最大フローが f* とすると、ループは最悪で |f*| 回走る。
よって O(E|f*|)
余談
高速な最大フローのアルゴリズムはで動作するが、最大フローの値が十分小さければ Ford-Fulkerson の方が速くなることがある。
http://judge.u-aizu.ac.jp/onlinejudge/cdescription.jsp?cid=ACPC2016Day3&pid=F
2 部グラフの最大マッチング問題
プッシュ再ラベルアルゴリズム
今までは頂点にフローを溜め込むことができない条件のみを考えてきた。
頂点 u に流入するフローと頂点 u から流出するフローの合計が等しかった。
これを緩和して、流入量が流出量を超えることが出来るものとする。
このような条件でのフローをプリフローと呼ぶ。
この過剰量を e(u) とする。
について、
となるような頂点
をオーバーフロー頂点と呼ぶ。
高さ関数
であり、残余辺
について、
が成り立つような高さ関数 h を考える。
プッシュ操作
以下の条件を満たす残余辺 (u, v) について、u から v にフローをプッシュする。
Push(u, v) # 適用条件: u がオーバーフロー頂点で、c_f(u, v) > 0 かつ h(u) = h(v) + 1 df = min(e(u), c_f(u, v)) if (u, v) in E (u, v).f = (u, v).f + df else (v, u).f = (v, u).f - df e(u) -= df e(v) += df
プッシュ後に となるようなプッシュを飽和プッシュと呼ぶ。
再ラベル操作
かつ
の全ての v について
であるとき、u の高さを上げる。
Relabel(u) # 適用条件: u がオーバーフロー頂点、かつ、h(u) <= h(v) h(u) = 1 + min([h(v) for (u, v) in E_f])
基礎アルゴリズム
Initialize-Preflow(G, s) for v in V h(v) = 0 e(v) = 0 for (u, v) in E (u, v).f = 0 h(s) = |V| for v in G[s] (s, v).f = c(s, v) e(v) = c(s,v) e(s) -= c(s, v)
これによって s から出る全ての辺に容量上限までフローを流す。
つまり、s から出る辺は残余グラフに含まれなくなる。
よって全ての残余辺 について
が成り立つ。
(全てのについて
だから)
Generic-Push-Relabel(G)
Initialize-Preflow(G, s)
while 適用可能な push か relabel がある
適用可能な push か relabel を選び、実行する
補題 26.14
u がオーバーフロー頂点であれば、push か relabel が実行可能である。
証明
u から push が実行可能でない場合、全ての残余辺 について、
である。
このとき、 であり、relabel が実行可能である。
補題26.15
Generic-Push-Relabel の実行中、h(u) は減少しない。
証明
h(u) は relabel 以外では変化せず、relabel では適用のたびに必ず 1 以上増える。
補題26.16
Generic-Push-Relabel は h を高さ関数として維持する。
証明
初期状態では h が高さ関数制約を満たしている。
u から出る辺 (u, v) を考える。
Relabel(u) を行った後は が保証される。
u に入る辺 (w, u) を考える。
Relabel(u) の前に が成立していたならば、操作後は
が成立する。
よって Relabel(u) は高さ制約を維持する。
Push(u, v) を実行することを考える。
Push(u, v) によって が減少するとき、
が増加する。
これは に (v, u) が加わると考えられる。
このとき だから
である。
新しい残余辺 (v, u) について が成り立つ。
Push(u, v) によって が減少するとき、
から (u, v) が取り除かれると考える。
このときは、制約が取り除かれるので、再び h は高さ関数である。
補題26.17
f をプリフローとする。このとき残余グラフ には s から t への道はない。
証明
矛盾を導くために における s から t への道
が存在すると仮定する。
である。
一般性を失うことなく と仮定する。
に対して
である。
に対して
である。
よって である。
ここでだから
となり、高さ関数制約
に矛盾する。
補題26.18
Generic-Push-Relabel を実行して停止したとき、プリフロー f は最大フローである。
Push-Relabel の解析
補題 26.19
f をプリフローとする。この時、残余ネットワークの任意のオーバーフロー頂点 u から s への単純道が存在する。
証明
オーバーフロー頂点 x について、とする。
s が U に含まれることを示す。
矛盾を導くためにを仮定する。
とする。
より、
かつ、s以外のすべての頂点が非負の過剰を持ち、
だから、
である。
したがって
フローは非負だから
よってとなる
が存在する。
よって残余ネットワークには残余辺
が存在する。
よって道 が存在する。これは
となり矛盾。
補題 26.20
Generic-Push-Relabel 実行中はすべての頂点 u で が成り立つ。
系 26.21
relabel の回数は頂点当たり高々回である。
補題 26.22
飽和プッシュ回数は回である。
補題 26.23
非飽和プッシュ回数は回である。
次回予告
Push-Relabel の解析
フロント移動
練習問題
おまけ
実装落ちてた。
github.com