已發布·持續改進
圖形走訪 指南 · 6/6
本章目前僅提供英文版。
Graph traversal is not just an interview topic. Build tools, package managers, garbage collectors, web crawlers and the paint-bucket tool in an image editor all run on the BFS, DFS and topological sorting covered in this guide. This chapter looks at real systems, standard libraries and common mistakes.
Since Python 3.9 the standard library ships a topological sorter in graphlib. Each dictionary value lists a node's predecessors, the things that must come first.
from graphlib import TopologicalSorter, CycleError
deps = {"app": {"ui", "net"}, "ui": {"core"}, "net": {"core"}}
print(list(TopologicalSorter(deps).static_order()))
# e.g. ['core', 'ui', 'net', 'app'] (order within a level is not guaranteed)
try:
list(TopologicalSorter({"a": {"b"}, "b": {"a"}}).static_order())
except CycleError as error:
print("cycle:", error.args[1])TopologicalSorter also supports parallel execution through prepare(), get_ready() and done(), handing ready tasks to workers as their prerequisites finish. For heavier graph work, NetworkX provides BFS, DFS, components and topological sorting out of the box.
import networkx as nx
grid = nx.grid_2d_graph(3, 3) # a 3 x 3 grid graph
print(nx.shortest_path_length(grid, (0, 0), (2, 2))) # 4, BFS when unweighted
print(nx.number_connected_components(nx.Graph([(0, 1), (2, 3)]))) # 2
print(list(nx.topological_sort(nx.DiGraph([("core", "ui"), ("ui", "app")]))))The mark phase of a garbage collector is an iterative DFS in disguise.
def mark(roots, refs):
live, stack = set(), list(roots)
while stack:
obj = stack.pop()
if obj in live:
continue
live.add(obj)
stack.extend(refs.get(obj, []))
return live
refs = {"main": ["a"], "a": ["b"], "b": ["a"], "c": ["d"]}
print(mark(["main"], refs)) # {'main', 'a', 'b'}: c and d get collectedThe cycle between a and b does not cause an infinite loop because of the visited set, and c and d are collected because nothing reachable points to them, regardless of their reference counts.
list.pop(0) in Python and shift() in JavaScript are O(n).-1 before using it in arithmetic.Wherever there are dependencies there is a topological sort, and wherever there is a reachability question there is a BFS or DFS. In production, reach for proven implementations like graphlib or NetworkX first; when you write your own, double-check when you mark vertices, which queue you use, how deep you recurse, and how you define a cycle.
0 則留言
登入 · 登入後即可留言。
來留下第一則留言吧。