You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

topological_sort.py 1.2KB

123456789101112131415161718192021222324252627282930313233343536
  1. class CyclicDependencyError(ValueError):
  2. pass
  3. def topological_sort_as_sets(dependency_graph):
  4. """
  5. Variation of Kahn's algorithm (1962) that returns sets.
  6. Take a dependency graph as a dictionary of node => dependencies.
  7. Yield sets of items in topological order, where the first set contains
  8. all nodes without dependencies, and each following set contains all
  9. nodes that may depend on the nodes only in the previously yielded sets.
  10. """
  11. todo = dependency_graph.copy()
  12. while todo:
  13. current = {node for node, deps in todo.items() if not deps}
  14. if not current:
  15. raise CyclicDependencyError('Cyclic dependency in graph: {}'.format(
  16. ', '.join(repr(x) for x in todo.items())))
  17. yield current
  18. # remove current from todo's nodes & dependencies
  19. todo = {node: (dependencies - current) for node, dependencies in
  20. todo.items() if node not in current}
  21. def stable_topological_sort(l, dependency_graph):
  22. result = []
  23. for layer in topological_sort_as_sets(dependency_graph):
  24. for node in l:
  25. if node in layer:
  26. result.append(node)
  27. return result