class RandomizedGlobalMinCut; end
class << RandomizedGlobalMinCut
private
def make_graph_representation(es)
ve = {}; ev = {}; v_living = []; e_living = []; v_max = -1
es.each.with_index do |vs,i|
v0,v1 = vs
ve[v0] ? (ve[v0] << i):(ve[v0] = [i])
ve[v1] ? (ve[v1] << i):(ve[v1] = [i])
ev[i] = [v0,v1]
v_living << v0; v_living << v1; e_living << i
m = [v0,v1].max
v_max = m if v_max < m
end
[ve,ev,v_living.uniq,e_living,v_max]
end
def calc_main(g)
ve,ev,v_living,e_living,v_max = g
closure = {}
v_living.each do |v|
closure[v] = [v]
end
while v_living.length > 2
e = e_living[Random.rand(e_living.length)]
v0,v1 = ev[e]
v = v_max+1
[v0,v1].each do |w|
ve[w].each do |f|
ev[f].map!{|x| x == w ? v : x}
end
end
ve[v] = (ve[v0].select{|x|x!=e} + ve[v1].select{|x|x!=e}).uniq
ve.delete(v0); ve.delete(v1); ev.delete(e)
v_living = v_living - [v0,v1] + [v]
e_living = e_living - [e]
closure[v] = (closure[v0] + closure[v1]).uniq
v_max += 1
end
v0,v1 = v_living
[closure[v0],closure[v1]]
end
def cut_val(es, cut)
count = 0
es.each do |e|
count += 1 if cut[0].include?(e[0]) && cut[1].include?(e[1]) || cut[1].include?(e[0]) && cut[0].include?(e[1])
end
count
end
public
def calc(es)
g = make_graph_representation(es)
vn = g[2].length
iter_n = ((vn*(vn-1)/2)*Math.log(vn)).ceil
min_cut = nil
min_val = 10**10
iter_n.times do
g = make_graph_representation(es)
cut = calc_main(g)
val = cut_val(es,cut)
if val < min_val
min_val = val
min_cut = cut
end
end
[min_val,min_cut]
end
end
def k_n(n)
es = []
(0...n).each do |j|
(j...n).each do |i|
es << [i,j] if i != j
end
end
es
end
if __FILE__ == $0
p RandomizedGlobalMinCut::calc(k_n(13))
end
Y2xhc3MgUmFuZG9taXplZEdsb2JhbE1pbkN1dDsgZW5kCmNsYXNzIDw8IFJhbmRvbWl6ZWRHbG9iYWxNaW5DdXQKICBwcml2YXRlCiAgZGVmIG1ha2VfZ3JhcGhfcmVwcmVzZW50YXRpb24oZXMpCiAgICB2ZSA9IHt9OyBldiA9IHt9OyB2X2xpdmluZyA9IFtdOyBlX2xpdmluZyA9IFtdOyB2X21heCA9IC0xCiAgICBlcy5lYWNoLndpdGhfaW5kZXggZG8gfHZzLGl8CiAgICAgIHYwLHYxID0gdnMKICAgICAgdmVbdjBdID8gKHZlW3YwXSA8PCBpKToodmVbdjBdID0gW2ldKQogICAgICB2ZVt2MV0gPyAodmVbdjFdIDw8IGkpOih2ZVt2MV0gPSBbaV0pCiAgICAgIGV2W2ldID0gW3YwLHYxXQogICAgICB2X2xpdmluZyA8PCB2MDsgdl9saXZpbmcgPDwgdjE7IGVfbGl2aW5nIDw8IGkKICAgICAgbSA9IFt2MCx2MV0ubWF4CiAgICAgIHZfbWF4ID0gbSBpZiB2X21heCA8IG0KICAgIGVuZAogICAgW3ZlLGV2LHZfbGl2aW5nLnVuaXEsZV9saXZpbmcsdl9tYXhdCiAgZW5kCiAgZGVmIGNhbGNfbWFpbihnKQogICAgdmUsZXYsdl9saXZpbmcsZV9saXZpbmcsdl9tYXggPSBnCiAgICBjbG9zdXJlID0ge30KICAgIHZfbGl2aW5nLmVhY2ggZG8gfHZ8CiAgICAgIGNsb3N1cmVbdl0gPSBbdl0KICAgIGVuZAogICAgd2hpbGUgdl9saXZpbmcubGVuZ3RoID4gMgogICAgICBlID0gZV9saXZpbmdbUmFuZG9tLnJhbmQoZV9saXZpbmcubGVuZ3RoKV0KICAgICAgdjAsdjEgPSBldltlXQogICAgICB2ID0gdl9tYXgrMQogICAgICBbdjAsdjFdLmVhY2ggZG8gfHd8CiAgICAgICAgdmVbd10uZWFjaCBkbyB8ZnwKICAgICAgICAgIGV2W2ZdLm1hcCF7fHh8IHggPT0gdyA/IHYgOiB4fQogICAgICAgIGVuZAogICAgICBlbmQKICAgICAgdmVbdl0gPSAodmVbdjBdLnNlbGVjdHt8eHx4IT1lfSArIHZlW3YxXS5zZWxlY3R7fHh8eCE9ZX0pLnVuaXEKICAgICAgdmUuZGVsZXRlKHYwKTsgdmUuZGVsZXRlKHYxKTsgZXYuZGVsZXRlKGUpCiAgICAgIHZfbGl2aW5nID0gdl9saXZpbmcgLSBbdjAsdjFdICsgW3ZdCiAgICAgIGVfbGl2aW5nID0gZV9saXZpbmcgLSBbZV0KICAgICAgY2xvc3VyZVt2XSA9IChjbG9zdXJlW3YwXSArIGNsb3N1cmVbdjFdKS51bmlxCiAgICAgIHZfbWF4ICs9IDEKICAgIGVuZAogICAgdjAsdjEgPSB2X2xpdmluZwogICAgW2Nsb3N1cmVbdjBdLGNsb3N1cmVbdjFdXQogIGVuZAogIGRlZiBjdXRfdmFsKGVzLCBjdXQpCiAgICBjb3VudCA9IDAKICAgIGVzLmVhY2ggZG8gfGV8CiAgICAgIGNvdW50ICs9IDEgaWYgY3V0WzBdLmluY2x1ZGU/KGVbMF0pICYmIGN1dFsxXS5pbmNsdWRlPyhlWzFdKSB8fCBjdXRbMV0uaW5jbHVkZT8oZVswXSkgJiYgY3V0WzBdLmluY2x1ZGU/KGVbMV0pCiAgICBlbmQKICAgIGNvdW50CiAgZW5kCiAgcHVibGljCiAgZGVmIGNhbGMoZXMpCiAgICBnID0gbWFrZV9ncmFwaF9yZXByZXNlbnRhdGlvbihlcykKICAgIHZuID0gZ1syXS5sZW5ndGgKICAgIGl0ZXJfbiA9ICgodm4qKHZuLTEpLzIpKk1hdGgubG9nKHZuKSkuY2VpbAogICAgbWluX2N1dCA9IG5pbAogICAgbWluX3ZhbCA9IDEwKioxMAogICAgaXRlcl9uLnRpbWVzIGRvCiAgICAgIGcgPSBtYWtlX2dyYXBoX3JlcHJlc2VudGF0aW9uKGVzKQogICAgICBjdXQgPSBjYWxjX21haW4oZykKICAgICAgdmFsID0gY3V0X3ZhbChlcyxjdXQpCiAgICAgIGlmIHZhbCA8IG1pbl92YWwKICAgICAgICBtaW5fdmFsID0gdmFsCiAgICAgICAgbWluX2N1dCA9IGN1dAogICAgICBlbmQKICAgIGVuZAogICAgW21pbl92YWwsbWluX2N1dF0KICBlbmQKZW5kCgpkZWYga19uKG4pCiAgZXMgPSBbXQogICgwLi4ubikuZWFjaCBkbyB8anwKICAgIChqLi4ubikuZWFjaCBkbyB8aXwKICAgICAgZXMgPDwgW2ksal0gaWYgaSAhPSBqCiAgICBlbmQKICBlbmQKICBlcwplbmQKCmlmIF9fRklMRV9fID09ICQwCiAgcCBSYW5kb21pemVkR2xvYmFsTWluQ3V0OjpjYWxjKGtfbigxMykpCmVuZA==
[12, [[3], [12, 6, 4, 1, 11, 10, 8, 7, 2, 5, 0, 9]]]