14  Çizgeler ve Enine Arama (BFS)

Çizge G=(V,E), yönlü (sıralı) / yönsüz (sırasız); basit çizgede |E|=O(V²); derece toplamı 2|E| → komşu döngüsü O(E); komşuluk listesi (+hash) O(1) kenar sorgusu; en kısa yol ağacı = öncül P(v), O(V) yer (optimal alt yapı); BFS seviye kümeleri Lₖ katman katman → δ/P/L tek geçişte, O(V+E) doğrusal

NotBölüm bilgisi

Bu ders, kursun çizge (graph) ünitesinin açılışıdır — veri yapılarından çizge algoritmalarına geçiş.

14.1 Bu Derste Ne Var?

Ders 12 (L8) ikili yığınla öncelik kuyruğunu çözdü. Bugün Justin Solomon ile kursun ikinci bölümünü açıyoruz: çizge algoritmaları. Önce çizge terminolojisini kurarız (düğüm, kenar, yönlü/yönsüz), sonra bir kaynaktan tüm düğümlere en kısa yolu hesaplayan ilk algoritmayı veririz: enine arama (BFS, breadth-first search).

“we’re officially starting part two of this class… our new unit which is graph theory.” — Solomon, 0:57

Üç temel kavram bu derste yan yana gelir:

  1. Çizge ve gösterimi\(G = (V, E)\); komşuluk listesi (adjacency list) ile \(O(1)\) kenar sorgusu.
  2. En kısa yol ağacı — her düğümde sadece “öncül” \(P(v)\) tutarak yolu \(O(V)\) yerde sakla.
  3. BFS — seviye kümelerini (level sets) katman katman üreterek ağırlıksız en kısa yolu \(O(V + E)\)’de bul.
flowchart TD
    A["Ders 13 (L9): Çizgeler ve Enine Arama"] --> G["Çizge G=(V,E)<br/>düğümler + kenarlar"]
    G --> G1["yönlü (sıralı çift)<br/>yönsüz (sırasız küme)"]
    G --> G2["basit çizge<br/>derece toplamı = iki kat kenar"]
    A --> R["Gösterim<br/>komşuluk listesi (hash)"]
    R --> R1["kenar sorgusu beklenen sabit<br/>kenar listesi yavaş, matris savurgan"]
    A --> P["En kısa yol ağacı<br/>öncül P(v)"]
    P --> P1["yolu geriye izle<br/>az yer, optimal alt yapı"]
    A --> B["BFS<br/>seviye kümeleri katman katman"]
    B --> B1["dalga dalga yayılma<br/>doğrusal zaman, ağırlıksız en kısa yol"]

    classDef root fill:#fef3c7,stroke:#b45309,stroke-width:3px,color:#1f2937
    classDef branch fill:#f3f4f6,stroke:#374151,stroke-width:2px,color:#1f2937
    classDef leaf fill:#ffffff,stroke:#9ca3af,stroke-width:1px,color:#1f2937
    class A root
    class G,R,P,B branch
    class G1,G2,R1,P1,B1 leaf
Şekil 14.1: Ders 13’ün (L9) kavram haritası: kök = çizgeler ve enine arama. Dört dal — (1) çizge G=(V,E), düğüm + kenar; kenar yönlü (sıralı çift) ya da yönsüz (sırasız küme); basit çizgede |E| = O(V²). (2) gösterim: komşuluk listesi düğümü komşularına eşler, hash ile beklenen O(1) kenar sorgusu; kenar listesi O(E), komşuluk matrisi O(V²) yer. (3) en kısa yol ağacı: her düğümde yalnız öncül P(v) tutulur, yol geriye izlenerek kurulur, O(V) yer (optimal alt yapı). (4) BFS: seviye kümeleri Lₖ katman katman üretilir, δ ve öncül tek geçişte dolar, doğrusal zaman O(V+E). Sonuç: bağlı her şeyin evrensel soyutlaması + ağırlıksız en kısa yol.
İpucuBuilder Notu — Bağlı Her Şey Bir Çizgedir

Çizge, “birbirine bağlı her şeyin” evrensel soyutlamasıdır — ağ topolojisi, sosyal graf, bağımlılık grafı, durum-geçiş uzayı. Önce nasıl saklayacağını (gösterim), sonra nasıl gezeceğini (BFS) sorarız.

  • Geriye → Ders 2-5 (veri yapıları): çizge de bir veri yapısı tasarım problemi; “hangi sorguyu hızlandıracağım?” sorusu gösterim seçimini (kenar listesi / komşuluk listesi / matris) belirler.
  • Geriye → Ders 8 (PS3, reduction): üç çizge problemi (erişilebilirlik ⊂ tek-çift en kısa yol ⊂ tek-kaynak en kısa yol) birbirine indirgenir — birini çözen diğerini çözer.
  • İleriye → Ders 16-19 (L11-L13, Dijkstra): BFS, ağırlıksız en kısa yoldur; ağırlıklara geçince öncelik kuyruğu (yığın) devreye girer (PS5 = Ders 17 arada).
  • İleriye → her yer: ağ yönlendirme (router, Google Maps), sosyal ağ, durum-geçiş (Rubik küpü), 3B model (üçgen ağ), seçim bölgesi — hepsi çizge.

Tek cümle: Çizgeyi komşuluk listesiyle saklayıp BFS ile katman katman gezersek, bir kaynaktan tüm düğümlere ağırlıksız en kısa yolu \(O(V + E)\)’de buluruz — ve sadece “öncül”leri tutarak yolları \(O(V)\) yerde saklarız.

14.2 1. Çizge Nedir?

Bir çizge (graph) \(G = (V, E)\) iki şeyden oluşur: bir düğüm (vertex) kümesi \(V\) ve bir kenar (edge) kümesi \(E \subseteq V \times V\). Her kenar iki düğümü birbirine bağlar.

“a graph… is a collection of two things: a set of vertices and a set of edges.” — Solomon, 2:01

İki tür:

  • Yönlü (directed): kenar bir sıralı çift \((w, v)\); \((w, v)\) ile \((v, w)\) farklıdır (su akışına karşı yüzemezsin).
  • Yönsüz (undirected): kenar bir sırasız küme \(\{v, w\}\); yön yoktur, yalnızca bağlantı.

“in a directed graph… the edge from w to v is different than the edge from v to w.” — Solomon, 3:53

Şekil 14.2 bu iki türü yan yana koyar: solda yönsüz kenar (sırasız küme \(\{v, w\}\), oksuz), ortada yönlü kenar (sıralı çift \((w, v)\), oklu — \((v, w) \neq (w, v)\)), sağda bu dersin örnek çizgesi (7 düğüm) derece rozetleriyle ve \(\sum \deg(v) = 16 = 2|E|\) kimliğiyle.

Şekil 14.2: Çizge anatomisi: yönsüz {v,w} vs yönlü (w,v) + derece toplamı kimliği (L9 §1/§4). SOL panel — YÖNSÜZ mini çizge: kenar = SIRASIZ küme {v, w}; düz (oksuz) çizgi, {v,w} = {w,v} aynı kenardır. ORTA panel — YÖNLÜ mini çizge (aynı düğümler): kenar = SIRALI çift (w, v); oklu kenar, (v,w) ≠ (w,v) → çift-yön İKİ ayrı ok ile (amber vurgu). SAĞ panel — bu dersin örnek çizgesi (7 düğüm sabit yerleşim): her düğüm yanında derece rozeti a:2 b:2 c:3 d:3 e:2 f:3 g:1; c-d kenarı amber işaretli, iki ucuna +1 (kenar İKİ uçtan sayılır); alt kutu Σ deg(v) = 16 = 2|E| = 2·8. Bu kimlik ‘her düğümün her komşusunu gez’ döngüsünü TOPLAM O(E) yapar. Motor kanıtı: degree_sums(build_example_graph()) → 16; dereceler {a:2,b:2,c:3,d:3,e:2,f:3,g:1}; make_directed’da (v,w) ile (w,v) iki AYRI kenar (Solomon 2:01 / 3:53 / 17:37).

14.3 2. Çizgeler Her Yerde

Birbirine bağlı her şey bir çizgedir: bilgisayar ağları (düğüm = makine, kenar = kablo), sosyal ağlar (düğüm = kişi, kenar = arkadaşlık), yol ağları (Google Maps en kısa yol çözer), Rubik küpü (düğüm = konfigürasyon, kenar = bir twist), 3B modeller (üçgen ağ), seçim bölgesi haritaları (komşuluk).

“graphs are literally everywhere in our everyday life.” — Solomon, 5:26

14.4 3. Basit Çizge ve |E| = O(V²)

Bu derste basit çizge varsayarız: özdöngü (self-loop) yok, her kenar farklı (çoklu kenar yok). Sonuç: kenar sayısı \(|E| = O(V^2)\) (yönlü için \(|E| \le 2 \binom{V}{2}\); yönsüz için \(|E| \le \binom{V}{2}\); ikisi de en fazla \(V^2\)).

“the edges are big O of v squared.” — Solomon, 11:44

Bu yüzden çizge algoritmalarında iki boyut vardır: \(V\) ve \(E\). Bir çizge seyrek (sparse) ise (\(E \ll V^2\)), \(E\)’ye bağlı bir algoritma, \(V^2\)’ye bağlı olandan çok daha hızlı olabilir.

14.5 4. Komşular ve Derece

  • Çıkış komşuları \(\text{Adj}^{+}(u)\): \(u\)’dan çıkan kenarların hedefleri. Giriş komşuları \(\text{Adj}^{-}(u)\): \(u\)’ya giren kenarlar. (Yönsüzde ayrım yok, sadece \(\text{Adj}(u)\).)
  • Derece (degree): komşu kümesinin boyutu — çıkış derecesi (out-degree), giriş derecesi (in-degree).

“the out degree is the number of edges that point out of a vertex.” — Solomon, 17:37

Kritik kimlik (çizge algoritmalarında sürekli kullanılır): tüm düğümlerin derecelerinin toplamı \(= 2|E|\) (yönsüz, her kenar iki düğüme sayılır) veya \(|E|\) (yönlü, çıkış derecesi). Bu, “her düğüm için her komşusunu gez” döngüsünün \(O(E)\) olduğunu söyler. Bu kimliği Şekil 14.2’nin sağ panelinde somut olarak görmüştük: örnek çizgede \(\sum \deg(v) = 16 = 2 \cdot 8\).

14.6 5. Çizge Veri Yapıları

  • Kenar listesi (edge list): tüm kenarların düz listesi. “\(v \to w\) kenarı var mı?” sorgusu \(O(E)\) — kötü.
  • Komşuluk listesi (adjacency list): her düğüm \(u\)’yu, komşularına eşleyen bir küme. Komşu kümesini hash tablosu tutarsa, kenar sorgusu beklenen \(O(1)\) (önce \(u\)’yu bul \(O(1)\), sonra \(w\)’yi sorgula \(O(1)\)). \(V^2 \to 1\).

“an adjacency list… a set that maps a vertex u to everything adjacent to u.” — Solomon, 23:08

  • Komşuluk matrisi (adjacency matrix): \(V \times V\) ikili dizi; kenar sorgusu \(O(1)\) ama komşuları gezmek \(O(V)\) ve \(O(V^2)\) yer — büyük çizgeler için savurgan.

Genel kural: komşuluk listesi (+ hash) en dengeli seçim; gösterim, hangi sorguyu sık yapacağına bağlıdır.

Şekil 14.3 aynı çizgeyi üç gösterimle yan yana koyar — kenar listesi (her sorguda yavaş), komşuluk listesi + hash (önerilen, amber çerçeve), komşuluk matrisi (sorgu hızlı ama yer ve komşu-gezme pahalı). Gösterim seçimi, hangi sorguyu hızlandıracağına bağlıdır.

Şekil 14.3: Aynı çizge, üç gösterim: kenar listesi · komşuluk listesi · komşuluk matrisi (L9 §5, İMZA figür). Üstte referans çizge (7 düğüm, 8 yönsüz kenar). Altta 3 panel: (1) KENAR LİSTESİ — 8 kenarın düz listesi; ‘a–g var mı?’ sorgusu TÜM listeyi tarar → kenar sorgusu O(E), komşu gezme O(E), yer O(E) (slate ✗). (2) KOMŞULUK LİSTESİ + hash (ÖNERİLEN, amber çerçeve) — her düğüm → komşu kümesi; kenar sorgusu beklenen O(1), komşu gezme O(derece), yer O(V+E) (amber). (3) KOMŞULUK MATRİSİ — 7×7 ikili ızgara; kenar sorgusu O(1) AMA komşu gezme O(V) ve yer O(V²) (✗). Komşuluklar MOTORDAN: adj[a]={b,c}, adj[c]={a,d,e}, adj[f]={d,e,g}, adj[g]={f}; yönsüz kayıt 2|E| = 16. Gösterim seçimi = hangi sorguyu hızlandıracağın (Solomon 23:08).

14.7 6. Yollar ve En Kısa Yol

Bir yol (path), ardışık çiftleri kenar olan bir düğüm dizisidir. Uzunluğu \(=\) kenar sayısı (\(=\) düğüm sayısı \(-1\); sık yapılan hata: \(+1\)). En kısa yol, iki düğüm arasında en az kenarlı yoldur.

“a path is nothing more than a sequence of vertices where every pair of adjacent vertices is an edge.” — Solomon, 27:15

Üç model problem (artan zorlukta): (1) tek-çift erişilebilirlik (\(s\)’den \(t\)’ye yol var mı?), (2) tek-çift en kısa yol, (3) tek-kaynak en kısa yol (SSSP)\(s\)’den her düğüme en kısa mesafe. Bunlar indirgemeyle bağlıdır: SSSP çözülürse (2) çözülür (yalnız \(t\)’ye bak), (2) çözülürse (1) çözülür (\(\infty\) ise erişilemez). Bugün (3)’ü çözeriz.

“a key idea in an algorithms class is this idea of reduction — that I can use one function to solve another.” — Solomon, 31:12

Şekil 14.4 üç problemi soldan sağa artan güçle dizer ve aralarındaki indirgeme oklarını gösterir: en güçlü problem (SSSP) çözülünce daha güçsüz ikisi de “bedava” çözülür.

Şekil 14.4: Üç çizge problemi + indirgeme zinciri: SSSP çözünce üçü birden çözülür (L9 §6, İMZA figür). Soldan sağa artan güç: (1) TEK-ÇİFT ERİŞİLEBİLİRLİK — s’den t’ye yol VAR mı? örnek a→g → EVET. (2) TEK-ÇİFT EN KISA YOL — kaç adımda? a→g = 4 adım. (3) SSSP (amber çerçeve, bugün çözülen) — s’den HER düğüme uzaklık: a:0 b:1 c:1 d:2 e:2 f:3 g:4. Kutular arası SOLA dönük amber ‘indirger’ okları: 3→2 (‘yalnız t’ye bak’), 2→1 (‘uzaklık sonlu mu?’). İndirgeme = bir problemi, başka bir problemin çözümünü ÇAĞIRAN bir fonksiyonla çözmek. Veri MOTORDAN: bfs(build_example_graph(),‘a’) → delta[g]=4, tablo a:0 b:1 c:1 d:2 e:2 f:3 g:4; reconstruct_path → a→g yolu VAR (erişilebilir) (Solomon 31:12).

14.8 7. En Kısa Yol Ağacı

Her düğüme giden tam yolu saklamak \(O(V^2)\) yer ister (her yol \(O(V)\), \(V\) yol). Daha iyisi: her düğümde yalnızca öncülünü (predecessor) \(P(v)\) tut — en kısa yolda \(v\)’den bir önceki düğüm. Yolu, \(P(v), P(P(v)), \ldots\) ile geriye izleyerek kurarsın. Yer: \(O(V)\).

Çalışılan Örnek — optimal alt yapı. Bu, en kısa yolların güzel özelliğine dayanır: örnek çizgemizde \(a\)’dan \(g\)’ye en kısa yol \(a \to b \to d \to f \to g\)’dir; onun bir öneki (\(a \to b \to d\)) de \(a\)’dan \(d\)’ye en kısa yoldur. (Aksi halde daha kısa bir \(a \leadsto d\) parçasını araya ekleyip \(a \to g\) yolunu kısaltırdık — en kısa olmasıyla çelişir.) Bu optimal alt yapı sayesinde, tüm yol yerine tek bir “geri ok” yeterlidir. Sonuçta oluşan yapı bir ağaçtır (döngü olamaz — geri izleme kaynağa varır).

“this object is called the shortest path tree.” — Solomon, 38:31

(Uyarı: tek bir kenar eklemek her düğümün en kısa yolunu değiştirebilir; kaynağı değiştirmek de — o zaman her şeyi yeniden hesaplarız.)

Şekil 14.5 örnek çizge üzerinde öncül ağacını çizer: kalın geri oklar her düğümden ebeveynine (\(P(v)\)), amber yol \(a \to g\) geriye izlenir (\(g \to f \to d \to b \to a\), ters çevir \(\to [a, b, d, f, g]\)), sağda öncül tablosu ve “\(O(V)\) yer vs üstü çizili \(O(V^2)\)” karşılaştırması.

Şekil 14.5: En kısa yol ağacı: öncül P(v) ile geriye izleme → yol [a, b, d, f, g] (L9 §7, İMZA figür). Sol/orta: örnek çizge; tüm kenarlar soluk slate; ÖNCÜL kenarları (b→a, c→a, d→b, e→c, f→d, g→f) kalın GERİ OKLARI (çocuktan ebeveyne) → bu oklar en kısa yol AĞACINI kurar. a→g yolu amber vurgu: g→f→d→b→a geriye izle, ters çevir → [a,b,d,f,g]; a→d öneki amber kesikli (optimal alt yapı). Sağ panel: öncül tablosu P (a kök, b:a, c:a, d:b, e:c, f:d, g:f); ‘yer O(V)’ vs üstü çizili ‘tüm yollar O(V²)’. Alt kutu: OPTİMAL ALT YAPI — en kısa yolun her öneki de en kısadır → tek geri ok yeter. Veri MOTORDAN: parent = {a:None, b:a, c:a, d:b, e:c, f:d, g:f}; reconstruct_path(P,a,g) = [a,b,d,f,g] (Solomon 38:31).

14.9 8. Seviye Kümeleri ve BFS

Seviye kümesi \(L_k\): kaynaktan tam \(k\) uzaklıktaki düğümler. \(L_0 = \{\text{kaynak}\}\). BFS, bu kümeleri katman katman üretir.

“the level set… all the vertices that are distance k away from my source.” — Solomon, 42:08

Çalışılan Örnek — BFS algoritması. Başlat: \(L_0 = \{s\}\), \(\delta(s, s) = 0\), \(P\) boş. Sonra, önceki seviye boş olmayana dek (\(i = 1, 2, \ldots\)): önceki seviyedeki her \(u\) için, \(u\)’nun henüz görülmemiş her komşusu \(v\)’ye: \(v\)’yi \(L_i\)’ye ekle, \(\delta(s, v) = i\) yap, \(P(v) = u\) ata. “Henüz görülmemiş” şart — bir düğümü iki seviyeye koymayız (ilk görüldüğü uzaklık en kısadır).

“Breadth-First search… an algorithm for computing all of those level sets.” — Solomon, 43:35

Mantık tümevarımsaldır: \(u\)’ya \(i-1\) adımda ulaşılıyorsa, komşusuna \(i\) adımda ulaşılır. Algoritma \(\delta\) (mesafe), \(P\) (öncül) ve \(L\) (seviye) bilgilerini tek seferde doldurur.

Şekil 14.6 örnek çizgede seviye kümelerini “dalga dalga” gösterir: kaynak \(a\)’dan eş-merkezli halkalar, her düğüm bulunduğu seviyenin tonuyla, altında \(\delta\) rozeti.

Şekil 14.6: BFS = dalga dalga yayılma: seviye kümeleri Lₖ (kaynaktan tam k uzaklık) (L9 §8, İMZA figür). Örnek çizge (7 düğüm, 8 yönsüz kenar) kaynak a’dan eş-merkezli KESİKLİ dalga yaylarıyla — bir taşın suya düşmesiyle oluşan halkalar gibi. Her düğüm bulunduğu seviyenin tonuyla dolar: L0 a amber dolgu (kaynak), L1 b,c amber-300, L2 d,e amber-100, L3 f slate açık, L4 g beyaz+slate çerçeve. Her düğümün altında δ rozeti: a:0 b:1 c:1 d:2 e:2 f:3 g:4. Sağda seviye tablosu L0={a} L1={b,c} L2={d,e} L3={f} L4={g}. Bir düğüm İLK görüldüğü seviyede sabitlenir (en kısa uzaklık δ) — iki seviyeye KONMAZ. Veri MOTORDAN: bfs_levels(build_example_graph(),‘a’) = [[a],[b,c],[d,e],[f],[g]] (Solomon 42:08).

BFS’i komşuluk listesi üzerinde Python’da yazmak kısadır (kuyruk = FIFO; “henüz görülmemiş” kontrolü \(\delta\) sözlüğünde):

from collections import deque

def bfs(adj, s):
    delta = {s: 0}
    parent = {s: None}
    queue = deque([s])
    while queue:
        u = queue.popleft()
        for v in adj[u]:
            if v not in delta:        # henuz gorulmemis
                delta[v] = delta[u] + 1
                parent[v] = u
                queue.append(v)
    return delta, parent

14.10 9. BFS Çalışma Süresi O(V + E)

İki bileşen: (1) \(V\) boyutlu mesafe/öncül dizilerini ayırmak \(O(V)\); (2) “her düğüm için her komşusunu gez” döngüsü — her düğüm tam bir kez görülür (seviye sırasında), komşu gezmelerinin toplamı \(=\) derecelerin toplamı \(= O(E)\). Toplam:

\[T(\text{BFS}) = O(V + E)\]

“our algorithm takes big O of mod v plus mod e time.” — Solomon, 51:40

Bu sınıfta buna doğrusal zaman denir (çizgeyi saklamak için kullanılan yerde doğrusal). İki terim de gereklidir: kenarsız çizgede \(V\) baskın; kenar arttıkça \(E\) (\(V^2\)’ye kadar) baskın — \(V^2\) demekten daha bilgilendirici bir ifade.

Şekil 14.7 bu yürütmeyi adım adım izler: kuyruk (FIFO) katman katman boşalır, \(\delta\) tablosu tek geçişte soldan sağa dolar; toplam-iş kutusu \(\sum \deg = 2|E| = 16\) ile \(O(V + E)\) sonucunu özetler.

Şekil 14.7: BFS yürütme izi: kuyruk katman katman boşalır, δ tablosu tek geçişte dolar (L9 §8-9, İMZA figür). Sol üst: örnek çizge (7 düğüm, 8 yönsüz kenar) + her düğümün δ değeri. Sağ: 7 satırlık adım izi (her satır = bir adım). Her düğüm KUYRUKTAN tam BİR kez çıkar (işlenir, amber dolu daire); çıkışta HENÜZ GÖRÜLMEMİŞ komşulara δ[v]=δ[u]+1 yazılır (amber-100 daireler) ve kuyruk SONUNA eklenir. Adımlar: 1.a→ekle b,c | 2.b→ekle d | 3.c→ekle e | 4.d→ekle f | 5.e→(yok, tümü görülmüş) | 6.f→ekle g | 7.g→(yok). Sağ alt kutu: her düğüm 1 kez işlenir → O(V); komşu gezmeleri = derece toplamı Σ deg = 2|E| = 16 → O(E); ⇒ BFS = O(V+E) (V=7, E=8). Doğrusal zaman = çizgeyi saklama YERİNDE doğrusal. Veri MOTORDAN: bfs_trace 7 adım, adım1 u=a added=[b,c], son delta a:0 b:1 c:1 d:2 e:2 f:3 g:4 (Solomon 51:40).

14.11 Bu Dersin Özeti

  1. Çizge \(G = (V, E)\); kenar = düğüm çifti; yönlü (sıralı) veya yönsüz (sırasız).
  2. Basit çizge: özdöngüsüz, çoklu-kenarsız; \(|E| = O(V^2)\); seyrek/yoğun ayrımı.
  3. Derece toplamı \(= 2|E|\) (yönsüz) / \(|E|\) (yönlü) → “her düğüm-her komşu” döngüsü \(O(E)\).
  4. Gösterim: kenar listesi (\(O(E)\) sorgu), komşuluk listesi + hash (\(O(1)\) sorgu), komşuluk matrisi (\(O(1)\) sorgu, \(O(V)\) komşu).
  5. Yol = ardışık-kenarlı düğüm dizisi; uzunluk = kenar sayısı; 3 problem indirgemeyle bağlı.
  6. En kısa yol ağacı: öncül \(P(v)\) ile \(O(V)\) yer; optimal alt yapı.
  7. BFS: seviye kümeleri \(L_k\); \(\delta/P/L\)’yi doldurur; \(O(V + E)\) (doğrusal).
ÖnemliTek Bir Cümle

BFS, kaynaktan dışa doğru “dalga dalga” yayılarak (seviye kümeleri) ağırlıksız en kısa yolu \(O(V + E)\)’de bulur; öncül ağacı sayesinde yolları da \(O(V)\) yerde saklar.

14.12 Kontrol Soruları

Cevap: Bağlıdır. Komşuluk matrisi kenar sorgusunu (\(v \to w\) var mı?) \(O(1)\) yapar ama \(O(V^2)\) yer ister ve bir düğümün komşularını gezmek \(O(V)\)’dir (tüm satırı taramak gerekir). Komşuluk listesi (+ hash) hem kenar sorgusunu beklenen \(O(1)\) hem de komşu gezmeyi \(O(\text{derece})\) yapar ve yalnızca \(O(V + E)\) yer kullanır. Seyrek çizgelerde (\(E \ll V^2\)) — ki çoğu gerçek çizge seyrektir — komşuluk listesi belirgin biçimde üstündür.

Cevap: Her düğüm için tam yolu (\(V\)’ye kadar düğüm) saklarsak \(O(V^2)\) olur. Ama optimal alt yapı sayesinde, her düğümde yalnızca öncülü \(P(v)\) (tek düğüm) tutmak yeterlidir — yolu \(P(v), P(P(v)), \ldots\) ile geriye izleyerek yeniden kurarız. Her düğüm bir öncül tuttuğundan toplam \(O(V)\) yerdir; yine de her yolu tam olarak verir.

Cevap: BFS, düğümleri kaynaktan artan uzaklık sırasında işler. Bir düğüm ilk kez \(L_i\)’de görüldüğünde, ona en kısa mesafe tam \(i\)’dir (daha erken bir seviyede görülmediğine göre). Onu daha sonraki bir \(L_j\)’ye (\(j > i\)) tekrar eklersek, yanlış (daha uzun) mesafe atamış oluruz. “Henüz görülmemiş” kontrolü, her düğümün ilk (= en kısa) uzaklığını sabitler ve algoritmanın doğruluğunu sağlar.

Cevap: İki ayrı maliyet vardır: \(V\) boyutlu mesafe/öncül dizilerini ayırmak \(O(V)\); ve “her düğüm için her komşusunu gez” döngüsü, derecelerin toplamı \(= O(E)\). Her düğüm tam bir kez işlendiğinden çift sayım yoktur. \(O(V + E)\) yazmak \(O(V^2)\)’den daha bilgilendiricidir: kenarsız çizgede \(V\) baskın, yoğun çizgede \(E\) (\(\le V^2\)) baskın olur. Tek terim, çizgenin seyrekliğini gizlerdi.

14.13 Egzersizler

Egzersiz 1. Verilen bir yönlü çizge için \(\text{Adj}^{+}\) ve \(\text{Adj}^{-}\) kümelerini, her düğümün in/out derecesini yaz; derecelerin toplamının \(|E|\) (çıkış) olduğunu doğrula.

Egzersiz 2. Bir çizgeyi hem komşuluk listesi hem komşuluk matrisi olarak temsil et; “\(v \to w\) var mı?” ve “\(u\)’nun komşuları” sorgularının her birinde maliyetini karşılaştır.

Egzersiz 3. Optimal alt yapıyı kanıtla: \(a \to \ldots \to v\) en kısa yol ise, onun her öneki de bir en kısa yoldur. (İpucu: daha kısa bir önek olsaydı ana yolu kısaltırdın.)

Egzersiz 4. Python’da komşuluk listesi üzerinde BFS yaz (\(\delta\) ve \(P\) döndür):

from collections import deque

def bfs(adj, s):
    delta = {s: 0}
    parent = {s: None}
    queue = deque([s])
    while queue:
        u = queue.popleft()
        for v in adj[u]:
            if v not in delta:        # henuz gorulmemis
                delta[v] = delta[u] + 1
                parent[v] = u
                queue.append(v)
    return delta, parent

Egzersiz 5. BFS’in ürettiği parent (öncül) sözlüğünden, \(s\)’den belirli bir \(t\)’ye en kısa yolu (düğüm dizisi) yeniden kuran bir fonksiyon yaz. Süresi nedir?

14.14 Sonraki Ders İçin Hazırlık

Ders 15 (L10): Derinlemesine Arama (DFS) ve Topolojik Sıralama

Justin Solomon ile, BFS’in kardeşi DFS (depth-first search)’e geçiyoruz: çizgeyi “olabildiğince derine in, sonra geri çekil” mantığıyla gez. DFS, topolojik sıralama (bağımlılık sıralaması) ve çevrim tespiti için kullanılır. (Not: kitap düzeninde önce Ders 14 (Quiz 1 Gözden Geçirme, Jason Ku) araya girer; DFS bunun ardından gelir.)

UyarıDers 15 Öncesi Yapılacak
  • Bu dersin egzersizlerini, özellikle Egzersiz 4’ü (BFS) çöz.
  • Üç çizge problemini (erişilebilirlik, tek-çift, tek-kaynak) ve indirgemeleri ezberden anlat.
  • Ana cümleyi tekrar oku: “BFS dalga dalga yayılarak ağırlıksız en kısa yolu \(O(V + E)\)’de bulur.”

14.15 Anahtar Kavramlar (Cheat Sheet)

Kavram Tanım Sayfada
Çizge \(G = (V, E)\) Düğümler + kenarlar; yönlü (sıralı) / yönsüz (sırasız) Böl. 1
Basit çizge Özdöngüsüz, çoklu-kenarsız; \(\lvert E \rvert = O(V^2)\) Böl. 3
Derece toplamı \(2\lvert E \rvert\) (yönsüz) / \(\lvert E \rvert\) (yönlü) → komşu döngüsü \(O(E)\) Böl. 4
Komşuluk listesi Düğüm → komşular (hash); kenar sorgusu \(O(1)\) Böl. 5
Yol / en kısa yol Ardışık-kenarlı dizi; uzunluk = kenar sayısı Böl. 6
En kısa yol ağacı Öncül \(P(v)\); \(O(V)\) yer; optimal alt yapı Böl. 7
Seviye kümesi \(L_k\) Kaynaktan \(k\) uzaklıktaki düğümler Böl. 8
BFS Katman katman; \(\delta/P/L\) doldurur; \(O(V + E)\) Böl. 8-9

14.16 Builder ve OMSCS Bağlantıları

İpucu6 köprü

Bu ders, “bağlı her şeyin evrensel soyutlaması (çizge)” ve “katman katman keşif (BFS)” sezgisini kurar — köprülerin özeti:

  1. Çizge gösterimi → her sistem tasarımı: sosyal graf, bağımlılık grafı, ağ topolojisi — komşuluk listesi varsayılan.
  2. BFS → en kısa yol (ağırlıksız), web crawler (katman katman), ağ yayını, “kaç adım uzakta” (LinkedIn derece).
  3. Reduction → OMSCS CS 6515: problemleri birbirine indirgemek, NP-tamlık dahil her yerde temel teknik.
  4. Optimal alt yapı → dinamik programlama (DP) köprüsü: en kısa yol, DP’nin habercisidir (alt-problem çözümleri birleşir).
  5. \(O(V + E)\) doğrusal → seyreklik bilinci: gerçek çizgeler seyrektir; \(E\)-bağlı algoritma \(V^2\)-bağlıdan çok hızlıdır.
  6. Öncül ağacı → yol yeniden kurma: routing tablosu, git geçmişi, bağımlılık çözümü — hep “geri izleme”.

ÖnemliTek bir şey alıp gideceksen

Çizge, “bağlı her şeyin” evrensel soyutlamasıdır; onu komşuluk listesiyle saklayıp BFS ile kaynaktan dışa dalga dalga gezersek, ağırlıksız en kısa yolu \(O(V + E)\)’de buluruz. Ve tüm yolları saklamak yerine sadece “öncül”leri tutarak, \(O(V)\) yerde her yolu yeniden kurabiliriz.