Bölüm 10: Dal Sınır Algoritmaları
Çoktan Seçmeli · Paradigma
Soru 1: Dal Sınırın Farkı
Dal sınır yöntemini geri izlemeden ayıran budama kuralı hangisidir (en büyükleme)?
B: Geri izleme yalnızca olursuzluk ve tamlık kurallarını kullanır. Dal sınır, düğüm geçerli olsa bile sinir(u) ≤ enİyi ise onu keser: altındaki hiçbir çözüm en iyiyi geçemez. Sınır testi olmayan bir TSP ya da klik araması aslında geri izlemedir.
Çoktan Seçmeli · Sınır
Soru 2: Geçerli Sınır
En büyükleme probleminde u düğümü için hesaplanan sinir(u) değerinin geçerli olması ne demektir ve geçerli olmazsa ne olur?
C: Sınır iyimser olmalıdır: alt ağaçtaki hiçbir çözüm onu geçemez. Sınır gerçek değerin altında kalırsa optimumu içeren dal "yeterince iyi değil" diye budanabilir ve sonuç yanlış olur. Sınırın sıkı ve ucuz olması ise verimlilikle ilgilidir; gerçek optimuma eşit olması gerekmez (o zaman problem zaten çözülmüş olurdu).
Çoktan Seçmeli · Sınır
Soru 3: Kötümser Sınır
Bir öğrenci sırt çantası için sınırı "kalan eşyalardan tamamen sığanların kazancını ekle, kesirli parçayı ekleme" diye hesaplıyor. Bu sınır için hangisi doğrudur?
D: Bu değer açgözlü bir 0/1 çözümün kazancıdır, yani bir alt sınırdır: gerçek optimumun altında kalabilir. (p, w) = (20, 2), (30, 5), (35, 7), (12, 3), W = 9 örneğinde kökte 20 + 30 = 50 verir ama optimum 55'tir; enİyi 50 iken bu "sınır" optimumun dalını keser. Üst sınır, kesirli gevşetme gibi iyimser bir değer olmalıdır.
Çoktan Seçmeli · Arama Stratejileri
Soru 4: Bellek Kısıtlı Strateji
Belleği çok kısıtlı bir sistemde dal sınır için hangi arama stratejisi seçilmelidir?
A: LIFO (DFS) yalnızca geçerli yolun kardeş düğümlerini tutar: bellek O(derinlik · dallanma). FIFO ve en iyi önce stratejilerinde canlı düğüm sayısı üstel büyüyebilir. En iyi önce genellikle en az düğümü genişletir ama kuyruğu bellek tüketir; LIFO erken bir tam çözümle enİyi'yi de hızla yükseltir.
Çıktı Sorusu · Arama Stratejileri
Soru 5: FIFO Dal Sınır
Dersteki sırt çantası örneği: (p, w) = (40, 2), (30, 5), (50, 10), (10, 5), W = 16. En iyi önce kodundaki öncelikli kuyruk ArrayDeque ile değiştirilip add()/poll() kullanılıyor (FIFO). Program ne yazar (enİyi, üretilen, genişletilen)?
Deque<Dugum> kuyruk = new ArrayDeque<>(); kuyruk.add(kok); while (!kuyruk.isEmpty()) { Dugum u = kuyruk.poll(); // ilk giren if (u.sinir <= enIyi || u.seviye == n - 1) continue; gen++; // al ve alma: aynı kod (uretilen += 2) } System.out.println( enIyi + " " + uretilen + " " + gen);
Cevabı göster
Çıktı: 90 13 6
- FIFO düğümleri seviye seviye (BFS) genişletir: önce kökün iki çocuğu, sonra onların çocukları…
- En iyi önce aynı örnekte 11 düğüm üretip 5'ini genişletir; FIFO en büyük sınırlı düğümü beklemediği için daha fazla düğüm açar.
- Optimum yine 90'dır (eşya 1 ve 3): strateji yalnızca iş miktarını ve belleği değiştirir.
Adım Adım Çalıştırma · 0/1 Sırt Çantası
Soru 6: sinir(kök) İzleme
Eşyalar (p, w): (20, 2), (30, 5), (35, 7), (12, 3); W = 9. Kök düğüm için kesirli sınır nasıl hesaplanır?
Eşyalar oran sırasında: (20, 2) 10 · (30, 5) 6 · (35, 7) 5 · (12, 3) 4; W = 9. Kök: seviye −1, kazanç 0, ağırlık 0 ≤ 9 → olurlu.
Sınır mevcut kazançtan başlar; j = seviye + 1 = 0 (eşya 1).
0 + w[0] = 2 ≤ 9 → eşya 1 tamamen sığar: toplamAg = 2, sonuc = 20.
2 + w[1] = 7 ≤ 9 → eşya 2 de sığar: toplamAg = 7, sonuc = 50.
7 + w[2] = 14 > 9 → eşya 3 tamamen sığmaz, döngü biter.
Kalan kapasite 2: eşya 3'ün 2/7'si → 2 · 35/7 = 10 eklenir, sonuc = 60.
sinir(kök) = 60: hiçbir 0/1 çözüm 60'tan fazla kazandıramaz. Gerçek optimum 55'tir (eşya 1 + 3, ağırlık 9).
double sinir(Dugum u) { if (u.agirlik > W) return 0; // olursuz double sonuc = u.kazanc; int toplamAg = u.agirlik; int j = u.seviye + 1; while (j < n && toplamAg + w[j] <= W) { toplamAg += w[j]; sonuc += p[j]; j++; } if (j < n) // kesirli sonuc += (W - toplamAg) * (double) p[j] / w[j]; return sonuc; }
Çıktı Sorusu · 0/1 Sırt Çantası
Soru 7: Diğer Düğümlerin Sınırı
Eşyalar (p, w): (20, 2), (30, 5), (35, 7), (12, 3); W = 9. Şu düğümlerin sınırlarını hesaplayın: C = "eşya 1 alınmadı" (seviye 0, kazanç 0, ağırlık 0) ve E = "eşya 1 alındı, eşya 2 alınmadı" (seviye 1, kazanç 20, ağırlık 2). Oranla açgözlü seçim ve optimum kaçtır; C budanır mı?
Cevabı göster
- sinir(C) = 50: eşya 2 sığar (30, ağırlık 5); eşya 3 sığmaz, kalan 4 birim → 4 · 35/7 = 20 → 30 + 20 = 50.
- sinir(E) = 55: 20 + eşya 3 (35, ağırlık 9) = 55; kapasite tam doldu, eşya 4 için kesir 0.
- Açgözlü (oran sırası) 1 ve 2'yi alır: 50 (ağırlık 7); 3 ve 4 sığmaz. Optimum 1 + 3 = 55.
- enİyi = 55 bulunduktan sonra sinir(C) = 50 ≤ 55 → C budanır: eşya 1'siz hiçbir çözüm 55'i geçemez.
Adım Adım Çalıştırma · 0/1 Sırt Çantası
Soru 8: En İyi Önce Dal Sınır
Eşyalar (p, w): (20, 2), (30, 5), (35, 7), (12, 3); W = 9. En iyi önce (LC) dal sınır hangi düğümleri hangi sırayla genişletir?
Kök A: kazanç 0, ağırlık 0, sinir = 60. Kuyruk (en büyük sınır önce): A (60); enİyi = 0. Etiketlerin yanındaki sayı sınırdır.
A çıkarıldı (en büyük sınır) ve dallandı; enİyi = 20. B (eşya 1 alındı): s = 60 → kuyruğa; C (eşya 1 yok): s = 50 → kuyruğa.
B çıkarıldı (en büyük sınır) ve dallandı; enİyi = 50. D (eşya 2 alındı): s = 60 → kuyruğa; E (eşya 2 yok): s = 55 → kuyruğa.
D çıkarıldı (en büyük sınır) ve dallandı; enİyi = 50. F (eşya 3 alındı): ağırlık 14 > 9 → olursuz; G (eşya 3 yok): s = 58 → kuyruğa.
G çıkarıldı (en büyük sınır) ve dallandı; enİyi = 50. H (eşya 4 alındı): ağırlık 10 > 9 → olursuz; I (eşya 4 yok): s = 50 ≤ 50 → budandı.
E çıkarıldı (en büyük sınır) ve dallandı; enİyi = 55. J (eşya 3 alındı): s = 55 ≤ 55 → budandı; K (eşya 3 yok): s = 32 ≤ 55 → budandı.
C çıkarıldı: sinir = 50 ≤ enİyi = 55 → budandı (beklerken eskidi). Kuyruk boş: en iyi kazanç 55. Tam ağacın 31 düğümünden 11'i üretildi, 5'i genişletildi.
Dugum u = kuyruk.poll(); // en büyük sınır if (u.sinir <= enIyi || u.seviye == n - 1) continue; int i = u.seviye + 1; Dugum al = new Dugum(i, u.kazanc + p[i], u.agirlik + w[i]); if (al.agirlik <= W && al.kazanc > enIyi) enIyi = al.kazanc; al.sinir = sinir(al); if (al.sinir > enIyi) kuyruk.add(al); Dugum alma = new Dugum(i, u.kazanc, u.agirlik); alma.sinir = sinir(alma); if (alma.sinir > enIyi) kuyruk.add(alma);
Çoktan Seçmeli · 0/1 Sırt Çantası
Soru 9: Kuyruktan Çıkınca Tekrar Sına
En iyi önce kodunda poll() sonrasında if (u.sinir <= enIyi) continue; testi neden yapılır? Düğüm kuyruğa eklenirken zaten sınanmıştı.
B: Sınır değişmez; değişen enİyi'dir. W = 9'luk sırt çantası örneğinde C düğümü (sınır 50) eklenirken enİyi 20'ydi; çıkarıldığında enİyi 55 olmuştu ve C hiç genişletilmeden atıldı. Test yapılmasa sonuç yine doğru olur, ama gereksiz düğümler genişletilir.
Adım Adım Çalıştırma · Gezgin Satıcı
Soru 10: TSP Dal Sınır İzleme
Simetrik uzaklıklar: d(0,1) = 4, d(0,2) = 9, d(0,3) = 5, d(1,2) = 3, d(1,3) = 7, d(2,3) = 6. tsp(0, 0, 1) hangi dalları açar, hangilerini budar?
Şehir 0'dan başlanır. Her şehrin en ucuz çıkış kenarı enKucuk = [4, 3, 3, 5]; kök alt sınırı 4 + 3 + 3 + 5 = 15.
0 → 1: yeni = 4; alt = 15 < ∞ → dallan.
1 → 2: yeni = 7; alt = 15 < ∞ → dallan.
2 → 3: yeni = 13; alt = 18 < ∞ → dallan.
Tur 0 → 1 → 2 → 3 → 0 = 18 < ∞ → enİyi = 18.
1 → 3: yeni = 11; alt = 19 ≥ enİyi = 18 → budandı.
0 → 2: yeni = 9; alt = 20 ≥ enİyi = 18 → budandı.
0 → 3: yeni = 5; alt = 16 < 18 → dallan.
3 → 1: yeni = 12; alt = 18 ≥ enİyi = 18 → budandı.
3 → 2: yeni = 11; alt = 17 < 18 → dallan.
2 → 1: yeni = 14; alt = 17 < 18 → dallan.
Tur 0 → 3 → 2 → 1 → 0 = 18 = enİyi; güncellenmez. Bitti: en kısa tur 18 (0 → 1 → 2 → 3 → 0).
void tsp(int sehir, int maliyet, int sayac) { if (sayac == n) { // tur tamam int tur = maliyet + d[sehir][0]; if (tur < enIyi) enIyi = tur; return; } for (int s = 0; s < n; s++) { if (ziyaret[s]) continue; int yeni = maliyet + d[sehir][s]; ziyaret[s] = true; if (altSinir(s, yeni) < enIyi) // sınır tsp(s, yeni, sayac + 1); ziyaret[s] = false; // geri al } }
Çoktan Seçmeli · Gezgin Satıcı
Soru 11: TSP Alt Sınırının Geçerliliği
alt(yol) = maliyet(yol) + enKucuk[son şehir] + Σ enKucuk[ziyaret edilmemiş] sınırı neden geçerlidir?
D: Turu tamamlamak için son şehirden ve ziyaret edilmemiş her şehirden tam bir kez çıkılır; her çıkış en az o şehrin en ucuz kenarı kadar tutar. Bu yüzden hiçbir tamamlanmış tur alt(yol)'dan ucuz olamaz. Sınır gerçek değere eşit olmak zorunda değildir; A en yakın komşu sezgiselidir ve bir üst değer verir.
Klasik Soru · Gezgin Satıcı
Soru 12: İki En Kısa Kenar Sınırı
Simetrik uzaklıklar: d(0,1) = 4, d(0,2) = 9, d(0,3) = 5, d(1,2) = 3, d(1,3) = 7, d(2,3) = 6. Bu 4 şehirli örnekte "her şehrin iki en kısa kenarının toplamının yarısı" kök alt sınırını hesaplayın. Her şehrin en ucuz çıkış kenarlarının toplamı olan sınırla (15) karşılaştırın.
Cevabı göster
| şehir | iki en kısa kenar | toplam |
|---|---|---|
| 0 | 4, 5 | 9 |
| 1 | 3, 4 | 7 |
| 2 | 3, 6 | 9 |
| 3 | 5, 6 | 11 |
(9 + 7 + 9 + 11) / 2 = 36 / 2 = 18. Her şehre bir kenarla girilir, bir kenarla çıkılır; her kenar iki şehirde sayıldığı için toplam 2'ye bölünür.
Bu sınır optimuma (18) eşittir: kökte bile ilk tur bulununca tüm dallar budanabilir. En ucuz çıkış sınırı 15 ile daha gevşektir. Sıkı sınır daha çok budar ama her düğümde biraz daha pahalıdır.
Adım Adım Çalıştırma · Atama Problemi
Soru 13: Atama Problemi İzleme
Maliyet matrisi [[9, 2, 7], [6, 4, 3], [5, 8, 1]] (satır: kişi, sütun: iş). ata(0, 0) hangi dalları açar, hangilerini budar?
Kişi i'ye iş j'nin maliyeti c[i][j]. Satır en küçükleri 2, 3, 1 → kalanMin = [6, 4, 1, 0] (i. satırdan sonuna). Kök alt sınırı 6.
Kişi 0 → iş 0: yeni = 9, alt = 9 + kalanMin[1] = 13 < ∞ → dallan.
Kişi 1 → iş 1: yeni = 13, alt = 13 + kalanMin[2] = 14 < ∞ → dallan.
Kişi 2 → iş 2: yeni = 14, alt = 14 + kalanMin[3] = 14 < ∞ → dallan.
Tam atama [0, 1, 2], maliyet 14 → enİyi = 14.
Kişi 1 → iş 2: yeni = 12, alt = 12 + kalanMin[2] = 13 < 14 → dallan.
Kişi 2 → iş 1: alt = 20 ≥ enİyi = 14 → budandı.
Kişi 0 → iş 1: yeni = 2, alt = 2 + kalanMin[1] = 6 < 14 → dallan.
Kişi 1 → iş 0: yeni = 8, alt = 8 + kalanMin[2] = 9 < 14 → dallan.
Kişi 2 → iş 2: yeni = 9, alt = 9 + kalanMin[3] = 9 < 14 → dallan.
Tam atama [1, 0, 2], maliyet 9 → enİyi = 9.
Kişi 1 → iş 2: yeni = 5, alt = 5 + kalanMin[2] = 6 < 9 → dallan.
Kişi 2 → iş 0: alt = 10 ≥ enİyi = 9 → budandı.
Kişi 0 → iş 2: alt = 11 ≥ enİyi = 9 → budandı. Bitti: en iyi atama [1, 0, 2] (2 + 6 + 1), maliyet 9.
void ata(int i, int maliyet) { // i. kişi if (i == n) { enIyi = Math.min(enIyi, maliyet); return; } for (int j = 0; j < n; j++) { if (atandi[j]) continue; int yeni = maliyet + c[i][j]; if (yeni + kalanMin[i + 1] >= enIyi) continue; // sınır atandi[j] = true; ata(i + 1, yeni); atandi[j] = false; // geri al } }
Çıktı Sorusu · Atama Problemi
Soru 14: 4 × 4 Atama
Dal sınırla çalışan ata metodu (yeni + kalanMin[i + 1] ≥ enİyi ise dal kesilir; çağrı sayacı ve tam atama sayacı eklenmiş) aşağıdaki matrisle çalıştırılıyor. Kök alt sınırı (kalanMin[0]) nedir; program ne yazar?
int[][] c = {{7, 3, 8, 4}, {5, 6, 2, 9}, {4, 8, 5, 3}, {6, 2, 7, 5}}; // kalanMin: satır en küçüklerinin sonek toplamı ata(0, 0); System.out.println(kalanMin[0] + " " + enIyi + " " + cagri + " " + tam);
Cevabı göster
Çıktı: 10 12 21 4 (kalanMin[0], enIyi, çağrı, tam atama).
- Satır en küçükleri 3, 2, 3, 2 → kök alt sınırı 10. Sınır geçerlidir: her kişi en az kendi en ucuz işi kadar tutar.
- En iyi atama: kişi 0 → iş 3 (4), 1 → iş 2 (2), 2 → iş 0 (4), 3 → iş 1 (2) = 12.
- Kaba kuvvet 4! = 24 tam atama dener; dal sınır 21 çağrıda yalnızca 4 tam atamaya ulaşır.
Klasik Soru · Tam Sayılı Programlama
Soru 15: ILP Dal Sınır Ağacı
En büyükle Z = 5x + 8y; x + y ≤ 6, 5x + 9y ≤ 45, x, y ≥ 0 tam sayı. LP gevşetmeleriyle dal sınır uygulayın (önce y, sonra x kesirliyse onda dallanın). Optimum nedir? LP çözümünü yuvarlamak neden yetmez?
Cevabı göster
| düğüm | LP çözümü (x; y) | Z | karar |
|---|---|---|---|
| kök | (2,25; 3,75) | 41,25 | y kesirli → y ≤ 3 | y ≥ 4 |
| y ≤ 3 | (3; 3) | 39 | tam sayı → enİyi = 39 |
| y ≥ 4 | (1,8; 4) | 41 | x kesirli → x ≤ 1 | x ≥ 2 |
| y ≥ 4, x ≤ 1 | (1; 4,44) | 40,56 | y kesirli → y ≤ 4 | y ≥ 5 |
| … y ≤ 4 | (1; 4) | 37 | 37 ≤ 39 → budandı |
| … y ≥ 5 | (0; 5) | 40 | tam sayı, 40 > 39 → enİyi = 40 |
| y ≥ 4, x ≥ 2 | — | — | olursuz |
Optimum x = 0, y = 5, Z = 40. Yuvarlama: (2; 4) olursuzdur (5·2 + 9·4 = 46 > 45), (2; 3) ise Z = 34'tür; gerçek optimum LP noktasından uzaktadır. LP değeri (41,25) her alt ağaç için üst sınırdır.
Çoktan Seçmeli · Tam Sayılı Programlama
Soru 16: Kesirli Değişkende Dallanma
Bir ILP düğümünde LP gevşetmesinin çözümü y = 2,6 veriyor. Dal sınır hangi iki alt problemi üretir ve neden hiçbir tam sayı çözüm kaybolmaz?
A: Dallanma kesirli bölgeyi (2, 3) atar; tam sayı noktaların hepsi iki alt problemden birinde kalır. B kalan y değerlerini kaybeder; C mevcut LP çözümünü iki alt problemde de bırakır (ilerleme olmaz); D'de alt problemler örtüşür. Her alt problemin LP değeri o dal için bir üst sınırdır.
Çıktı Sorusu · Maksimum Klik
Soru 17: Klik Sınırının Kazancı
Kenarlar 0–1, 0–2, 1–2, 1–3, 2–3, 3–4, 2–4, 1–4. Dersteki klik metodu sınır satırıyla ve sınır satırı silinerek çalıştırılıyor; her çağrıda bir sayaç artıyor. En büyük klik ve iki sürümün çağrı sayıları nedir?
Cevabı göster
- En büyük klik: {1, 2, 3, 4} (4 düğüm; her çift komşu).
- Sınırsız (geri izleme): 20 çağrı; |K| + |aday| ≤ |enİyi| sınırıyla: 15 çağrı.
- enİyi = {1, 2, 3, 4} bulunduktan sonra K = {2}, aday = {3, 4} gibi dallar 1 + 2 ≤ 4 olduğu için hemen kesilir: bu daldan 4'ten büyük klik çıkamaz.
Çoktan Seçmeli · Maksimum Klik
Soru 18: Dal Sınır Gerekmeyen Problem
Aşağıdaki problemlerden hangisi için dal sınır yöntemine gerek yoktur?
C: Maksimum akışın polinom zamanlı algoritmaları vardır (Ford-Fulkerson, Edmonds-Karp). Dal sınır NP-zor eniyileme problemleri (TSP, 0/1 sırt çantası, maksimum klik, ILP) için anlamlıdır; en kötü durumda yine üstel çalışır ama iyi bir sınırla pratikte çok az düğüm gezer.