Bölüm 9: Geri İzleme Algoritmaları
Çoktan Seçmeli · Temel Fikir
Soru 1: Kaba Kuvvetten Farkı
Geri izlemeyi (backtracking) kaba kuvvetten ayıran temel özellik hangisidir?
A: Çözüm adım adım kısmi çözüm olarak kurulur; bir adım kısıtı bozunca o dal terk edilir ve altındaki alt ağaç hiç üretilmez. B kaba kuvvettir (8 vezirde 8⁸ ≈ 16,7 milyon tam yerleşim), C açgözlü yaklaşım, D dinamik programlamadır.
Çoktan Seçmeli · Temel Fikir
Soru 2: Geri Almayı Unutmak
Genel şablondaki cikar(kismi, a) (geri al) satırı silinirse ne olur?
B: Kısmi çözüm (tahta, yol, ziyaret dizisi) paylaşılan bir yapıdır; çağrıdan dönünce eski hâline getirilmezse sıradaki aday, önceki denemenin kalıntılarıyla birlikte sınanır. N vezirde t[s][k] = 0, kelime aramada ziyaret = false yapılmazsa geçerli dallar yanlışlıkla budanır ya da geçersiz "çözümler" üretilir. Yalnızca parametre olarak geçirilen ilkel değerler (ör. toplam) otomatik geri yüklenir.
Çıktı Sorusu · Alt Küme ve Permütasyon
Soru 3: Permütasyon Üretimi
Aşağıdaki kod uret(new ArrayList<>(), 3) ile çağrılıyor (kul 4 hücreli boolean dizi). Ne yazar? Durum uzayı ağacında kök dahil kaç düğüm vardır?
static boolean[] kul = new boolean[4]; static void uret(List<Integer> yol, int n) { if (yol.size() == n) { for (int x : yol) System.out.print(x); System.out.print(" "); return; } for (int v = 1; v <= n; v++) { if (!kul[v]) { kul[v] = true; yol.add(v); // seç uret(yol, n); // keşfet yol.remove(yol.size() - 1); // geri al kul[v] = false; } } }
Cevabı göster
Çıktı: 123 132 213 231 312 321
- Adaylar 1, 2, 3 sırasıyla denendiği için permütasyonlar sözlüksel sırada çıkar.
- Ağaç: kök 1 + 1. düzey 3 + 2. düzey 3·2 = 6 + 3. düzey 6 = 16 düğüm (uret çağrısı); 6 yaprak = 3!.
kul[v] = falseveremoveile geri alma yapılmasaydı yalnızca 123 yazılırdı. n öğe için O(n · n!).
Adım Adım Çalıştırma · Alt Küme ve Permütasyon
Soru 4: Alt Küme Toplamı İzleme
a = {3, 5, 6, 7} ve HEDEF = 15 için ara(0, 0) durum uzayı ağacını nasıl gezer? Bulunan ilk alt küme hangisidir?
a = {3, 5, 6, 7}, HEDEF = 15. Her düzeyde bir öğe için iki dal: önce "al" (+a[i]), sonra "alma" (−). Kökte toplam 0.
ara(1, 3): a[0] = 3 alındı → toplam 3. Önce a[1] = 5 alınmayı deneyecek.
ara(2, 8): a[1] = 5 alındı → toplam 8. Önce a[2] = 6 alınmayı deneyecek.
ara(3, 14): a[2] = 6 alındı → toplam 14. Önce a[3] = 7 alınmayı deneyecek.
ara(4, 21): 21 > 15 → budandı, false. Bu düğümün altı hiç üretilmez.
ara(4, 14): öğe kalmadı (i == n) ve toplam 15 değil → false; geri dön.
ara(3, 8): a[2] = 6 alınmadı → toplam 8. Önce a[3] = 7 alınmayı deneyecek.
ara(4, 15): toplam == HEDEF → true; true tüm çağrılar boyunca yukarı taşınır. Çözüm {3, 5, 7}.
boolean ara(int i, int toplam) { if (toplam == HEDEF) return true; if (i == n || toplam > HEDEF) return false; secildi[i] = true; // al if (ara(i + 1, toplam + a[i])) return true; secildi[i] = false; // alma return ara(i + 1, toplam); }
Çoktan Seçmeli · Alt Küme ve Permütasyon
Soru 5: Permütasyon Ağacı
{1, 2, 3, 4} kümesinin tüm permütasyonlarını geri dönüşle üreten aramanın durum uzayı ağacında kök dahil kaç düğüm vardır?
C: Düzeyler: kök 1, sonra 4, 4·3 = 12, 4·3·2 = 24, 24 → 1 + 4 + 12 + 24 + 24 = 65. 24 yalnızca yaprak (4!) sayısıdır; 256 = 4⁴, aynı öğenin tekrar seçilmesine izin veren (budamasız) ağacın yaprak sayısıdır.
Adım Adım Çalıştırma · N Vezir
Soru 6: 5 Vezir İzleme
n = 5 için coz(t, 0) ilk çözümü nasıl bulur? Kırmızımsı hücreler, o satırda önceki vezirlerin tehdit ettiği sütunlardır.
n = 5, boş tahta. coz(t, 0): satırlar yukarıdan aşağı doldurulur; her satırda sütun 0, 1, 2, … sırayla denenir.
Satır 0: sütun 0 güvenli → t[0][0] = 1, coz(t, 1).
Satır 1: sütun 0, 1 tehdit altında; sütun 2 güvenli → t[1][2] = 1, coz(t, 2).
Satır 2: sütun 0, 1, 2, 3 tehdit altında; sütun 4 güvenli → t[2][4] = 1, coz(t, 3).
Satır 3: sütun 0 tehdit altında; sütun 1 güvenli → t[3][1] = 1, coz(t, 4).
Satır 4: sütun 0, 1, 2 tehdit altında; sütun 3 güvenli → t[4][3] = 1, coz(t, 5).
satir == n → true; true yığın boyunca yukarı taşınır. Çözüm [0, 2, 4, 1, 3]: 5 yerleştirme, hiç geri dönüş yok (4 vezirde 8 yerleştirme, 4 geri dönüş gerekmişti).
boolean coz(int[][] t, int satir) { if (satir == n) return true; for (int sutun = 0; sutun < n; sutun++) { if (guvenliMi(t, satir, sutun)) { t[satir][sutun] = 1; if (coz(t, satir + 1)) return true; t[satir][sutun] = 0; // geri al } } return false; }
Çıktı Sorusu · N Vezir
Soru 7: 6 Vezir: İlk Çözüm
Dersteki coz metoduna her yerleştirmede artan bir yer sayacı eklendi. n = 6 için program ne yazar (sütunlar satır sırasıyla)?
static int yer = 0; static boolean coz(int[][] t, int satir) { if (satir == n) return true; for (int s = 0; s < n; s++) { if (guvenliMi(t, satir, s)) { t[satir][s] = 1; yer++; if (coz(t, satir + 1)) return true; t[satir][s] = 0; } } return false; } // main (n = 6): coz(t, 0); sonra her satırdaki // vezirin sütunu bir diziye yazılır: System.out.println( Arrays.toString(sut) + " " + yer);
Cevabı göster
Çıktı: [1, 3, 5, 0, 2, 4] 31
- Sütunlar küçükten büyüğe denendiği için sözlüksel sıradaki ilk çözüm bulunur: satır 0'da sütun 0 ile başlayan tüm dallar çıkmaza girer; çözüm sütun 1 ile başlar.
- İlk çözüme kadar 31 vezir yerleştirilir (n = 5'te 5, n = 7'de yalnızca 9): iş n ile düzgün artmaz.
- n = 6'nın yalnızca 4 çözümü vardır; tüm çözümleri bulmak için 152 yerleştirme gerekir.
Çıktı Sorusu · N Vezir
Soru 8: O(1) Güvenlik Testi
n = 8 için bayrak dizileriyle çalışan sürümde (2, 5) karesine bir vezir konuyor. Hangi sut, k1 ve k2 hücreleri true olur? Ardından (4, 3) ve (5, 2) kareleri güvenli midir?
boolean[] sut = new boolean[n]; boolean[] k1 = new boolean[2*n-1]; // r+c boolean[] k2 = new boolean[2*n-1]; // r-c+n-1 // (r, c) güvenli mi? int a = r + c, b = r - c + n - 1; if (sut[c] || k1[a] || k2[b]) continue; sut[c] = k1[a] = k2[b] = true; // yerleştir
Cevabı göster
- sut[5], k1[2 + 5] = k1[7], k2[2 − 5 + 7] = k2[4] true olur.
- (4, 3): k1[4 + 3] = k1[7] zaten true → aynı ters köşegende (2,5)–(3,4)–(4,3): güvenli değil.
- (5, 2): sut[2] false, k1[7] → 5 + 2 = 7 true → yine ters köşegende: güvenli değil. (5, 1) ise k1[6], k2[11], sut[1] hepsi false: güvenli.
Aynı ters köşegende r + c, aynı köşegende r − c sabittir; + n − 1 indisin 0'dan başlamasını sağlar. Test O(n) yerine O(1) olur.
Çoktan Seçmeli · N Vezir
Soru 9: Tüm Çözümleri Saymak
İlk çözümde duran coz metodunu tüm çözümleri sayacak biçimde değiştirmenin doğru yolu hangisidir?
A: false döndürmek aramayı sürdürür: üst çağrı tahtayı geri alır ve sıradaki sütunu dener. true döndürülürse ilk çözümde durulur. Bu değişiklikle n = 6 için 4, n = 8 için 92 çözüm sayılır; yerleştirme sayısı sırasıyla 152 ve 2056'dır.
Çıktı Sorusu · En Az Çakışma
Soru 10: Çakışma Sayıları
4 × 4 tahtada her sütunda bir vezir var; sütun 0, 1, 2, 3'teki vezirlerin satırları [2, 0, 3, 2]. Onarım için sütun 3'teki vezir seçildi. Bu vezir sütunu içinde her satıra taşınsa diğer vezirlerden kaçıyla çakışır? En az çakışma onu nereye taşır?
Cevabı göster
Sütun 3 için çakışma sayıları (satır 0–3): 1, 0, 3, 1.
- satır 0: 1 ((0,1) aynı satır) · satır 1: 0 · satır 2: 3 ((2,0) aynı satır, (0,1) çapraz, (3,2) çapraz) · satır 3: 1 ((3,2) aynı satır). Satır kaydı (r, s) = (satır, sütun).
- Şu anki satır 2 en kötüsüdür (3). En küçük değer 0, yalnızca satır 1'de → vezir oraya taşınır.
- Yeni yerleşim [2, 0, 3, 1]: hiçbir çakışma kalmaz, tek onarım adımıyla 4 vezir çözümü bulundu. Eşitlik olsaydı rastgele seçilirdi.
Çoktan Seçmeli · En Az Çakışma
Soru 11: En Az Çakışmanın Sınırı
En az çakışma sezgiseli ile geri izleme karşılaştırıldığında aşağıdakilerden hangisi doğrudur?
D: En az çakışma tam yerleşimle başlayıp yerel onarım yapan bir yerel aramadır: platolarda dolaşabilir ve tam değildir; adım sınırına ulaşmak "çözüm yok" demek değildir. Buna karşılık n = 1 000 000 için bile ortalama birkaç onlu adımda çözüm bulur. Geri izleme tamdır ve tüm çözümleri (8'de 92) sayabilir ama n büyüdükçe hızla yavaşlar.
Çıktı Sorusu · Sudoku
Soru 12: Kutunun Köşesi
9 × 9 Sudoku'nun gecerliMi metodundaki kutu hesabı aşağıda. Kod ne yazar? (7, 4) hücresinin kutusu hangi satır ve sütunları kapsar?
int[][] h = {{7, 4}, {2, 8}, {5, 5}}; for (int[] x : h) { int bs = x[0] / 3 * 3; int bk = x[1] / 3 * 3; System.out.print(bs + " " + bk + " "); }
Cevabı göster
Çıktı: 6 3 0 6 3 3
- Tam sayı bölmesi: 7 / 3 = 2 → 2·3 = 6; 4 / 3 = 1 → 3. (7, 4)'ün kutusu satır 6–8, sütun 3–5'tir.
- (2, 8) → (0, 6); (5, 5) → (3, 3).
s / 3 * 3, s'yi 3'ün katına aşağı yuvarlar; çarpma unutulursa (yalnızca s / 3) kutu numarası (0–2) elde edilir, indis değil. - Kutu denetimi unutulursa satır ve sütunu doğru ama kutuları geçersiz "çözümler" üretilir.
Çoktan Seçmeli · Sudoku
Soru 13: MRV Sezgiseli
Sudoku çözücüsünde MRV (minimum remaining values) sezgiseli neyi değiştirir?
D: MRV değişken sıralamasıdır: satır satır ilk boş hücre yerine en az adaylı hücre doldurulur. Tek adaylı hücreler önce dolar ve çelişkiler erkenden ortaya çıkar; dersteki bulmacada geri alma sayısı 4157'den 0'a iner. B ayrı bir iyileştirmedir (bit maskeleri).
Adım Adım Çalıştırma · Çizge Boyama ve Hamilton Yolu
Soru 14: Çizge Boyama İzleme
Kenarlar 0–1, 0–4, 1–2, 1–3, 1–4, 2–3, 3–4; m = 3. boya(0) renkleri nasıl atar, nerede geri döner?
5 düğüm, m = 3 renk (r1, r2, r3). Düğümler 0, 1, 2, … sırayla boyanır; her düğümde renk 1, 2, 3 sırayla denenir.
Düğüm 0: renk 1 uygun → atanır, boya(1).
Düğüm 1: renk 1 komşuda var; renk 2 uygun → atanır, boya(2).
Düğüm 2: renk 1 uygun → atanır, boya(3).
Düğüm 3: renk 1, 2 komşuda var; renk 3 uygun → atanır, boya(4).
Düğüm 4: denenecek renk kalmadı → return false (çıkmaz).
Geri al: düğüm 3'ün rengi (3) silinir; aynı düğümde sıradaki renk denenecek.
Düğüm 3: denenecek renk kalmadı → return false (çıkmaz).
Geri al: düğüm 2'nin rengi (1) silinir; aynı düğümde sıradaki renk denenecek.
Düğüm 2: renk 2 komşuda var; renk 3 uygun → atanır, boya(3).
Düğüm 3: renk 1 uygun → atanır, boya(4).
Düğüm 4: renk 1, 2 komşuda var; renk 3 uygun → atanır, boya(5). Beş düğüm de boyandı: geçerli 3-boyama [1, 2, 3, 1, 3].
boolean boya(int v) { if (v == n) return true; for (int c = 1; c <= m; c++) { if (uygunMu(v, c)) { // komşularda c yok renk[v] = c; if (boya(v + 1)) return true; renk[v] = 0; // geri al } } return false; }
Klasik Soru · Çizge Boyama ve Hamilton Yolu
Soru 15: Tek Uzunluklu Döngü
5 düğümlü döngü çizgesi C₅ (0–1–2–3–4–0), boya(0) ile m = 2 renkle boyanmaya çalışılıyor. Arama ne döndürür ve neden? En az kaç renk gerekir?
Cevabı göster
- Düğüm 0: renk 1 → düğüm 1: 1 komşuda var, renk 2 → düğüm 2: renk 1 → düğüm 3: renk 2 → düğüm 4: 1 (0'da) ve 2 (3'te) komşuda → çıkmaz.
- Geri dönüşler sonucu değiştirmez: 2 renkte renkler zorunlu olarak dönüşümlü gider (1, 2, 1, 2, …) ve düğüm 4 her iki renge de komşudur. Arama tüm ağacı gezip false döner; bu, çözüm olmadığının kanıtıdır (arama tamdır).
- Tek uzunluklu döngüler 3 renk ister: 1, 2, 1, 2, 3. Çift uzunluklu döngüler (iki parçalı çizgeler) 2 renkle boyanabilir.
Adım Adım Çalıştırma · Kelime Arama
Soru 16: Kelime Arama İzleme
Izgara ABCE / SFCS / ADEE. (1, 0)'dan başlayan ara çağrısı "SADE" kelimesini nasıl bulur? (ds = {−1, 1, 0, 0}, dk = {0, 0, −1, 1})
Izgara ABCE / SFCS / ADEE, kelime "SADE". ara(iz, "SADE", 0, 1, 0, ziyaret): (1, 0)'daki S'den başlanır. Yön sırası: yukarı, aşağı, sol, sağ.
(1, 0) = 'S' kelimenin 0. harfiyle eşleşti → ziyaret edildi işaretlenir, 4 komşu denenir.
(0, 0) = 'A' kelimenin 1. harfiyle eşleşti → ziyaret edildi işaretlenir, 4 komşu denenir.
(0, 0)'den hiçbir komşu 'D' ile sürmüyor (B, sınır ya da ziyaretli) → işaret kaldırılır, false.
(2, 0) = 'A' kelimenin 1. harfiyle eşleşti → ziyaret edildi işaretlenir, 4 komşu denenir.
(2, 1) = 'D' kelimenin 2. harfiyle eşleşti → ziyaret edildi işaretlenir, 4 komşu denenir.
(2, 2) = 'E' kelimenin 3. harfiyle eşleşti → ziyaret edildi işaretlenir, 4 komşu denenir.
i == 4 == kelime uzunluğu → true. Yol: (1,0) S → (2,0) A → (2,1) D → (2,2) E.
boolean ara(char[][] iz, String kelime, int i, int s, int k, boolean[][] ziyaret) { if (i == kelime.length()) return true; if (s < 0 || s >= iz.length || k < 0 || k >= iz[0].length || ziyaret[s][k] || iz[s][k] != kelime.charAt(i)) return false; ziyaret[s][k] = true; for (int d = 0; d < 4; d++) if (ara(iz, kelime, i + 1, s + ds[d], k + dk[d], ziyaret)) return true; ziyaret[s][k] = false; // geri al return false; }
Çoktan Seçmeli · Kelime Arama
Soru 17: Ziyaret İşaretini Kaldırmamak
Kelime aramada ziyaret[s][k] = false satırı unutulursa ne olur?
B: İşaret kalırsa, başarısız bir denemede geçilen hücreler sonraki denemelerde "kullanılmış" görünür; var olan bir kelime bulunamayabilir. Bir yolda aynı hücreyi iki kez kullanma (A) ise işaretin kendisiyle zaten engellenir. Önce işaretle, sonra keşfet, en sonda işareti kaldır: seç → keşfet → geri al.
Çoktan Seçmeli · Analiz
Soru 18: Karmaşıklık
Geri izlemede en kötü durum karmaşıklıkları için hangi eşleştirme doğrudur?
C: Sudoku'da m boş hücrenin her biri 9 aday alır: 9ᵐ. m-boyamada n düğümün her biri m renk alır, denetim düğüm başına O(n): O(n · mⁿ). N vezir O(n!), Hamilton yolu O(n · n!), kelime arama O(R · C · 3ᴸ); alt kümeler O(2ⁿ), permütasyonlar O(n · n!). Bellek ise yalnızca O(derinlik)'tir.