Menurut Lemma 22.11 dari Cormen et al., Pengantar Algoritma (CLRS):
Grafik berarah G adalah asiklik jika dan hanya jika pencarian G-kedalaman tidak menghasilkan tepi belakang.
Ini telah disebutkan dalam beberapa jawaban; di sini saya juga akan memberikan contoh kode berdasarkan bab 22 CLRS. Contoh grafik diilustrasikan di bawah ini.
Kode pseudo CLRS untuk pencarian kedalaman-pertama berbunyi:
Pada contoh di CLRS Gambar 22.4, grafik terdiri dari dua pohon DFS: satu terdiri dari simpul u , v , x , dan y , dan yang lainnya dari simpul w dan z . Setiap pohon berisi satu tepi belakang: satu dari x ke v dan satu lagi dari z ke z (loop otomatis).
Realisasi utama adalah bahwa tepi kembali ditemui ketika, dalam DFS-VISIT
fungsi, sedangkan iterasi tetangga v
dari u
, sebuah node ditemui dengan GRAY
warna.
Kode Python berikut adalah adaptasi dari pseudocode CLRS dengan if
klausa yang ditambahkan yang mendeteksi siklus:
import collections
class Graph(object):
def __init__(self, edges):
self.edges = edges
self.adj = Graph._build_adjacency_list(edges)
@staticmethod
def _build_adjacency_list(edges):
adj = collections.defaultdict(list)
for edge in edges:
adj[edge[0]].append(edge[1])
return adj
def dfs(G):
discovered = set()
finished = set()
for u in G.adj:
if u not in discovered and u not in finished:
discovered, finished = dfs_visit(G, u, discovered, finished)
def dfs_visit(G, u, discovered, finished):
discovered.add(u)
for v in G.adj[u]:
# Detect cycles
if v in discovered:
print(f"Cycle detected: found a back edge from {u} to {v}.")
# Recurse into DFS tree
if v not in finished:
dfs_visit(G, v, discovered, finished)
discovered.remove(u)
finished.add(u)
return discovered, finished
if __name__ == "__main__":
G = Graph([
('u', 'v'),
('u', 'x'),
('v', 'y'),
('w', 'y'),
('w', 'z'),
('x', 'v'),
('y', 'x'),
('z', 'z')])
dfs(G)
Perhatikan bahwa dalam contoh ini, the time
pseudocode dalam CLRS tidak ditangkap karena kami hanya tertarik untuk mendeteksi siklus. Ada juga beberapa kode boilerplate untuk membangun representasi daftar adjacency dari grafik dari daftar tepi.
Ketika skrip ini dieksekusi, ia mencetak output berikut:
Cycle detected: found a back edge from x to v.
Cycle detected: found a back edge from z to z.
Ini persis tepi belakang dalam contoh dalam CLRS Gambar 22.4.