Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

📚 The CoCalc Library - books, templates and other resources

132939 views
License: OTHER
1
def strongly_connected_components(graph):
2
"""
3
Tarjan's Algorithm (named for its discoverer, Robert Tarjan) is a
4
graph theory algorithm for finding the strongly connected
5
components of a graph.
6
7
Based on: http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
8
@author: Dries Verdegem, some minor edits by Martin Thoma
9
@source: http://www.logarithmic.net/pfh/blog/01208083168
10
"""
11
12
index_counter = 0
13
stack = []
14
lowlinks = {}
15
index = {}
16
result = []
17
18
def strongconnect(node, index_counter):
19
print("Start with node: %s###########################" % node)
20
# set the depth index for this node to the smallest unused index
21
print("lowlinks:\t%s" % lowlinks)
22
print("index:\t%s" % index)
23
print("stack:\t%s" % stack)
24
25
index[node] = index_counter
26
lowlinks[node] = index_counter
27
index_counter += 1
28
stack.append(node)
29
30
# Consider successors of `node`
31
try:
32
successors = graph[node]
33
except:
34
successors = []
35
36
# Depth first search
37
for successor in successors:
38
# Does the current node point to a node that was already
39
# visited?
40
if successor not in lowlinks:
41
print("successor not in lowlinks: %s -> %s (node, successor)" %
42
(node, successor))
43
# Successor has not yet been visited; recurse on it
44
strongconnect(successor, index_counter)
45
lowlinks[node] = min(lowlinks[node], lowlinks[successor])
46
elif successor in stack:
47
# else:
48
print("successor in stack: %s -> %s" % (node, successor))
49
# the successor is in the stack and hence in the
50
# current strongly connected component (SCC)
51
lowlinks[node] = min(lowlinks[node], index[successor])
52
else:
53
print("This happens sometimes. node: %s, successor: %s" %
54
(node, successor))
55
print("Lowlinks: %s" % lowlinks)
56
print("stack: %s" % stack)
57
58
# If `node` is a root node, pop the stack and generate an SCC
59
if lowlinks[node] == index[node]:
60
print("Got root node: %s (index/lowlink: %i)" %
61
(node, lowlinks[node]))
62
connected_component = []
63
64
while True:
65
successor = stack.pop()
66
print("pop: %s" % successor)
67
connected_component.append(successor)
68
if successor == node:
69
break
70
71
component = tuple(connected_component)
72
73
# storing the result
74
result.append(component)
75
else:
76
print("Node: %s, lowlink: %i, index: %i" %
77
(node, lowlinks[node], index[node]))
78
79
for node in graph:
80
if node not in lowlinks:
81
strongconnect(node, index_counter)
82
83
return result
84
85
graph = {'a': ['b'],
86
'b': ['c'],
87
'c': ['d', 'e'],
88
'd': ['a', 'e', 'h'],
89
'e': ['c', 'f'],
90
'f': ['g', 'i'],
91
'g': ['h', 'f'],
92
'h': ['j'],
93
'i': ['g', 'f'],
94
'j': ['i'],
95
'k': [],
96
'h': []}
97
98
print strongly_connected_components(graph)
99
100