blogskol

思わず声に出して読みたくなるブログ

最大マッチングの何か

仲のいい子としか組みたく無い生意気なガキ達を受け持った時にどうにか沢山二人組を作らせないといけない人向けの記事
ただしガキは友好関係を無向グラフで与えてくれるものとする(友好なのに無向)

サムネ用画像

マッチング

無向グラフG=(V,E)に対して端点を共有しない辺集合M\subseteq Eのこと

太線がマッチング、赤点がカバーされている点
今回はマッチングMのうち最大のやつを求める方法を考える
頂点vMの辺の端点になってる時vMにカバーされていると言う
今回の問題はカバーされてない頂点が最小となるマッチングを求めるとも言える
全ての頂点がカバーされてるマッチングのことを完全マッチングと言う
完全マッチングのイラスト

交互道

グラフ上の点素パスで、Mの辺と非Mの辺を交互に使うやつ

増加道

交互道で始点と終点がともにMでカバーされてないやつ

青い矢印が増加道

Thm

増加道があったらMと増加道で対称差をとる(図のようにMに入ってるかどうかを入れ替える)と一つサイズの大きいマッチングが出来る(この操作をaugmentと呼ぶ)
また、Mが最大マッチングで無い限り必ず増加道は存在する( 最大マッチングM'Mの対称差をとると交互道と交互サイクルだけになることから示せる)

augmentの例



Thmより、最大マッチングになるまで増加道を見つけてaugmentすればOK
終わり











もうちょっとだけ続くんじゃ

マッチングMとカバーされてない頂点rが与えられた時、

(a)rを始点とする増加道を見つけてaugmentする
(b)rをカバーしない最大マッチングが存在することを示しrをグラフから削除する

のどっちか片方を必ず行うアルゴリズムを作れれば、全ての点がカバーされたグラフになるまでこのアルゴリズムを適用することで最大マッチングが得られるのでこれを考える

rが辺を持っていない時:明らかにrを削除していいのでOK
そうで無い時: まずはrを始点とする増加道を探す為、rを端点とする辺rvを見る(この辺は当然Mに含まれていない)

(A)vがカバーされてない時: 増加道発見おめでとう



(B)vwとマッチングしている時: r,v,wが交互道なので、wに隣接する非M辺も増加道の候補になる




そこで、交互木Tと言うものを考えることにする
これはrを根とする根付き木で、

  1. Tの頂点はrのみカバーされていない
  2. rからTの各頂点へのT上のパスは交互道になっている

の二つを満たすものである

赤が偶点、白が奇点

T上の各頂点について、rからのT上の距離が偶数(奇数)の時偶点(奇点)と呼ぶ
この時、各偶点uについて、T外の頂点vに対し辺uvが存在する時
(A')vがカバーされてない時:
rからvへの増加道発見おめでとう




(B')vwとマッチングしている時(この時wTの点では無い):
uv,vwTに加えてTを(交互木を保って)拡大出来る(この操作をextendと呼ぶ)





また、交互木には嬉しい性質が存在する

frustratedの定理(名前は適当)

交互木Tが、Tの偶点を端点に持つようなGの辺が全てもう片方の端点をTの奇点に持つ時frustratedと言う
この時、V(T)についてはマッチングを固定してしまい以降はG\backslash Tのみを考えることにして良い(この操作をdeleteと呼ぶ)

proof:

Tの奇点の数をkと置くと、偶点の数はk+1である(これは交互木なら常に成り立つ)
Tから奇点全部取り除くと、仮定からk+1個の偶点は全て孤立してしまう
この時、k個の奇点とk個の偶点によるマッチングが存在するならそのマッチングを固定してしまって良い(偶点は奇点とマッチング出来なければ孤立してしまうため、奇点を偶点以外とマッチングさせることに嬉しさが無いので)
Tでは実際k個の奇点とk個の偶点によるマッチングになっているから固定させてOK



進捗:
偶点から伸びてる辺の相手が全て奇点ならTを削除出来る
偶点から伸びてる辺の相手がTの外のカバーされてない点ならaugment出来る
偶点から伸びてる辺の相手がTの外のカバーされている点ならextend出来る
未進捗:
偶点から伸びてる辺の相手が他の偶点の時


偶点から偶点に伸びてる辺が存在する時、図のように奇数長の閉路が出来る

この時は、この閉路を図のように一点に縮約すると良いです(この操作をshrinkと言う)

7点をまとめて一つの点として扱うことにする
びっくりですね
終わり





以下のことが成り立ちます

  • 一点に潰す操作をしても交互木の性質を保つ
  • 交互木の点のうち潰されて出来たものは全て偶点で、潰される前の頂点数は必ず奇数
  • 任意の頂点は潰される前の世界で見ると因子臨界的

(頂点集合A因子臨界的:Aからどの一点を除いても残りの|A|-1点で完全マッチングが出来る)

奇数長閉路は図のようにどの一点を除いても残りで完全マッチングが作れる
奇数閉路の中に奇数閉路があったりしても因子臨界的

これらから、frustratedの定理は潰された頂点を含む場合にも適用して良いことがわかる (k個の奇点を除くとk+1個の 偶点=潰される前の世界における奇数連結成分 が孤立するから、奇点は各連結成分の一点とマッチングさせてやって良い。各連結成分は因子臨界的なので、一点が奇点とマッチングすれば残りの点は完全マッチングが作れる)

したがって、augmentかdeleteをするたびに潰されていた各点を引き戻してやり、引き戻す前とカバーされてない点の個数が変わらないようにいい感じにマッチングを張ってあげるとOK

分かりづらくなってきたのでアルゴリズムの形で書いてまとめる
グラフG,マッチングM,カバーされてない点rを与えるとaugmentかdeleteを必ず行う
Algoをカバーされてない点が全てdeleteされるまで繰り返すと最大マッチングになります

Algo

T:=( \{ r \} ,\phi)
while:偶点vと非奇点wの間に辺が存在
 if:wが偶点 shrink(vw)
 else if wがカバーされてる: extend(vw)
 else
  augment(vw)
  break;
shrinkを引き戻していい感じにマッチングを割り当てる
augmentして無い場合:delete(T)



これをカバーされてない点が全てdeleteされるまで繰り返す





Algoは

  • カバーされてない点の個数が増えることは無い
  • while中頂点数が増えることは無い
  • while中Tの外の点が増えることは無い

が成り立つから、

  1. 行われる回数はO(N) (一回行うたびに考える必要のあるカバーされてない頂点数が減るので)
  2. 一回のAlgo中shrinkの行われる回数はO(N) (一回行うたびに頂点数が減るので)
  3. 一回のAlgo中extendの行われる回数はO(N) (一回行うたびにTの外の点が減るので)

したがって必ず停止する
計算量はshrinkの部分をうまくやるとO(N^3)
UnionFindとか使ってもほとんど変わらないはず
増加道を最短のものから見つける工夫をするとDinicの2部マッチングみたいにO(M\sqrt N)まで落ちるらしい
細かい実装とかは読者への演習問題とします

参考文献 : William J. Cook, William H. Cunningham, William R. Pulleyblank, Alexander Schrijver Combinatorial Optimization December 1997