-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStoer-Wagner's Algorithm.py
84 lines (68 loc) · 2.62 KB
/
Stoer-Wagner's Algorithm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
"""
The Stoer-Wagner algorithm is used to find the minimum cut of a graph. It is an iterative algorithm that works by
contracting vertices of the graph until there are only two vertices left. The minimum cut is then the sum of the
weights of the edges that connect these two vertices.
"""
from sys import maxsize
def minimum_cut(graph):
"""
Computes the minimum cut in an undirected graph using the Stoer-Wagner algorithm.
Args:
graph (List[List[int]]): Adjacency matrix representation of the graph.
Returns:
Tuple[int, List[int]]: Tuple containing the minimum cut value and the nodes in the cut.
"""
n = len(graph) # Number of vertices
mincut = maxsize # Initialize mincut with a large value
bestcut = [] # Store the nodes in the best cut
# Iterate over all possible subsets of nodes
for i in range(n):
# Active vertices that haven't been contracted
active = [True] * n
# Potential nodes for contraction
v = list(range(n))
a = i
# Contract vertices until only 2 nodes are left
for _ in range(n - 1):
active[a] = False # Mark vertex 'a' as inactive
# Find the most tightly connected vertex to 'a'
b = -1
mincutval = -maxsize - 1
for j in range(n):
if active[j]:
cutval = graph[a][j]
if cutval > mincutval:
mincutval = cutval
b = j
# Contract vertex 'a' and 'b'
if _ == n - 2:
# Last iteration, store the cut value and nodes
last = [a, b]
cut = min(graph[a][b], mincut)
if cut == mincut:
bestcut = last
mincut = min(cut, mincut)
else:
# Contract vertices 'a' and 'b'
for j in range(n):
graph[a][j] += graph[b][j]
graph[j][a] += graph[j][b]
active[b] = False # Mark vertex 'b' as inactive
# Update the weights of the merged vertex
for j in range(n):
if active[j]:
graph[a][j] -= graph[b][j]
graph[j][a] -= graph[j][b]
a = b # Contracted vertex
return mincut, bestcut
# Example usage with adjacency matrix
graph = [
[0, 2, 3, 0, 0],
[2, 0, 5, 1, 0],
[3, 5, 0, 4, 2],
[0, 1, 4, 0, 3],
[0, 0, 2, 3, 0]
]
cut_value, cut_nodes = minimum_cut(graph)
print("Minimum Cut Value:", cut_value)
print("Nodes in the Cut:", cut_nodes)