| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- def strongly_connected_components(graph):
- """
- Tarjan's Algorithm (named for its discoverer, Robert Tarjan) is a
- graph theory algorithm for finding the strongly connected
- components of a graph.
-
- Based on: http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
- @author: Dries Verdegem, some minor edits by Martin Thoma
- @source: http://www.logarithmic.net/pfh/blog/01208083168
- """
- index_counter = 0
- stack = []
- lowlinks = {}
- index = {}
- result = []
-
- def strongconnect(node, index_counter):
- print("Start with node: %s###########################" % node)
- # set the depth index for this node to the smallest unused index
- print("lowlinks:\t%s" % lowlinks)
- print("index:\t%s" % index)
- print("stack:\t%s" % stack)
- index[node] = index_counter
- lowlinks[node] = index_counter
- index_counter += 1
- stack.append(node)
-
- # Consider successors of `node`
- try:
- successors = graph[node]
- except:
- successors = []
- # Depth first search
- for successor in successors:
- # Does the current node point to a node that was already
- # visited?
- if successor not in lowlinks:
- print("successor not in lowlinks: %s -> %s (node, successor)" % (node, successor))
- # Successor has not yet been visited; recurse on it
- strongconnect(successor, index_counter)
- lowlinks[node] = min(lowlinks[node],lowlinks[successor])
- elif successor in stack:
- #else:
- print("successor in stack: %s -> %s" % (node, successor));
- # the successor is in the stack and hence in the
- # current strongly connected component (SCC)
- lowlinks[node] = min(lowlinks[node],index[successor])
- else:
- print("This happens sometimes. node: %s, successor: %s" % (node, successor))
- print("Lowlinks: %s" %lowlinks)
- print("stack: %s" % stack)
-
- # If `node` is a root node, pop the stack and generate an SCC
- if lowlinks[node] == index[node]:
- print("Got root node: %s (index/lowlink: %i)" % (node, lowlinks[node]))
- connected_component = []
-
- while True:
- successor = stack.pop()
- print("pop: %s" % successor)
- connected_component.append(successor)
- if successor == node: break
- component = tuple(connected_component)
- # storing the result
- result.append(component)
- else:
- print("Node: %s, lowlink: %i, index: %i" % (node, lowlinks[node], index[node]))
-
- for node in graph:
- if node not in lowlinks:
- strongconnect(node, index_counter)
-
- return result
- graph = {'a': ['b'],
- 'b': ['c'],
- 'c': ['d', 'e'],
- 'd': ['a', 'e', 'h'],
- 'e': ['c', 'f'],
- 'f': ['g', 'i'],
- 'g': ['h', 'f'],
- 'h': ['j'],
- 'i': ['g', 'f'],
- 'j': ['i'],
- 'k': [],
- 'h': []}
- print strongly_connected_components(graph)
|