7
7
8
8
class EdmondsBlossomAlgorithm :
9
9
@staticmethod
10
- def maximum_matching (edges : List [Tuple [int , int ]], vertex_count : int ) -> List [Tuple [int , int ]]:
10
+ def maximum_matching (
11
+ edges : List [Tuple [int , int ]], vertex_count : int
12
+ ) -> List [Tuple [int , int ]]:
11
13
"""
12
14
Finds the maximum matching in a general graph using Edmonds' Blossom Algorithm.
13
15
@@ -61,7 +63,9 @@ def maximum_matching(edges: List[Tuple[int, int]], vertex_count: int) -> List[Tu
61
63
if match [neighbor ] == UNMATCHED :
62
64
parent [neighbor ] = current_vertex
63
65
augmenting_path_found = True
64
- EdmondsBlossomAlgorithm .update_matching (match , parent , neighbor )
66
+ EdmondsBlossomAlgorithm .update_matching (
67
+ match , parent , neighbor
68
+ )
65
69
break
66
70
67
71
# Case 2: neighbor is matched, add neighbor's match to the queue
@@ -73,12 +77,25 @@ def maximum_matching(edges: List[Tuple[int, int]], vertex_count: int) -> List[Tu
73
77
in_queue [matched_vertex ] = True
74
78
else :
75
79
# Case 3: Both current_vertex and neighbor have a parent; check for a cycle/blossom
76
- base_vertex = EdmondsBlossomAlgorithm .find_base (base , parent , current_vertex , neighbor )
80
+ base_vertex = EdmondsBlossomAlgorithm .find_base (
81
+ base , parent , current_vertex , neighbor
82
+ )
77
83
if base_vertex != UNMATCHED :
78
- EdmondsBlossomAlgorithm .contract_blossom (BlossomData (
79
- BlossomAuxData (queue , parent , base , in_blossom , match , in_queue ),
80
- current_vertex , neighbor , base_vertex
81
- ))
84
+ EdmondsBlossomAlgorithm .contract_blossom (
85
+ BlossomData (
86
+ BlossomAuxData (
87
+ queue ,
88
+ parent ,
89
+ base ,
90
+ in_blossom ,
91
+ match ,
92
+ in_queue ,
93
+ ),
94
+ current_vertex ,
95
+ neighbor ,
96
+ base_vertex ,
97
+ )
98
+ )
82
99
83
100
# Create result list of matched pairs
84
101
matching_result = []
@@ -89,7 +106,9 @@ def maximum_matching(edges: List[Tuple[int, int]], vertex_count: int) -> List[Tu
89
106
return matching_result
90
107
91
108
@staticmethod
92
- def update_matching (match : List [int ], parent : List [int ], current_vertex : int ) -> None :
109
+ def update_matching (
110
+ match : List [int ], parent : List [int ], current_vertex : int
111
+ ) -> None :
93
112
"""
94
113
Updates the matching along the augmenting path found.
95
114
@@ -111,7 +130,9 @@ def update_matching(match: List[int], parent: List[int], current_vertex: int) ->
111
130
current_vertex = next_vertex
112
131
113
132
@staticmethod
114
- def find_base (base : List [int ], parent : List [int ], vertex_u : int , vertex_v : int ) -> int :
133
+ def find_base (
134
+ base : List [int ], parent : List [int ], vertex_u : int , vertex_v : int
135
+ ) -> int :
115
136
"""
116
137
Finds the base of a node in the blossom.
117
138
@@ -146,7 +167,7 @@ def find_base(base: List[int], parent: List[int], vertex_u: int, vertex_v: int)
146
167
current_vertex_v = parent [current_vertex_v ]
147
168
148
169
@staticmethod
149
- def contract_blossom (blossom_data : ' BlossomData' ) -> None :
170
+ def contract_blossom (blossom_data : " BlossomData" ) -> None :
150
171
"""
151
172
Contracts a blossom in the graph, modifying the base array
152
173
and marking the vertices involved.
@@ -162,18 +183,26 @@ def contract_blossom(blossom_data: 'BlossomData') -> None:
162
183
current_vertex_u = blossom_data .u
163
184
while blossom_data .aux_data .base [current_vertex_u ] != blossom_data .lca :
164
185
base_u = blossom_data .aux_data .base [current_vertex_u ]
165
- match_base_u = blossom_data .aux_data .base [blossom_data .aux_data .match [current_vertex_u ]]
186
+ match_base_u = blossom_data .aux_data .base [
187
+ blossom_data .aux_data .match [current_vertex_u ]
188
+ ]
166
189
blossom_data .aux_data .in_blossom [base_u ] = True
167
190
blossom_data .aux_data .in_blossom [match_base_u ] = True
168
- current_vertex_u = blossom_data .aux_data .parent [blossom_data .aux_data .match [current_vertex_u ]]
191
+ current_vertex_u = blossom_data .aux_data .parent [
192
+ blossom_data .aux_data .match [current_vertex_u ]
193
+ ]
169
194
170
195
current_vertex_v = blossom_data .v
171
196
while blossom_data .aux_data .base [current_vertex_v ] != blossom_data .lca :
172
197
base_v = blossom_data .aux_data .base [current_vertex_v ]
173
- match_base_v = blossom_data .aux_data .base [blossom_data .aux_data .match [current_vertex_v ]]
198
+ match_base_v = blossom_data .aux_data .base [
199
+ blossom_data .aux_data .match [current_vertex_v ]
200
+ ]
174
201
blossom_data .aux_data .in_blossom [base_v ] = True
175
202
blossom_data .aux_data .in_blossom [match_base_v ] = True
176
- current_vertex_v = blossom_data .aux_data .parent [blossom_data .aux_data .match [current_vertex_v ]]
203
+ current_vertex_v = blossom_data .aux_data .parent [
204
+ blossom_data .aux_data .match [current_vertex_v ]
205
+ ]
177
206
178
207
# Update the base for all marked vertices
179
208
for i in range (len (blossom_data .aux_data .base )):
@@ -189,8 +218,15 @@ class BlossomAuxData:
189
218
Auxiliary data class to encapsulate common parameters for the blossom operations.
190
219
"""
191
220
192
- def __init__ (self , queue : deque , parent : List [int ], base : List [int ],
193
- in_blossom : List [bool ], match : List [int ], in_queue : List [bool ]) -> None :
221
+ def __init__ (
222
+ self ,
223
+ queue : deque ,
224
+ parent : List [int ],
225
+ base : List [int ],
226
+ in_blossom : List [bool ],
227
+ match : List [int ],
228
+ in_queue : List [bool ],
229
+ ) -> None :
194
230
self .queue = queue
195
231
self .parent = parent
196
232
self .base = base
0 commit comments