Last active
March 27, 2020 01:01
-
-
Save danong/9dd8696f7400d1606733c0721207866f to your computer and use it in GitHub Desktop.
Directed graph: detect cycles and topological sort
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def detect_cycles(graph: dict) -> bool: | |
"""Return whether or not graph has any cycles.""" | |
visited = set() | |
path = set() | |
def visit(node): | |
"""Return True if node is in a cycle""" | |
if node in visited: | |
return False | |
visited.add(node) | |
path.add(node) | |
for edge in graph[node]: | |
if edge in path or visit(edge): | |
return True | |
path.remove(node) | |
return False | |
return any(visit(node) for node in graph) | |
def topological_sort(graph: dict) -> list: | |
"""Return a topological sorting of graph""" | |
temp_path = set() | |
final_path = [] | |
def visit(node): | |
if node in final_path: | |
return | |
if node in temp_path: | |
raise TypeError('input graph is cyclic and cannot be sorted topologically') | |
temp_path.add(node) | |
for neighbor in graph[node]: | |
visit(neighbor) | |
final_path.append(node) | |
for node in graph: | |
visit(node) | |
return final_path[::-1] | |
if __name__ == '__main__': | |
my_graph = { | |
1: {2}, | |
2: {3, 6}, | |
3: set(), | |
4: {5}, | |
5: set(), | |
6: set(), | |
7: {2, 6} | |
} | |
print(detect_cycles(my_graph)) | |
print(topological_sort(my_graph)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment