Bölüm 4.1: Çizge Gezinme Algoritmaları

Bölüm 4.1: Çizge Gezinme Algoritmaları · Çalışma Soruları
Çizge gösterimiDerinlik öncelikli arama (DFS)Genişlik öncelikli arama (BFS)Ağırlıksız en kısa yolTarjan SCCTopolojik sıralama
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Çoktan Seçmeli · Gösterim

Soru 1: Liste ve Matris Boyutu

Yönsüz, 7 düğümlü ve 9 kenarlı bir çizge komşuluk listesi ve komşuluk matrisiyle ayrı ayrı tutuluyor. Komşuluk listelerindeki toplam öğe sayısı ve matrisin hücre sayısı nedir?

C: Yönsüz çizgede her kenar iki listede görünür: 2E = 18 öğe; matris V × V = 49 hücredir. A, yönsüz kenarın iki kez yazıldığını unutur; B köşegeni (n(n−1)) dışarıda bırakır. Bellek: liste O(V + E), matris O(V²).

Çıktı Sorusu · Gösterim

Soru 2: Matrisle DFS

Yönlü çizge komşuluk matrisiyle verilmiştir (G[i][j] = 1: i → j kenarı). dfs(0) ne yazdırır?

01234
000101
110000
201010
301000
400010
void dfs(int v) {
  ziyaret[v] = true;
  System.out.print(v + " ");
  for (int w = 0; w < n; w++)
    if (G[v][w] == 1 && !ziyaret[w])
      dfs(w);
}
Cevabı göster

Çıktı: 0 2 1 3 4

  • 0'ın satırı: ilk 1 sütun 2'de → dfs(2). 2'nin satırı: 1 → dfs(1); 1'in tek komşusu 0 ziyaretli, döner.
  • 2'de taramaya devam: 3 → dfs(3); 3 → 1 ziyaretli, döner. 2 biter, 0'a dönülür.
  • 0'da sütun 4 → dfs(4); 4 → 3 ziyaretli. Çağrılar biter.

Satırlar soldan sağa tarandığı için komşular artan sırada denenir. Her düğüm için n öğeli satır tarandığından zaman O(V²) (BFS sırası ise 0 2 4 1 3 olurdu).

Adım Adım Çalıştırma · DFS

Soru 3: Özyinelemeli DFS İzleme

dfs(0, ziyaret) hangi sırayla yazdırır? Sarı düğümler çağrı yığınındaki çerçevelerdir.

012345

Yönlü çizge, komşu listeleri artan sırada: 0: 1, 3 · 1: 2, 4 · 2: 0 · 3: 4 · 4: 2, 5 · 5: —. Hiçbir düğüm ziyaret edilmedi.

012345

dfs(0): 0 işaretlenir ve yazdırılır; çağrı yığınında tek çerçeve var.

012345

0'ın komşusu 1 ziyaret edilmemiş → dfs(1): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.

012345

1'in komşusu 2 ziyaret edilmemiş → dfs(2): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.

012345

2 → 0 kenarı: 0 zaten ziyaretli (yığında, işi sürüyor) → atlanır.

012345

2 bitti, çağrı döner; kontrol 1'e geri gelir (geri dönüş).

012345

1'in komşusu 4 ziyaret edilmemiş → dfs(4): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.

012345

4 → 2 kenarı: 2 zaten ziyaretli (bitmiş) → atlanır.

012345

4'ün komşusu 5 ziyaret edilmemiş → dfs(5): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.

012345

5, 4, 1 bitti, çağrı döner; kontrol 0'a geri gelir (geri dönüş).

012345

0'ın komşusu 3 ziyaret edilmemiş → dfs(3): işaretlenir, yazdırılır; yığına yeni çerçeve eklenir.

012345

3 → 4 kenarı: 4 zaten ziyaretli (bitmiş) → atlanır.

012345

3 bitti, çağrı döner; kontrol 0'a geri gelir (geri dönüş).

012345

Tüm çağrılar döndü. Çıktı: 0 1 2 4 5 3. Vurgulu kenarlar DFS ağacıdır; 2 → 0 geri kenardır (döngü).

void dfs(int v, boolean[] ziyaret) {
  ziyaret[v] = true;
  System.out.print(v + " ");
  for (int w : komsu[v])
    if (!ziyaret[w])
      dfs(w, ziyaret);
}

Çoktan Seçmeli · DFS

Soru 4: Yığınla DFS'in Özellikleri

Derste yazılan dfsYigin (yığından çekerken işaretleyen sürüm) için aşağıdakilerden hangisi doğrudur?

B: İşaretleme çekerken yapıldığı için henüz çekilmemiş bir düğüm farklı komşulardan tekrar itilebilir; itme sayısı 1 + Σ derece, yani O(E)'dir. C yanlıştır: sıra itme sırasının tersine döner. D yanlıştır: ziyaret dizisi olmadan döngüde aynı düğümler sonsuza kadar itilir.

Çoktan Seçmeli · DFS

Soru 5: Yönlü Çizgede Döngü

Yönlü bir çizgede DFS ile döngü aranıyor (sarı: çağrı yığınında, koyu: bitmiş, beyaz: keşfedilmemiş). DFS sırasında hangi durum kesin olarak bir döngü olduğunu gösterir?

abcde

C: Yığındaki w, v'nin atasıdır; w ⇝ v ağaç yolu ve v → w kenarı birlikte döngüdür (geri kenar). A ve B yanlıştır: yönlü çizgede bitmiş düğüme giden kenar (çapraz/ileri kenar) döngü oluşturmayabilir. Şekilde d → b kenarı daha sonra incelenecek; b yığında olduğundan e → d → b → c → e döngüsü bulunur.

Çıktı Sorusu · DFS

Soru 6: Kaç Kez Başlatılır?

Yönlü çizgede aşağıdaki kod çalıştırılıyor (dfs özyinelemeli DFS'tir). Ne yazdırır? Döngü v = n − 1'den 0'a doğru dönseydi ne yazdırırdı?

320154
int sayac = 0;
for (int v = 0; v < n; v++)
  if (!ziyaret[v]) {
    dfs(v, ziyaret);
    sayac++;
  }
System.out.println(sayac);
Cevabı göster

Artan sırada: 5. dfs(0) yalnızca {0, 1}'i gezer (0'dan 2'ye kenar yok); sonra 2, 3, 4, 5 ayrı ayrı başlatılır.

Azalan sırada: 2. dfs(5) {5, 4}'ü, dfs(3) ise 3 → 2 → 0 → 1 ile kalan dört düğümü gezer.

Yönsüz çizgede başlatma sayısı bağlantılı bileşen sayısına eşittir. Yönlü çizgede ise sıraya bağlıdır; ne zayıf bileşen sayısını (2) ne de güçlü bağlantılı bileşen sayısını (6) verir.

Adım Adım Çalıştırma · BFS

Soru 7: BFS İzleme

bfs(0) hangi sırayla yazdırır? Kuyruğun içeriğini ve BFS ağacını izleyin.

0351624kuyruk0↑ ön

Yönsüz çizge, komşu listeleri artan sırada. 0 işaretlendi ve kuyruğa kondu (katman 0).

0351624kuyruk35↑ ön

0 çıkarıldı ve yazdırıldı. Yeni komşular 3, 5 işaretlenip kuyruğun sonuna eklendi (uzaklık 1).

0351624kuyruk516↑ ön

3 çıkarıldı ve yazdırıldı. Yeni komşular 1, 6 işaretlenip kuyruğun sonuna eklendi (uzaklık 2).

0351624kuyruk162↑ ön

5 çıkarıldı ve yazdırıldı. Yeni komşu 2 işaretlenip kuyruğun sonuna eklendi (uzaklık 2).

0351624kuyruk62↑ ön

1 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.

0351624kuyruk24↑ ön

6 çıkarıldı ve yazdırıldı. Yeni komşu 4 işaretlenip kuyruğun sonuna eklendi (uzaklık 3).

0351624kuyruk4↑ ön

2 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.

0351624kuyrukboş

4 çıkarıldı ve yazdırıldı. Keşfedilmemiş komşusu yok.

0351624kuyrukboş

Kuyruk boş. Çıktı 0 3 5 1 6 2 4; katmanlar {0}, {3, 5}, {1, 6, 2}, {4}. Vurgulu kenarlar BFS ağacıdır.

void bfs(int s) {
  boolean[] ziyaret = new boolean[n];
  Queue<Integer> kuyruk = new LinkedList<>();
  ziyaret[s] = true; kuyruk.add(s);
  while (!kuyruk.isEmpty()) {
    int v = kuyruk.poll();
    System.out.print(v + " ");
    for (int w : komsu[v])
      if (!ziyaret[w]) {
        ziyaret[w] = true;
        kuyruk.add(w);
      }
  }
}

Çıktı Sorusu · BFS

Soru 8: BFS Uzaklıkları ve Yol

A'dan BFS (komşular alfabetik) ile ziyaret sırasını, her düğümün uzaklığını ve ebeveynini bulun. Ebeveyn dizisiyle A'dan H'ye en kısa yol nedir?

ABDCEGFH
Cevabı göster

Sıra: A B D C E G F H

düğümABCDEFGH
uzaklık01212323
ebeveyn—ABABCDG

H → ebeveyn G → ebeveyn D → ebeveyn A; ters çevrilince A → D → G → H (3 kenar). A–B–C–F–H de bir yoldur ama 4 kenarlıdır; BFS bir düğüme ilk ulaştığı anda en az kenarlı yolu bulmuştur.

Çoktan Seçmeli · BFS

Soru 9: Ağırlıklı Çizgede BFS

BFS ebeveyn dizisiyle s'den t'ye bir yol bulunuyor (komşular alfabetik). Bulunan yolun toplam ağırlığı ve gerçek en kısa yolun ağırlığı nedir?

sabt22715

D: BFS kenar sayısına bakar; t'yi s'nin komşusu olarak ilk katmanda bulur: s → t (1 kenar, ağırlık 7). En hafif yol s → a → t = 2 + 2 = 4'tür. B, s → b → t'yi (6) en kısa sanar. Ağırlıklı çizgede Dijkstra gerekir; BFS yalnızca tüm ağırlıklar eşitse doğrudur.

Çoktan Seçmeli · BFS

Soru 10: Kuyruk ve Yığın Boyutu

15 düğümlü tam ikili ağaç (4 düzey) bir çizge olarak kökten geziliyor. Derste yazılan BFS'te kuyruk en çok kaç düğüm tutar, özyinelemeli DFS'te çağrı yığını en çok kaç çerçeve olur?

B: BFS son düzeydeki 8 yaprağı birlikte kuyrukta tutar (en geniş katman); DFS ise kökten yaprağa en uzun yol kadar, 4 çerçeve derinleşir. A ikisini karıştırır. Genel olarak BFS'in belleği en geniş katmana, DFS'inki en derin yola bağlıdır; ikisi de en kötü O(V).

Klasik Soru · BFS

Soru 11: İki Parçalılık Testi

A'dan BFS ile katmanları bulup çift katmanları bir renge, tek katmanları öteki renge boyayın. Çizge iki parçalı mıdır? Değilse sorunu hangi kenar gösterir ve D–E kenarı silinirse ne olur?

ABCDEF
Cevabı göster ABCDEFk0k1k1k2k2k3

Katmanlar: A (0); B, C (1); D, E (2); F (3). D–E kenarının iki ucu da katman 2'de → aynı renk: çizge iki parçalı değildir. C–D–E tek uzunlukta (3) bir döngüdür.

D–E silinirse tüm kenarlar ardışık katmanları bağlar: kümeler {A, D, E} ve {B, C, F}; çizge iki parçalı olur. Test O(V + E) sürer.

Çoktan Seçmeli · Tarjan SCC

Soru 12: Kaç SCC Var?

Yönlü çizgenin kaç güçlü bağlantılı bileşeni (SCC) vardır?

01263457

D: {0, 1, 2} (0 → 1 → 2 → 0), {3, 4} (3 ⇄ 4) ve {5, 6, 7} (5 → 6 → 7 → 5). 1 → 6 ve 2 → 3, 4 → 5 kenarları bileşenleri birbirine bağlar ama geri dönüş yolu olmadığı için onları birleştirmez. 1 cevabı, "0'dan herkese ulaşılıyor" yanılgısıdır: SCC karşılıklı ulaşılabilirlik ister.

Adım Adım Çalıştırma · Tarjan SCC

Soru 13: Tarjan İzleme

scc(0) çağrısı ne yazdırır? indeks, dusuk ve yığını izleyin.

01234

Çizge: 0 ⇄ 1, 1 → 2, 2 → 3 → 4 → 2. indeks[w] == 0 ziyaret edilmedi demektir; düğüm yanındaki etiket indeks/dusuk.

012341/1

scc(0): indeks = dusuk = 1; 0 yığına itilir.

012341/12/2

0 → 1: 1 ziyaret edilmemiş → scc(1): indeks = dusuk = 2; yığına itilir.

012341/12/1

1 → 0: 0 yığında → dusuk[1] = min(2, indeks[0] = 1) = 1.

012341/12/13/3

1 → 2: 2 ziyaret edilmemiş → scc(2): indeks = dusuk = 3; yığına itilir.

012341/12/13/34/4

2 → 3: 3 ziyaret edilmemiş → scc(3): indeks = dusuk = 4; yığına itilir.

012341/12/13/34/45/5

3 → 4: 4 ziyaret edilmemiş → scc(4): indeks = dusuk = 5; yığına itilir.

012341/12/13/34/45/3

4 → 2: 2 yığında → dusuk[4] = min(5, indeks[2] = 3) = 3.

012341/12/13/34/45/3

dusuk[4] = 3 ≠ indeks[4] = 5 → 4 kök değil, yığında kalır.

012341/12/13/34/35/3

scc(4) döndü: dusuk[3] = min(4, dusuk[4] = 3) = 3. dusuk[3] = 3 ≠ indeks[3] = 4 → 3 kök değil, yığında kalır.

012341/12/13/34/35/3

scc(3) döndü: dusuk[2] = min(3, dusuk[3] = 3) = 3. dusuk[2] = indeks[2] = 3 → 2 köktür; 4, 3, 2 çekilip yazdırılır: SCC {2, 3, 4}.

012341/12/13/34/35/3

scc(2) döndü: dusuk[1] = min(1, dusuk[2] = 3) = 1. dusuk[1] = 1 ≠ indeks[1] = 2 → 1 kök değil, yığında kalır.

012341/12/13/34/35/3

scc(1) döndü: dusuk[0] = min(1, dusuk[1] = 1) = 1. dusuk[0] = indeks[0] = 1 → 0 köktür; 1, 0 çekilip yazdırılır: SCC {0, 1}.

012341/12/13/34/35/3

Bitti: önce {2, 3, 4}, sonra {0, 1} bulundu. SCC'ler ters topolojik sırada çıkar: {0, 1} → {2, 3, 4} kenarı vardır.

void scc(int v) {
  indeks[v] = dusuk[v] = ++sayac;
  yigin.push(v); yiginda[v] = true;
  for (int w : komsu[v]) {
    if (indeks[w] == 0) {
      scc(w);
      dusuk[v] = Math.min(dusuk[v], dusuk[w]);
    } else if (yiginda[w])
      dusuk[v] = Math.min(dusuk[v], indeks[w]);
  }
  if (dusuk[v] == indeks[v]) {
    int w;
    do { w = yigin.pop(); yiginda[w] = false;
         System.out.print(w + " "); } while (w != v);
    System.out.println();
  }
}

Çıktı Sorusu · Tarjan SCC

Soru 14: Yığında mı Denetimi

Tarjan kodunda else if (yiginda[w]) satırı yalnızca else yapılırsa (ziyaret edilmiş her w için dusuk[v] = min(dusuk[v], indeks[w])), ziyaret edilmemiş her düğümden 0, 1, 2, 3 sırasıyla scc çağıran program ne yazdırır? Doğru kod ne yazdırırdı?

0132
Cevabı göster

Doğru kod: 1 0 ve 3 2 (iki satır).

Hatalı kod: yalnızca 1 0. scc(2)'de indeks[2] = 3, scc(3)'te indeks[3] = 4; 3 → 2 kenarı dusuk[3]'ü 3 yapar. 3 → 0 kenarında ise 0 bitmiş bir SCC'dedir ama denetim kalktığı için dusuk[3] = indeks[0] = 1 olur. Dönüşte dusuk[2] = 1 ≠ 3 → 2 kök sayılmaz; {2, 3} hiç yazdırılmaz, yığında kalır.

Bitmiş SCC'lere giden kenarlar yok sayılmalıdır; aksi hâlde kökler kaybolur.

Çıktı Sorusu · Uygulamalar

Soru 15: Ters Bitiş Sırası

Döngüsüz yönlü çizgede (DAG) komşu listeleri artan sıradadır. Program ne yazdırır?

051234
void dfsBitis(int v) {
  ziyaret[v] = true;
  for (int w : komsu[v])
    if (!ziyaret[w]) dfsBitis(w);
  yigin.push(v);           // bitince it
}
// main: ziyaret edilmemiş her v için
for (int v = 0; v < n; v++)
  if (!ziyaret[v]) dfsBitis(v);
while (!yigin.isEmpty())
  System.out.print(yigin.pop() + " ");
Cevabı göster

Bitiş sırası: 4, 3, 1, 2, 0, 5 (dfsBitis(0): 0 → 1 → 3 → 4; 4, 3, 1 biter; 2 biter, 0 biter; sonra dfsBitis(5): 5 biter).

Yığından çekilen sıra (ters bitiş): 5 0 2 1 3 4

Her u → v kenarında v, u'dan önce biter; bu yüzden ters bitiş sırasında u önce gelir. Kahn bu çizgede 0 5 1 2 3 4 verir; ikisi de geçerlidir. Zaman O(V + E).

Adım Adım Çalıştırma · Uygulamalar

Soru 16: Kahn Algoritması İzleme

kahn() hangi topolojik sırayı yazdırır? Giriş derecelerini ve kuyruğu izleyin.

013245gd=0gd=0gd=2gd=2gd=1gd=2kuyrukboş

DAG: kenarlar 0→2, 0→3, 1→3, 1→4, 3→2, 2→5, 4→5. Giriş dereceleri sayıldı (etiketler).

013245gd=0gd=0gd=2gd=2gd=1gd=2kuyruk01

Giriş derecesi 0 olanlar (0, 1) kuyruğa kondu: önlerinde bekleyen iş yok.

013245gd=0gd=0gd=1gd=1gd=1gd=2kuyruk1

0 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 2 (1), 3 (1). Kuyruğa ekleme yok.

013245gd=0gd=0gd=1gd=0gd=0gd=2kuyruk34

1 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 3 (0), 4 (0). 3, 4 kuyruğa eklendi.

013245gd=0gd=0gd=0gd=0gd=0gd=2kuyruk42

3 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 2 (0). 2 kuyruğa eklendi.

013245gd=0gd=0gd=0gd=0gd=0gd=1kuyruk2

4 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 5 (1). Kuyruğa ekleme yok.

013245gd=0gd=0gd=0gd=0gd=0gd=0kuyruk5

2 çıkarıldı, yazdırıldı. Kenarları silinir: gd azalır → 5 (0). 5 kuyruğa eklendi.

013245gd=0gd=0gd=0gd=0gd=0gd=0kuyrukboş

5 çıkarıldı, yazdırıldı. Çıkan kenarı yok.

013245gd=0gd=0gd=0gd=0gd=0gd=0kuyrukboş

Kuyruk boş; 6 düğümün hepsi çıktı → çizge döngüsüz. Topolojik sıra: 0 1 3 4 2 5.

void kahn() {
  int[] gd = new int[n];    // giriş dereceleri
  for (int v = 0; v < n; v++)
    for (int w : komsu[v]) gd[w]++;
  Queue<Integer> kuyruk = new LinkedList<>();
  for (int v = 0; v < n; v++)
    if (gd[v] == 0) kuyruk.add(v);
  while (!kuyruk.isEmpty()) {
    int v = kuyruk.poll();
    System.out.print(v + " ");
    for (int w : komsu[v])
      if (--gd[w] == 0) kuyruk.add(w);
  }
}

Çoktan Seçmeli · Uygulamalar

Soru 17: Geçersiz Topolojik Sıra

Şekildeki DAG için aşağıdaki sıralardan hangisi topolojik sıra değildir?

013245

A: 3 → 2 kenarı vardır; topolojik sırada 3, 2'den önce gelmelidir. A'da 2, 3'ten önce yazılmış. Diğer üçü her u → v kenarında u'yu önce yazar; topolojik sıra tek değildir (Kahn kuyruk sırasına göre bunlardan birini, 0 1 3 4 2 5'i verir).

Çoktan Seçmeli · Uygulamalar

Soru 18: Köprü Koşulu

Yönsüz bir çizgede DFS yapılıyor; keşif(v) keşif sırası, enDüşükBağ(w) ise w'nin alt ağacından tek bir geri kenarla ulaşılabilen en küçük keşif değeridir. DFS ağacındaki v–w kenarı (w çocuk) ne zaman köprüdür?

B: w'nin alt ağacından v'ye ya da v'nin atalarına geri kenar yoksa, v–w silinince alt ağaç kopar. A (≥) eklem noktası koşuludur: alt ağaç v'ye dönebiliyorsa v–w köprü değildir ama v yine de eklem noktası olabilir. D yalnızca w'nin v'den hemen sonra keşfedildiğini söyler.

Son

Bölüm 4.1: Çizge Gezinme Algoritmaları: Çalışma Soruları
Konu anlatımı: Çizge gezinme sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.