1
1
import random
2
2
from copy import deepcopy
3
+ import networkx as nx
4
+ import matplotlib .pyplot as plt
5
+ import glob
6
+ import imageio
7
+ import os
8
+ import cv2
9
+ import numpy as np
3
10
4
11
5
12
class FindMaximumMatching :
6
13
def __init__ (self , edges , vertices ):
14
+ self .graph = nx .Graph ()
7
15
self .edges = edges
8
16
self .vertices = set (vertices )
9
17
self .matching = []
10
18
self .saturated_vertices = set ()
11
19
self .separate = False
20
+ self .graph .add_nodes_from (self .vertices )
21
+ self .graph .add_edges_from (self .edges )
22
+ self .pos = nx .spring_layout (self .graph )
23
+ self .x = 0
24
+ self .images = []
25
+ self .draw_graph ()
26
+
27
+ def draw_graph (self , augmenting_path = None ):
28
+
29
+ nx .draw (self .graph , self .pos , with_labels = True , font_weight = 'bold' , node_size = 1000 , node_color = '#efc20e' , width = 4 ,
30
+ edge_color = '#82807b' , alpha = 0.8 , font_size = 16 )
31
+ temp = []
32
+ if augmenting_path :
33
+ for edge in augmenting_path :
34
+ temp .append (tuple (edge ))
35
+ nx .draw_networkx_edges (self .graph , self .pos ,
36
+ edgelist = temp ,
37
+ width = 8 , alpha = 0.5 , edge_color = 'r' )
38
+
39
+ for edge in self .matching :
40
+ temp .append (tuple (edge ))
41
+ nx .draw_networkx_edges (self .graph , self .pos ,
42
+ edgelist = temp ,
43
+ width = 8 , alpha = 0.5 , edge_color = 'b' )
44
+ nx .draw_networkx_nodes (self .graph , self .pos , nodelist = list (self .saturated_vertices ), node_color = '#207c36' ,
45
+ node_size = 1000 , alpha = 0.8 )
46
+
47
+ string = 'Matching Number: ' + str (len (self .matching ))
48
+ plt .axis ('off' )
49
+ plt .text (- 1 , 1 , string )
50
+
51
+ plt .savefig ('img{}.png' .format (self .x ), dpi = 120 , bbox_inches = 'tight' )
52
+ self .x = self .x + 1
53
+ plt .close ()
12
54
13
55
def find_maximum_matching (self ):
14
56
print ('matching' , self .matching )
15
57
fake_matching = []
58
+ useless_edges = set ()
16
59
reveiw_augmenting_path = False
17
60
i = 0
18
61
while True :
19
62
print ('--------------' , i , '--------------' )
20
63
i = i + 1
21
64
unsaturated = self .vertices .difference (self .saturated_vertices )
65
+ if reveiw_augmenting_path :
66
+ unsaturated = unsaturated .difference (useless_edges )
67
+
22
68
if len (unsaturated ) <= 1 :
23
69
print ('yaaay' )
24
70
return
25
71
if reveiw_augmenting_path :
26
72
print ('reveiwwwww' )
27
- print ('fucking unsaturated' , unsaturated )
28
73
start = unsaturated .pop ()
29
74
for finish in unsaturated :
30
75
path = self .bfs_find_path_between (start , finish )
@@ -42,15 +87,19 @@ def find_maximum_matching(self):
42
87
for j in range (0 , len (augmenting_vertices ) - 1 ):
43
88
augmenting_path .append ({augmenting_vertices [j ], augmenting_vertices [j + 1 ]})
44
89
print (augmenting_path )
90
+ self .draw_graph (augmenting_path )
91
+
45
92
for edge in augmenting_path :
46
93
if edge in self .matching :
47
94
self .matching .remove (edge )
48
95
else :
49
96
self .matching .append (edge )
50
97
print ('matching' , self .matching )
98
+ self .draw_graph ()
99
+
51
100
break
52
101
else :
53
- self . vertices . remove (start )
102
+ useless_edges . add (start )
54
103
55
104
else :
56
105
if not self .separate :
@@ -63,8 +112,10 @@ def find_maximum_matching(self):
63
112
for j in range (0 , len (augmenting_vertices ) - 1 ):
64
113
augmenting_path .append ({augmenting_vertices [j ], augmenting_vertices [j + 1 ]})
65
114
print (augmenting_path )
115
+ self .draw_graph (augmenting_path )
66
116
self .matching = [edge for edge in augmenting_path if edge not in self .matching ]
67
117
print ('matching' , self .matching )
118
+ self .draw_graph ()
68
119
else :
69
120
self .separate = True
70
121
fake_matching = []
@@ -83,13 +134,15 @@ def find_maximum_matching(self):
83
134
for j in range (0 , len (augmenting_vertices ) - 1 ):
84
135
augmenting_path .append ({augmenting_vertices [j ], augmenting_vertices [j + 1 ]})
85
136
print (augmenting_path )
137
+ self .draw_graph (augmenting_path )
86
138
for edge in augmenting_path :
87
139
if edge in self .matching :
88
140
self .matching .remove (edge )
89
141
else :
90
142
self .matching .append (edge )
91
143
92
144
print ('matching' , self .matching )
145
+ self .draw_graph ()
93
146
fake_matching = [edge for edge in augmenting_path if edge not in fake_matching ]
94
147
print ('fake matching ' , fake_matching )
95
148
else :
@@ -157,9 +210,7 @@ def bfs_find_path_between(self, start, finish):
157
210
visited .append (node )
158
211
159
212
def dfs (self , depth , vertices , v , is_matching , fake_matching = None , finish = None ):
160
- print ("depth " , depth , "vertices" , vertices , "v" , v , is_matching )
161
213
if finish is not None :
162
- print ('aaaaa' )
163
214
if depth is 0 and v is finish :
164
215
return [v ]
165
216
else :
@@ -175,15 +226,13 @@ def dfs(self, depth, vertices, v, is_matching, fake_matching=None, finish=None):
175
226
176
227
else :
177
228
connected_edges = [edge for edge in connected_edges if edge in self .matching ]
178
- print (connected_edges )
179
229
vertices .remove (v )
180
230
if len (connected_edges ) is 1 :
181
231
v1 , v2 = connected_edges [0 ]
182
232
if v1 == v :
183
233
path = self .dfs (depth - 1 , deepcopy (vertices ), v2 , not is_matching , fake_matching , finish )
184
234
else :
185
235
path = self .dfs (depth - 1 , deepcopy (vertices ), v1 , not is_matching , fake_matching , finish )
186
- # print('pp', path)
187
236
if path :
188
237
path .append (v )
189
238
return path
@@ -192,15 +241,13 @@ def dfs(self, depth, vertices, v, is_matching, fake_matching=None, finish=None):
192
241
connected_edges = [edge for edge in connected_edges if edge not in fake_matching ]
193
242
else :
194
243
connected_edges = [edge for edge in connected_edges if edge not in self .matching ]
195
- print (connected_edges )
196
244
vertices .remove (v )
197
245
for edge in connected_edges :
198
246
v1 , v2 = edge
199
247
if v1 == v :
200
248
path = self .dfs (depth - 1 , deepcopy (vertices ), v2 , not is_matching , fake_matching , finish )
201
249
else :
202
250
path = self .dfs (depth - 1 , deepcopy (vertices ), v1 , not is_matching , fake_matching , finish )
203
- # print('p', path)
204
251
if path :
205
252
path .append (v )
206
253
return path
@@ -219,11 +266,37 @@ def find_connected_edges_to_vertex(self, vertex, vertices):
219
266
return result
220
267
221
268
222
- vertices = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]
223
- # edges = [{1, 6}, {1, 7}, {1, 9}, {1, 10}, {2, 6}, {2, 7}, {2, 9}, {2, 10}, {3, 8}, {3, 10}, {4, 6}, {4, 10}, {5, 10}]
269
+ def make_circuit_video (movie_filename , fps ):
270
+ # sorting filenames in order
271
+ filenames = glob .glob ('img*.png' )
272
+ filenames_sort_indices = np .argsort ([int (os .path .basename (filename ).split ('.' )[0 ][3 :]) for filename in filenames ])
273
+ filenames = [filenames [i ] for i in filenames_sort_indices ]
274
+
275
+ # make movie
276
+ with imageio .get_writer (movie_filename , mode = 'I' , fps = fps ) as writer :
277
+ for filename in filenames :
278
+ image = imageio .imread (filename )
279
+ cv2 .imshow ('hel' , image )
280
+ key = cv2 .waitKey (1000 ) # ~ 30 frames per second
281
+
282
+ os .remove (filename )
283
+ writer .append_data (image )
284
+
285
+
286
+
287
+ # sample 1
288
+ vertices = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
289
+ edges = [{1 , 6 }, {1 , 7 }, {1 , 9 }, {1 , 10 }, {2 , 6 }, {2 , 7 }, {2 , 9 }, {2 , 10 }, {3 , 8 }, {3 , 10 }, {4 , 6 }, {4 , 10 }, {5 , 10 }]
290
+
291
+ ## sample 2
292
+ # vertices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
224
293
# edges = [{1, 6}, {1, 7}, {2, 7}, {2, 9}, {3, 8}, {3, 6}, {4, 7}, {4, 10}, {5, 10}, {5, 8}]
225
- edges = [{1 , 3 }, {1 , 6 }, {1 , 8 }, {2 , 4 }, {2 , 6 }, {2 , 7 }, {2 , 8 }]
294
+
295
+ ## sample 3
296
+ # vertices = [1, 2, 3, 4, 5, 6, 7, 8]
297
+ # edges = [{1, 4}, {1, 5}, {1, 6}, {2, 5}, {2, 7}, {2, 8}, {3, 5}, {3, 8}]
226
298
227
299
f = FindMaximumMatching (edges , vertices )
228
300
f .find_maximum_matching ()
229
301
print (f .matching )
302
+ make_circuit_video ('animation.gif' , fps = 1 )
0 commit comments