Skip to content

Commit

Permalink
Added missing file tarjan_sort.py
Browse files Browse the repository at this point in the history
  • Loading branch information
joxeankoret committed Aug 24, 2018
1 parent 41f3c14 commit d657946
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
Empty file added others/__init__.py
Empty file.
113 changes: 113 additions & 0 deletions others/tarjan_sort.py
@@ -0,0 +1,113 @@

# Downloaded from http://www.logarithmic.net/pfh-files/blog/01208083168/sort.py

"""
Tarjan's algorithm and topological sorting implementation in Python
by Paul Harrison
Public domain, do with it as you will
"""

def strongly_connected_components(graph):
""" Find the strongly connected components in a graph using
Tarjan's algorithm.
graph should be a dictionary mapping node names to
lists of successor nodes.
"""

result = [ ]
stack = [ ]
low = { }

def visit(node):
if node in low: return

num = len(low)
low[node] = num
stack_pos = len(stack)
stack.append(node)

for successor in graph[node]:
visit(successor)
low[node] = min(low[node], low[successor])

if num == low[node]:
component = tuple(stack[stack_pos:])
del stack[stack_pos:]
result.append(component)
for item in component:
low[item] = len(graph)

for node in graph:
visit(node)

return result


def topological_sort(graph):
count = { }
for node in graph:
count[node] = 0
for node in graph:
for successor in graph[node]:
count[successor] += 1

ready = [ node for node in graph if count[node] == 0 ]

result = [ ]
while ready:
node = ready.pop(-1)
result.append(node)

for successor in graph[node]:
count[successor] -= 1
if count[successor] == 0:
ready.append(successor)

return result


def robust_topological_sort(graph):
""" First identify strongly connected components,
then perform a topological sort on these components. """

components = strongly_connected_components(graph)

node_component = { }
for component in components:
for node in component:
node_component[node] = component

component_graph = { }
for component in components:
component_graph[component] = [ ]

for node in graph:
node_c = node_component[node]
for successor in graph[node]:
successor_c = node_component[successor]
if node_c != successor_c:
component_graph[node_c].append(successor_c)

return topological_sort(component_graph)


if __name__ == '__main__':
d = {
0 : [1],
1 : [2],
2 : [1,3],
3 : [3],
}
#print d
#print robust_topological_sort(d)

d = {0 : [1, 2, 4], 1 : [3, 4], 2 : [0, 3], 3 : [], 4: [1]}
print d
print "scc", strongly_connected_components(d)
print "rts", robust_topological_sort(d)

0 comments on commit d657946

Please sign in to comment.