-
Notifications
You must be signed in to change notification settings - Fork 5
/
topological_sorting.py
82 lines (69 loc) · 2.45 KB
/
topological_sorting.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
"""
Topological sorting
https://en.wikipedia.org/wiki/Topological_sorting
"""
from __future__ import print_function
class Graph(object):
""" Simple implementation of directed acyclic graph
nodes : set
set of all nodes in the graph
dependencies : list
list of tuples (node1, node2) which show connection
between nodes of the graph
"""
def __init__(self, nodes, dependencies):
self.nodes = nodes
self.dependencies = dependencies
def __str__(self):
""" string representation of the graph """
string = ''
for node in sorted(self.nodes):
strnode = ["{} -> {}".format(start, end)
for start, end in self.dependencies if start == node]
string += "node {}: {}\n".format(node, " ".join(strnode))
return string[:-1]
def topological_sort(self):
""" Topological sort implementation
Returns
-------
out : list
list of tolopological sorted nodes
"""
# determine order and stack lists
order, stack = [], set(self.nodes)
# colors : default - WHITE, 1 - GRAY, 2 - BLACK
colors = {}
def dfs(node):
""" Depth-first search """
# set gray color for current node
colors[node] = 1
for start, sub in self.dependencies:
if start != node:
# skip node
continue
# get color
color = colors.get(sub, 0)
if color == 1:
# gray color
raise ValueError('Cycle')
elif color == 2:
# black color
continue
# remove sub node from stack
stack.discard(sub)
# recursive call
dfs(sub)
# insert to top of list
order.insert(0, node)
# set black color for current node
colors[node] = 2
while stack:
dfs(stack.pop())
return order
if __name__ in '__main__':
GRAPH_NODES = {0, 1, 2, 3, 4, 5, 6, 7}
GRAPH_DEPENDECIES = [(0, 1), (0, 4), (1, 3), (3, 5), (1, 5), (5, 6),
(5, 7), (6, 7), (4, 6), (3, 7)]
GRAPH = Graph(GRAPH_NODES, GRAPH_DEPENDECIES)
print("Show Graph:\n{}\n".format(GRAPH))
print("Show nodes in topological order: {}".format(GRAPH.topological_sort()))