Skip to content

Instantly share code, notes, and snippets.

@danong
Last active March 27, 2020 01:01
Show Gist options
  • Save danong/9dd8696f7400d1606733c0721207866f to your computer and use it in GitHub Desktop.
Save danong/9dd8696f7400d1606733c0721207866f to your computer and use it in GitHub Desktop.
Directed graph: detect cycles and topological sort
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