隨機化最小割
Vibe Prompt
「實作 Karger's Contraction 演算法,找到圖形的最小割。跑 100 次取最佳結果。」
import random, copy
def karger_min_cut(graph):
"""
graph: {node: [neighbors]}
"""
while len(graph) > 2:
# 隨機選一條邊
u = random.choice(list(graph.keys()))
v = random.choice(graph[u])
# 合併 v 到 u
graph[u].extend(graph[v])
for w in graph[v]:
graph[w] = [u if x == v else x for x in graph[w]]
graph[u] = [x for x in graph[u] if x != u]
del graph[v]
# 剩餘兩節點之間的邊數 = 最小割
nodes = list(graph.keys())
return len([x for x in graph[nodes[0]] if x == nodes[1]])
def find_min_cut(graph, trials=100):
best = float('inf')
for i in range(trials):
g = copy.deepcopy(graph)
cut = karger_min_cut(g)
if cut < best:
best = cut
print(f"第 {i+1} 次: 找到更小割 {best}")
return best
# 測試
graph = {
0: [1, 2, 3],
1: [0, 2, 3],
2: [0, 1, 3, 4],
3: [0, 1, 2, 4],
4: [2, 3, 5, 6],
5: [4, 6],
6: [4, 5],
}
min_cut = find_min_cut(graph, trials=50)
print(f"最小割: {min_cut}")
# 理論值:這個圖的最小割是 2(切開 {4,5,6})