123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- 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)
|