ちょっと諸事情で過去に勉強したアルゴリズムを復習したくて、Mincutアルゴリズムを再度勉強していた。
VLSIにおいて配置配線をする際に使用されるアルゴリズムとして有名なものに、Quadratic Placement & Mincutというものがある。 そのうちのMincutは、1つのグラフを、なるべく同じ大きさで、交差する辺を最小にしつつ分割するアルゴリズムだ。
以下のWikipediaが参考になる。
function Kernighan-Lin(G(V, E)) is determine a balanced initial partition of the nodes into sets A and B do compute D values for all a in A and b in B let gv, av, and bv be empty lists for n := 1 to |V| / 2 do find a from A and b from B, such that g = D[a] + D[b] − 2×c(a, b) is maximal remove a and b from further consideration in this pass add g to gv, a to av, and b to bv update D values for the elements of A = A \ a and B = B \ b end for find k which maximizes g_max, the sum of gv[1], ..., gv[k] if g_max > 0 then Exchange av[1], av[2], ..., av[k] with bv[1], bv[2], ..., bv[k] until (g_max ≤ 0) return G(V, E)
あるノードに着目し、グループの中でまとまっている辺をとし、グループから外に出る辺をとする。この時の差分をと計算する。また、はノードaからbのコストを示す。
コメントにあるように、が最大となるとを見つける。この式の意味は、内部に接続が多い方がが大きくなるため、内部へのパスが多いとを選択し、かつからへの接続のコストを引いたものなり、とを直接つなぐコスト以外の、内部の辺への寄与率を示したものになる。
つぎに、ここで選んだとを削除し、残ったノードに対して再度を計算し直す。この際、とを選択した際のの値を]として記憶しておく。選択したを, 選択したをとしてリストに追加する。
この結果、, g[i], …, g[k])]の値が最も大きくなるを算出する。この値が正であれば、, av[1], …, av[2]] と , bv[1], … bv[k]]を交換する。
上記のsumの値が最終的にマイナスになるまで繰り返すことでこのアルゴリズムは終了する。