2828@sort: accessibility, connected_components, cut_edges, cut_nodes, mutual_accessibility
2929"""
3030
31-
3231# Imports
3332from sys import getrecursionlimit , setrecursionlimit
3433
3534# Transitive-closure
3635
36+
3737def accessibility (graph ):
3838 """
3939 Accessibility matrix (transitive closure).
@@ -45,23 +45,24 @@ def accessibility(graph):
4545 @return: Accessibility information for each node.
4646 """
4747 recursionlimit = getrecursionlimit ()
48- setrecursionlimit (max (len (graph .nodes ())* 2 , recursionlimit ))
49-
50- accessibility = {} # Accessibility matrix
48+ setrecursionlimit (max (len (graph .nodes ()) * 2 , recursionlimit ))
49+
50+ accessibility = {} # Accessibility matrix
5151
5252 # For each node i, mark each node j if that exists a path from i to j.
5353 for each in graph :
5454 access = {}
5555 # Perform DFS to explore all reachable nodes
5656 _dfs (graph , access , 1 , each )
5757 accessibility [each ] = list (access .keys ())
58-
58+
5959 setrecursionlimit (recursionlimit )
6060 return accessibility
6161
6262
6363# Strongly connected components
6464
65+
6566def mutual_accessibility (graph ):
6667 """
6768 Mutual-accessibility matrix (strongly connected components).
@@ -73,12 +74,12 @@ def mutual_accessibility(graph):
7374 @return: Mutual-accessibility information for each node.
7475 """
7576 recursionlimit = getrecursionlimit ()
76- setrecursionlimit (max (len (graph .nodes ())* 2 , recursionlimit ))
77-
77+ setrecursionlimit (max (len (graph .nodes ()) * 2 , recursionlimit ))
78+
7879 mutual_access = {}
7980 stack = []
8081 low = {}
81-
82+
8283 def visit (node ):
8384 if node in low :
8485 return
@@ -87,11 +88,11 @@ def visit(node):
8788 low [node ] = num
8889 stack_pos = len (stack )
8990 stack .append (node )
90-
91+
9192 for successor in graph .neighbors (node ):
9293 visit (successor )
9394 low [node ] = min (low [node ], low [successor ])
94-
95+
9596 if num == low [node ]:
9697 component = stack [stack_pos :]
9798 del stack [stack_pos :]
@@ -101,16 +102,17 @@ def visit(node):
101102
102103 for item in component :
103104 low [item ] = len (graph )
104-
105+
105106 for node in graph :
106107 visit (node )
107-
108+
108109 setrecursionlimit (recursionlimit )
109110 return mutual_access
110111
111112
112113# Connected components
113114
115+
114116def connected_components (graph ):
115117 """
116118 Connected components.
@@ -122,28 +124,29 @@ def connected_components(graph):
122124 @return: Pairing that associates each node to its connected component.
123125 """
124126 recursionlimit = getrecursionlimit ()
125- setrecursionlimit (max (len (graph .nodes ())* 2 , recursionlimit ))
126-
127+ setrecursionlimit (max (len (graph .nodes ()) * 2 , recursionlimit ))
128+
127129 visited = {}
128130 count = 1
129131
130132 # For 'each' node not found to belong to a connected component, find its connected
131133 # component.
132134 for each in graph :
133- if ( each not in visited ) :
135+ if each not in visited :
134136 _dfs (graph , visited , count , each )
135137 count = count + 1
136-
138+
137139 setrecursionlimit (recursionlimit )
138140 return visited
139141
140142
141143# Limited DFS implementations used by algorithms here
142144
145+
143146def _dfs (graph , visited , count , node ):
144147 """
145148 Depth-first search subfunction adapted for accessibility algorithms.
146-
149+
147150 @type graph: graph, digraph, hypergraph
148151 @param graph: Graph.
149152
@@ -159,7 +162,7 @@ def _dfs(graph, visited, count, node):
159162 visited [node ] = count
160163 # Explore recursively the connected component
161164 for each in graph [node ]:
162- if ( each not in visited ) :
165+ if each not in visited :
163166 _dfs (graph , visited , count , each )
164167
165168
@@ -179,109 +182,110 @@ def _dfs(graph, visited, count, node):
179182# u are so that low[v] > pre[u], which means that there's no path from v to outside this subtree
180183# without passing through u.
181184
185+
182186def cut_edges (graph ):
183187 """
184188 Return the cut-edges of the given graph.
185-
189+
186190 A cut edge, or bridge, is an edge of a graph whose removal increases the number of connected
187191 components in the graph.
188-
192+
189193 @type graph: graph, hypergraph
190194 @param graph: Graph.
191-
195+
192196 @rtype: list
193197 @return: List of cut-edges.
194198 """
195199 recursionlimit = getrecursionlimit ()
196- setrecursionlimit (max (len (graph .nodes ())* 2 , recursionlimit ))
200+ setrecursionlimit (max (len (graph .nodes ()) * 2 , recursionlimit ))
197201
198202 # Dispatch if we have a hypergraph
199- if ' hypergraph' == graph .__class__ .__name__ :
203+ if " hypergraph" == graph .__class__ .__name__ :
200204 return _cut_hyperedges (graph )
201205
202- pre = {} # Pre-ordering
203- low = {} # Lowest pre[] reachable from this node going down the spanning tree + one backedge
206+ pre = {} # Pre-ordering
207+ low = {} # Lowest pre[] reachable from this node going down the spanning tree + one backedge
204208 spanning_tree = {}
205209 reply = []
206210 pre [None ] = 0
207211
208212 for each in graph :
209- if ( each not in pre ) :
213+ if each not in pre :
210214 spanning_tree [each ] = None
211215 _cut_dfs (graph , spanning_tree , pre , low , reply , each )
212-
216+
213217 setrecursionlimit (recursionlimit )
214218 return reply
215219
216220
217221def _cut_hyperedges (hypergraph ):
218222 """
219223 Return the cut-hyperedges of the given hypergraph.
220-
224+
221225 @type hypergraph: hypergraph
222226 @param hypergraph: Hypergraph
223-
227+
224228 @rtype: list
225229 @return: List of cut-nodes.
226230 """
227231 edges_ = cut_nodes (hypergraph .graph )
228232 edges = []
229-
233+
230234 for each in edges_ :
231- if ( each [1 ] == 'h' ) :
235+ if each [1 ] == "h" :
232236 edges .append (each [0 ])
233-
237+
234238 return edges
235239
236240
237241def cut_nodes (graph ):
238242 """
239243 Return the cut-nodes of the given graph.
240-
244+
241245 A cut node, or articulation point, is a node of a graph whose removal increases the number of
242246 connected components in the graph.
243-
247+
244248 @type graph: graph, hypergraph
245249 @param graph: Graph.
246-
250+
247251 @rtype: list
248252 @return: List of cut-nodes.
249253 """
250254 recursionlimit = getrecursionlimit ()
251- setrecursionlimit (max (len (graph .nodes ())* 2 , recursionlimit ))
252-
255+ setrecursionlimit (max (len (graph .nodes ()) * 2 , recursionlimit ))
256+
253257 # Dispatch if we have a hypergraph
254- if ' hypergraph' == graph .__class__ .__name__ :
258+ if " hypergraph" == graph .__class__ .__name__ :
255259 return _cut_hypernodes (graph )
256-
257- pre = {} # Pre-ordering
258- low = {} # Lowest pre[] reachable from this node going down the spanning tree + one backedge
260+
261+ pre = {} # Pre-ordering
262+ low = {} # Lowest pre[] reachable from this node going down the spanning tree + one backedge
259263 reply = {}
260264 spanning_tree = {}
261265 pre [None ] = 0
262-
266+
263267 # Create spanning trees, calculate pre[], low[]
264268 for each in graph :
265- if ( each not in pre ) :
269+ if each not in pre :
266270 spanning_tree [each ] = None
267271 _cut_dfs (graph , spanning_tree , pre , low , [], each )
268272
269273 # Find cuts
270274 for each in graph :
271275 # If node is not a root
272- if ( spanning_tree [each ] is not None ) :
276+ if spanning_tree [each ] is not None :
273277 for other in graph [each ]:
274278 # If there is no back-edge from descendent to a ancestral of each
275- if ( low [other ] >= pre [each ] and spanning_tree [other ] == each ) :
279+ if low [other ] >= pre [each ] and spanning_tree [other ] == each :
276280 reply [each ] = 1
277281 # If node is a root
278282 else :
279283 children = 0
280284 for other in graph :
281- if ( spanning_tree [other ] == each ) :
285+ if spanning_tree [other ] == each :
282286 children = children + 1
283287 # root is cut-vertex iff it has two or more children
284- if ( children >= 2 ) :
288+ if children >= 2 :
285289 reply [each ] = 1
286290
287291 setrecursionlimit (recursionlimit )
@@ -291,57 +295,57 @@ def cut_nodes(graph):
291295def _cut_hypernodes (hypergraph ):
292296 """
293297 Return the cut-nodes of the given hypergraph.
294-
298+
295299 @type hypergraph: hypergraph
296300 @param hypergraph: Hypergraph
297-
301+
298302 @rtype: list
299303 @return: List of cut-nodes.
300304 """
301305 nodes_ = cut_nodes (hypergraph .graph )
302306 nodes = []
303-
307+
304308 for each in nodes_ :
305- if ( each [1 ] == 'n' ) :
309+ if each [1 ] == "n" :
306310 nodes .append (each [0 ])
307-
311+
308312 return nodes
309313
310314
311315def _cut_dfs (graph , spanning_tree , pre , low , reply , node ):
312316 """
313317 Depth first search adapted for identification of cut-edges and cut-nodes.
314-
318+
315319 @type graph: graph, digraph
316320 @param graph: Graph
317-
321+
318322 @type spanning_tree: dictionary
319323 @param spanning_tree: Spanning tree being built for the graph by DFS.
320324
321325 @type pre: dictionary
322326 @param pre: Graph's preordering.
323-
327+
324328 @type low: dictionary
325329 @param low: Associates to each node, the preordering index of the node of lowest preordering
326330 accessible from the given node.
327331
328332 @type reply: list
329333 @param reply: List of cut-edges.
330-
334+
331335 @type node: node
332336 @param node: Node to be explored by DFS.
333337 """
334338 pre [node ] = pre [None ]
335339 low [node ] = pre [None ]
336340 pre [None ] = pre [None ] + 1
337-
341+
338342 for each in graph [node ]:
339- if ( each not in pre ) :
343+ if each not in pre :
340344 spanning_tree [each ] = node
341345 _cut_dfs (graph , spanning_tree , pre , low , reply , each )
342- if ( low [node ] > low [each ]) :
346+ if low [node ] > low [each ]:
343347 low [node ] = low [each ]
344- if ( low [each ] == pre [each ]) :
348+ if low [each ] == pre [each ]:
345349 reply .append ((node , each ))
346- elif ( low [node ] > pre [each ] and spanning_tree [node ] != each ) :
350+ elif low [node ] > pre [each ] and spanning_tree [node ] != each :
347351 low [node ] = pre [each ]
0 commit comments