Topolojik Sıralama
Yönlü döngüsüz bir grafın düğümlerini her ok ileri bakacak şekilde sıralayan, bağımlılık çözmenin temel yöntemi.
Önce bunlara göz at
#Nasıl çalışır?
Topolojik sıralama, yönlü ve döngüsüz bir grafın (DAG) düğümlerini, her ok (u → v) için u'nun v'den önce geleceği şekilde sıralar. "Önce şunu yap, sonra bunu" türündeki bağımlılıkları çözmenin yoludur.
Kahn algoritması (1962) gelen kenar sayısı (in-degree) 0 olan, yani önkoşulu kalmamış düğümlerle başlar. Bir düğüm sıraya eklendiğinde ondan çıkan oklar "tamamlanmış" sayılır ve hedeflerin in-degree değeri bir azalır; 0'a düşen düğüm kuyruğa girer.
Grafta döngü varsa döngüdeki düğümlerin in-degree değeri hiçbir zaman 0'a düşmez. Bu yüzden kuyruk erken boşalır ve sıralanan düğüm sayısı V'den az kalır: Kahn algoritması aynı zamanda bir döngü dedektörüdür.
Bir DAG'ın birden fazla geçerli topolojik sırası olabilir. Alternatif yöntem DFS'tir: bir düğümün tüm alt dalları bitince onu listenin başına eklemek de topolojik sıra verir.
#Kendin dene
Komşuluk listesi
- 1 → 2, 3
- 2 → 4, 5
- 3 → 2, 5, 6
- 4 → 7
- 5 → 7
- 6 → 7
- 7 → —
Oklar "önce bu, sonra şu" demek (ör. ders önkoşulları). Topolojik sıralama her okun ileri baktığı bir sıra bulur. 7 → 1 kenarını ekleyip döngüyü yakalamayı dene.
#Adım adım
- 01Her düğümün in-degree değerini hesapla.
- 02In-degree değeri 0 olan tüm düğümleri kuyruğa koy.
- 03Kuyruktan bir düğüm (u) al ve sıraya ekle; u'dan çıkan her ok için hedefin in-degree değerini 1 azalt, 0 olanı kuyruğa ekle.
- 04Kuyruk boşalınca sıralanan düğüm sayısı V'den azsa grafta döngü vardır.
#Örnek kod
Aynı algoritma 8 dilde. Her program derlenip çalıştırılarak test edildi ve hepsi aynı çıktıyı veriyor.
from collections import deque
# u -> v means "u before v", e.g. course prerequisites.
EDGES = [(1, 2), (1, 3), (3, 2), (2, 4), (2, 5), (3, 5), (3, 6), (4, 7), (5, 7), (6, 7)]
def topo_sort(n: int, edges) -> list:
"""Kahn's algorithm. Returns the order, or an empty list if there is a cycle."""
out = {v: [] for v in range(1, n + 1)}
indegree = {v: 0 for v in range(1, n + 1)}
for u, v in edges:
out[u].append(v)
indegree[v] += 1
queue = deque(v for v in range(1, n + 1) if indegree[v] == 0)
order = []
while queue:
u = queue.popleft()
order.append(u)
for v in sorted(out[u]):
indegree[v] -= 1
if indegree[v] == 0:
queue.append(v)
return order if len(order) == n else []
print(" ".join(map(str, topo_sort(7, EDGES))))
print("cycle" if not topo_sort(7, EDGES + [(7, 1)]) else "no cycle") # 7 -> 1 closes a loop#Karmaşıklık
| İşlem | Süre |
|---|---|
| In-degree hesaplamak | O(V + E) |
| Kahn algoritması | O(V + E) |
| DFS ile topolojik sıra | O(V + E) |
| Bellek | O(V) |
Her düğüm kuyruğa bir kez girer ve her ok bir kez işlenir; toplam doğrusal zamandır. Sıralama yalnızca DAG'larda mümkündür; yönsüz graflar ve döngülü yönlü graflar için tanımlı değildir.
#Ne zaman kullanılır?
Derleme sistemleri (make, npm/yarn bağımlılıkları), görev zamanlama, ders önkoşul planlaması, elektronik tablolarda hücrelerin hesaplanma sırası, veritabanı migration sıraları ve paket yöneticileri topolojik sıralama kullanır.
#Alıştırma
Soruları cevaplamak ve ilerlemeni kaydetmek için giriş yap.
Kolay
Topolojik sıralama hangi graflarda mümkündür?
- 1Yönlü ve döngüsüz graflarda (DAG)
- 2Tüm yönsüz graflarda
- 3Döngülü yönlü graflarda
- 4Yalnızca ağaçlarda
Kahn algoritması hangi düğümlerle başlar?
- 1Gelen kenar sayısı (in-degree) 0 olanlarla
- 2Giden kenarı olmayanlarla
- 3En çok komşusu olanla
- 4Rastgele bir düğümle
Kahn algoritması bir döngüyü nasıl fark eder?
- 1Kuyruk boşaldığında sıralanan düğüm sayısı V'den az kalır
- 2Aynı düğüm kuyruğa iki kez girer
- 3Bir düğümün in-degree değeri negatif olur
- 4Algoritma sonsuz döngüye girer
Orta
Oklar: A → B, A → C, C → B. Hangisi geçerli bir topolojik sıradır?
- 1A, C, B
- 2A, B, C
- 3B, C, A
- 4C, A, B
Zor
DFS ile topolojik sıra nasıl elde edilir?
- 1Bir düğümün tüm alt dalları bitince onu listenin başına eklersin
- 2Düğümleri ziyaret sırasıyla yazarsın
- 3BFS sırasını ters çevirirsin
- 4Düğümleri derinliğe göre sıralarsın