Bölüm 10: Dal Sınır Algoritmaları

Algoritmalar
Durum uzayı ağacıSınırlama ve budamaFIFO, LIFO, en düşük maliyet0/1 sırt çantası Gezgin satıcıTam sayılı programlamaMaksimum klikParadigmaların karşılaştırması
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Paradigma

Dal sınır yönteminin durum uzayı ağacı, dallanma, sınırlama ve budama adımlarını açıklamak; geri izlemeden farkını söylemek.

Sınır tasarımı

En büyükleme için üst, en küçükleme için alt sınır kurmak; sınırın geçerli (iyimser) olmasının neden şart olduğunu gerekçelendirmek.

Arama stratejileri

FIFO, LIFO ve en düşük maliyet (en iyi önce) stratejilerini aynı örnekte izlemek; bellek ve düğüm sayısı açısından karşılaştırmak; tasarım paradigmalarını birbirinden ayırt etmek.

Uygulamalar

0/1 sırt çantası, gezgin satıcı, tam sayılı doğrusal programlama ve maksimum klik problemlerini dal sınır ile adım adım çözmek.

Giriş

En İyi Seçenekleri Ele Almak

  • Karmaşık problemleri çözmek, bazen bir yol ayrımında doğru seçeneği bulmaya benzer.
  • Dal sınır (branch and bound) algoritmaları bu problemler için akıllı bir yaklaşım sunar: olası çözüm yollarını inceleyerek en iyi seçeneği bulmaya çalışır.
  • Hedef: kombinatoryal optimizasyon problemlerinde kesin (optimal) çözüm. Tüm adayları denemek ise üstel ya da faktöriyel sürer.
  • Fikir: bir dalın en fazla ne kadar iyi olabileceğini önceden tahmin et; yeterince iyi değilse o dala hiç girme.
n2ⁿ alt küme(n−1)! tur
53224
101 024362 880
201 048 576≈ 1,2 · 10¹⁷
40≈ 1,1 · 10¹²≈ 2,0 · 10⁴⁶

Sırt çantası 2ⁿ alt kümeyi, gezgin satıcı (n−1)! turu dener: kaba kuvvet hızla imkânsızlaşır.

Giriş

Dal Sınır Algoritmaları

  • Dallanıp budanan bir ağaç gibi düşünülebilir.
  • Önce problem daha küçük alt problemlere ayrılır (dallanma, branching).
  • Her alt problem için ulaşılabilecek en iyi değer tahmin edilir (sınır, bound).
  • Sınırı, o ana kadar bulunan en iyi çözümden daha iyi olmayan olasılıklar elenir (budama, pruning).
  • İşlem kalan tüm alt problemler için tekrarlanır; gereksiz dallar budandıkça arama süresi kısalır.
  • Gezgin satıcı, sırt çantası, çizelgeleme gibi birçok alanda kullanılır.
✗✗✗en iyibudandı
Budanan düğümün (✗) alt ağacı hiç üretilmez.

Giriş

Temel Kavramlar

Durum uzayı ağacıKök = hiçbir karar verilmemiş durum; her seviye bir karar (ör. "eşya i alınsın mı?"); yapraklar tam çözümler.
DallanmaBir düğümün alt problemlerini (çocuklarını) üretmek. Genişletilen düğüme E-düğüm (expanding node) denir.
SınırDüğümün altındaki hiçbir çözümün geçemeyeceği iyimser değer: en büyüklemede üst, en küçüklemede alt sınır.
Canlı düğümÜretilmiş ama henüz genişletilmemiş, umut vaat eden düğüm. Hepsi bir kuyruk yapısında bekler.
Ölü düğümGenişletilmiş, olursuz ya da sınırı yetersiz olduğu için budanmış düğüm; bir daha ele alınmaz.
enİyi (incumbent)Şimdiye kadar bulunan en iyi tam çözümün değeri. Budama kararları bu değere göre verilir.
ölü (genişletildi)E-düğüm✗ sınır ≤ enİyienİyi (tam çözüm)canlı (kuyrukta)✗ olursuz

Paradigma

Genel Şema (En Büyükleme)

int enIyi = -∞;
kuyruk.ekle(kök);
while (!kuyruk.bosMu()) {
  Dugum u = kuyruk.cikar();   // strateji
  if (sinir(u) <= enIyi) continue;
  for (Dugum c : u.cocuklar()) {
    if (!olurluMu(c)) continue;
    if (tamCozumMu(c) && deger(c) > enIyi)
      enIyi = deger(c);      // yeni aday
    if (sinir(c) > enIyi)
      kuyruk.ekle(c);        // canlı düğüm
  }
}
return enIyi;
  1. Seç: kuyruktan bir canlı düğüm çıkar. Hangisinin çıkacağını strateji belirler (FIFO, LIFO, en iyi sınır).
  2. Tekrar sına: düğüm beklerken enİyi büyümüş olabilir; sınırı artık yetersizse at.
  3. Dallan: çocukları üret; olursuzları ele.
  4. Güncelle: tam çözüm daha iyiyse enİyi'yi yükselt.
  5. Sınırla: yalnızca sınırı enİyi'yi geçebilen çocukları kuyruğa koy.
kuyruktan u çıkarsinir(u) ≤ enİyi?çocukları üretolurlu? tam? sınır?canlıyı kuyruğa ekleevet → at (tekrar sına)olursuz / sınır ≤ enİyi → budakuyruk boşalana kadar

En küçüklemede yönler ters çevrilir: alt sınır kullanılır, alt(c) ≥ enIyi ise budanır.

Paradigma

Sınır (Bound) Nasıl Seçilir?

Geçerli (iyimser) olmalıEn büyüklemede sınır(u) ≥ alt ağaçtaki her çözüm; en küçüklemede alt(u) ≤ her çözüm. Aksi hâlde optimum budanabilir ve sonuç yanlış olur.
Sıkı olmalıGerçek değere ne kadar yakınsa o kadar çok dal budanır. Sonsuz büyük bir "sınır" geçerlidir ama hiçbir şey budamaz.
Ucuz hesaplanmalıSınır her düğümde hesaplanır. Çok pahalı bir sınır, budadığı düğümlerden daha fazla zaman harcatabilir.
Gevşetme (relaxation) ile kurulurZor bir kısıtı kaldırıp kolay problemi çöz: kesirli sırt çantası, LP gevşetmesi, en ucuz çıkış kenarları.
Başarı büyük ölçüde iyi bir sınır tahminine bağlıdır. En küçüklemede alt sınır, en iyi senaryoda elde edilebilecek minimum değerdir; zayıf bir alt sınır arama süresini uzatır.

Paradigma

Bir Düğüm Ne Zaman Budanır?

1. OlursuzlukDüğüm bir kısıtı ihlal ediyor: ağırlık > kapasite, aynı şehre ikinci ziyaret, LP'nin çözümü yok. Altında hiçbir geçerli çözüm yoktur.
2. Sınırsinir(u) ≤ enİyi (en büyükleme) ya da alt(u) ≥ enİyi (en küçükleme). Altındaki çözümler en iyiyi geçemez.
3. TamlıkDüğüm tam bir çözüm (yaprak) ya da gevşetmenin çözümü zaten olurlu (ör. LP çözümü tam sayı). Değeri enİyi ile karşılaştırılır; dallanmaya gerek kalmaz.

Geri izleme yalnızca 1. kuralı (ve tamlığı) kullanır. Dal sınırı ondan ayıran şey 2. kuraldır: düğüm geçerli olsa bile "yeterince iyi değilse" kesilir.

Paradigma

Arama Stratejileri: Sıradaki Canlı Düğüm Hangisi?

StratejiKuyrukNasıl gezer?Artı / eksi
FIFO dal sınırkuyruk (ArrayDeque)seviye seviye, genişlik öncelikli (BFS)sığ çözümleri erken bulur; canlı düğüm sayısı üstel büyüyebilir
LIFO dal sınıryığın (ya da özyineleme)derinlik öncelikli (DFS)bellek O(derinlik); erken bir tam çözüm enİyi'yi hızla yükseltir
En düşük maliyet (LC, en iyi önce)öncelikli kuyruk (PriorityQueue)sınırı en umut verici düğüm öncegenellikle en az düğümü genişletir; kuyruk bellek tüketir, her işlem O(log k)
  • Üç strateji de aynı optimumu bulur; değişen, üretilen düğüm sayısı ve bellektir.
  • LC aramada maliyet fonksiyonu ĉ(u) = sınır değeri (ya da f(u) + ĝ(u) tahmini) olur; A* araması bu fikrin yol bulmadaki karşılığıdır.

Paradigma

En Düşük Maliyetli (LC) Arama: ĉ(x) = f(x) + ĝ(x)

  • f(x): köke uzaklık (buraya kadar ödenen maliyet); ĝ(x): x'ten bir çözüme kalan maliyetin tahmini.
  • Canlı düğümlerden ĉ'si en küçük olan genişletilir. ĝ = 0 seçilirse FIFO'ya, f = 0 seçilirse açgözlü derinlik aramasına yaklaşır.
  • 8 bulmacasında ĝ = yerinde olmayan taş sayısı: her yanlış taş en az bir hamle ister, bu yüzden ĝ hiçbir zaman fazla tahmin etmez.
  • Başlangıçta 5 ve 8 yanlış yerde (ĝ = 2). En küçük ĉ'li çocuk “boşluk aşağı”; onun çocuğu “boşluk sağa” hedefe ulaşır: 2 hamle, yalnız 2 genişletme.
12346758ĉ = 0 + 213426758boşluk yukarıĉ = 1 + 3 = 412345678boşluk aşağıĉ = 1 + 1 = 212346758boşluk solaĉ = 1 + 3 = 412346758boşluk sağaĉ = 1 + 3 = 4
Hedef: 1 2 3 / 4 5 6 / 7 8 boşluk. Turuncu: hareket eden taş.

Paradigma

Geri İzleme ve Dal Sınır

ÖzellikGeri izlemeDal sınır
Problem türükarar / arama: bir ya da tüm geçerli çözümler (N-vezir, Sudoku)optimizasyon: en iyi çözüm (en büyük kazanç, en kısa tur)
Budama ölçütüolurluluk: kısıt ihlal ediliyor mu?olurluluk + sınır: enİyi'yi geçebilir mi?
Gezinmeher zaman DFS (özyineleme)DFS, BFS ya da en iyi önce
Ek bilgiyalnızca kısmi çözümkısmi çözüm + sınır fonksiyonu + enİyi
BellekO(derinlik)DFS'te O(derinlik); BFS/LC'de kuyruk boyu kadar
En kötü durumüstelyine üstel; pratikte çok daha az düğüm

Sınır testi olmayan bir TSP ya da maksimum klik araması aslında geri izlemedir; tek bir sınır satırı eklenince dal sınıra dönüşür.

Paradigma

Avantajlar ve Dezavantajlar

Avantajlar

  • Karmaşık optimizasyon problemlerinde kesin en iyi çözümü bulur.
  • Arama alanını daraltır, gereksiz olasılıkları eler.
  • En iyi rotayı ya da seçimi bulmayı gerektiren problemlerde idealdir.
  • Çözümleri ağaç olarak temsil edilebilen çok çeşitli problemlere uygulanır.
  • Erken durdurulursa elde iyi bir çözüm ve onun sınırı (kalite garantisi) bulunur.

Dezavantajlar

  • Çok fazla olasılık içeren durumlarda çözüm süresi artabilir: en kötü durumda üstel zaman.
  • FIFO ve en iyi önce stratejilerinde bellek de üstel büyüyebilir.
  • Başarı, iyi bir sınır tahminine bağlıdır; zayıf sınır neredeyse hiç budamaz.
  • Probleme özgü sınır ve dallanma kuralı tasarlamak gerekir; uygulaması geri izlemeden karmaşıktır.

0/1 Sırt Çantası

Örnek: 0/1 Sırt Çantası Problemi

  • Gösterim: kazanç pᵢ, ağırlık wᵢ, kapasite W, karar xᵢ ∈ {0, 1}; Σ wᵢxᵢ ≤ W koşuluyla Σ pᵢxᵢ en büyüklenir.
  • Eşyalar pᵢ/wᵢ oranına göre azalan sırada dizilir; sınır hesabı bu sırayı kullanır.
  • Durum uzayı ağacı ikilidir: i. seviyede sol dal "eşya i alındı" (1), sağ dal "alınmadı" (0). Tam ağaç 2⁵ − 1 = 31 düğüm.
eşya 1eşya 2eşya 3eşya 41 = al0 = alma
Eşyapᵢwᵢpᵢ/wᵢ
140220
23056
350105
41052

Kapasite W = 16.

Optimum: eşya 1 ve 3, kazanç 90 (ağırlık 12). Dal sınır bu sonuca 31 düğümün tamamını üretmeden ulaşır.

0/1 Sırt Çantası

Üst Sınır: Kesirli Sırt Çantası Gevşetmesi

  • Gevşetme: "eşya bölünemez" kısıtını kaldır. Kesirli sırt çantasını açgözlü yöntem en iyi şekilde çözer.
  • u düğümünde (kazanç k, ağırlık a, seviye i): kalan eşyaları oran sırasıyla, sığdığı kadar tam ekle; ilk sığmayan eşyanın kesirli parçasını ekle:
sinir(u) = k + Σj = i+1m−1 pⱼ + (W − a − Σ wⱼ) · pm / wm    (m: ilk sığmayan eşya)
Neden geçerli?Her 0/1 çözüm aynı zamanda bir kesirli çözümdür. Kesirli optimum ≥ 0/1 optimum, yani sınır asla gerçek en iyiyi küçük göstermez.
Kök için40 + 30 = 70 (ağırlık 7); eşya 3 sığmaz, kalan 9 birim → 9 · 50/10 = 45. sinir(kök) = 115. a > W ise düğüm olursuzdur (sınır 0).

0/1 Sırt Çantası · Kodu adım adım çalıştır

sinir(kök): Kodu Adım Adım İzle

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 parça
    sonuc += (W - toplamAg) * (double) p[j] / w[j];
  return sonuc;
}
kapasite W = 160481216henüz eşya yok

Kök düğüm: seviye −1, kazanç 0, ağırlık 0. 0 ≤ 16 olduğundan düğüm olurlu.

kapasite W = 160481216j = 0: sırada eşya 1

Sınır mevcut kazançtan başlar; j bir sonraki eşyayı gösterir (indis 0 = eşya 1).

kapasite W = 1604812160 + 2 ≤ 16 ?

0 + w[0] = 2 ≤ 16 → eşya 1 tamamen sığar.

kapasite W = 1610481216eşya 1 eklendi

toplamAg = 2, sonuc = 40, j = 1.

kapasite W = 16104812162 + 5 ≤ 16 ?

2 + w[1] = 7 ≤ 16 → eşya 2 de tamamen sığar.

kapasite W = 16120481216eşya 2 eklendi

toplamAg = 7, sonuc = 70, j = 2.

kapasite W = 161204812167 + 10 = 17 > 16

7 + w[2] = 17 > 16 → eşya 3 tamamen sığmaz, döngü biter.

kapasite W = 16123 (9/10)0481216kalan 9 birim: eşya 3’ün 9/10’u

Kalan kapasite 9: eşya 3’ün 9/10’u → 9 · 50/10 = 45 eklenir, sonuc = 115.

kapasite W = 16123 (9/10)0481216sinir(A) = 115

sinir(A) = 115: bu düğümün altındaki hiçbir çözüm 115’ten fazla kazandıramaz.

0/1 Sırt Çantası · Adım adım

En İyi Önce (LC) Dal Sınır: Durum Uzayı Ağacı

kökeşya 1(40, 2)eşya 2(30, 5)eşya 3(50, 10)eşya 4(10, 5)A0 / 0s = 115

Kök A: hiçbir eşya seçilmedi (kazanç 0, ağırlık 0). Kesirli sınır s = 115; enİyi = 0. Kuyruk: A (115).

kökeşya 1(40, 2)eşya 2(30, 5)eşya 3(50, 10)eşya 4(10, 5)10A0 / 0s = 115B40 / 2s = 115C0 / 0s = 82

A çıkarıldı (en büyük sınır) ve dallandı. B (eşya 1 alındı): enİyi = 40, s = 115 → kuyruğa. C (eşya 1 yok): s = 82 → kuyruğa. Kuyruk: B (115), C (82).

kökeşya 1(40, 2)eşya 2(30, 5)eşya 3(50, 10)eşya 4(10, 5)1010A0 / 0s = 115B40 / 2s = 115C0 / 0s = 82D70 / 7s = 115E40 / 2s = 98

B çıkarıldı (en büyük sınır) ve dallandı. D (eşya 2 alındı): enİyi = 70, s = 115 → kuyruğa. E (eşya 2 yok): s = 98 → kuyruğa. Kuyruk: D (115), E (98), C (82).

kökeşya 1(40, 2)eşya 2(30, 5)eşya 3(50, 10)eşya 4(10, 5)101010A0 / 0s = 115B40 / 2s = 115C0 / 0s = 82D70 / 7s = 115E40 / 2s = 98F120 / 17olursuzG70 / 7s = 80

D çıkarıldı (en büyük sınır) ve dallandı. F (eşya 3 alındı): ağırlık 17 > 16 → olursuz. G (eşya 3 yok): s = 80 → kuyruğa. Kuyruk: E (98), C (82), G (80).

kökeşya 1(40, 2)eşya 2(30, 5)eşya 3(50, 10)eşya 4(10, 5)10101010A0 / 0s = 115B40 / 2s = 115C0 / 0s = 82D70 / 7s = 115E40 / 2s = 98F120 / 17olursuzG70 / 7s = 80H90 / 12s = 98I40 / 2s = 50

E çıkarıldı (en büyük sınır) ve dallandı. H (eşya 3 alındı): enİyi = 90, s = 98 → kuyruğa. I (eşya 3 yok): s = 50 ≤ 90 → budandı. Kuyruk: H (98), C (82), G (80).

kökeşya 1(40, 2)eşya 2(30, 5)eşya 3(50, 10)eşya 4(10, 5)1010101010A0 / 0s = 115B40 / 2s = 115C0 / 0s = 82D70 / 7s = 115E40 / 2s = 98F120 / 17olursuzG70 / 7s = 80H90 / 12s = 98I40 / 2s = 50J100 / 17olursuzK90 / 12s = 90

H çıkarıldı (en büyük sınır) ve dallandı. J (eşya 4 alındı): ağırlık 17 > 16 → olursuz. K (eşya 4 yok): s = 90 ≤ 90 → budandı. Kuyruk: C (82), G (80).

kökeşya 1(40, 2)eşya 2(30, 5)eşya 3(50, 10)eşya 4(10, 5)1010101010A0 / 0s = 115B40 / 2s = 115C0 / 0s = 82D70 / 7s = 115E40 / 2s = 98F120 / 17olursuzG70 / 7s = 80H90 / 12s = 98I40 / 2s = 50J100 / 17olursuzK90 / 12s = 90

C çıkarıldı: s = 82 ≤ enİyi = 90 → budandı. G çıkarıldı: s = 80 ≤ enİyi = 90 → budandı. Kuyruk boş: en iyi kazanç 90 (H: eşya 1 ve 3). Tam ağacın 31 düğümünden yalnızca 11’i üretildi.

0/1 Sırt Çantası

En İyi Önce Dal Sınır: Java

int dalSinir() {
  PriorityQueue<Dugum> kuyruk = new PriorityQueue<>(
      (a, b) -> Double.compare(b.sinir, a.sinir));
  Dugum kok = new Dugum(-1, 0, 0);
  kok.sinir = sinir(kok);
  kuyruk.add(kok);  int enIyi = 0;
  while (!kuyruk.isEmpty()) {
    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;
    // sol çocuk: i. eşyayı al
    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);
    // sağ çocuk: i. eşyayı alma
    Dugum alma = new Dugum(i, u.kazanc, u.agirlik);
    alma.sinir = sinir(alma);
    if (alma.sinir > enIyi) kuyruk.add(alma);
  }
  return enIyi;
}
  • Dugum: seviye, kazanç, ağırlık, sınır (seçilen eşyalar için bir boolean[] ya da bit maskesi eklenebilir).
  • Karşılaştırıcı ters: en büyük sınır önce çıkar.
  • poll sonrası test, kuyrukta beklerken eskiyen düğümleri atar (örnekte C ve G).
  • FIFO için ArrayDeque + add()/poll(), LIFO için push()/pop() yeterlidir; kodun geri kalanı aynıdır.
  • En kötü durum O(2ⁿ) düğüm, düğüm başına O(n) sınır hesabı.

0/1 Sırt Çantası · Kodu adım adım çalıştır

FIFO Dal Sınır: Kod İzleme

int fifoDalSinir() {
  ArrayDeque<Dugum> kuyruk = new ArrayDeque<>();
  kuyruk.add(kok);  int enIyi = 0;
  while (!kuyruk.isEmpty()) {
    Dugum u = kuyruk.poll();          // ilk giren
    if (u.sinir <= enIyi || u.seviye == n - 1) continue;
    for (int al = 1; al >= 0; al--) { // önce al
      Dugum c = cocuk(u, al);         // sinir(c) dahil
      if (c.agirlik <= W && c.kazanc > enIyi)
        enIyi = c.kazanc;               // yeni aday
      if (c.sinir > enIyi) kuyruk.add(c);
    }
  }
  return enIyi;
}
A115kuyruktabudandı / olursuzenİyi

Aynı sırt çantası örneği (W = 16), bu kez FIFO kuyrukla. Kök A: kazanç 0, sınır 115; kuyrukta yalnız A.

10A115B115C82kuyruktabudandı / olursuzenİyi

A kuyruğun başından çıkar ve dallanır: B (al: s = 115 → kuyruğa, enİyi = 40); C (alma: s = 82 → kuyruğa).

1010A115B115C82D115E98kuyruktabudandı / olursuzenİyi

B kuyruğun başından çıkar ve dallanır: D (al: s = 115 → kuyruğa, enİyi = 70); E (alma: s = 98 → kuyruğa).

101010A115B115C82D115E98L82M60kuyruktabudandı / olursuzenİyi

C kuyruğun başından çıkar ve dallanır: L (al: s = 82 → kuyruğa); M (alma: s = 60 ≤ 70, budandı).

10101010A115B115C82D115E98L82M60F0G80kuyruktabudandı / olursuzenİyi

D kuyruğun başından çıkar ve dallanır: F (al: ağırlık 17 > 16, olursuz); G (alma: s = 80 → kuyruğa).

1010101010A115B115C82D115E98L82M60F0G80H98I50kuyruktabudandı / olursuzenİyi

E kuyruğun başından çıkar ve dallanır: H (al: s = 98 → kuyruğa, enİyi = 90); I (alma: s = 50 ≤ 90, budandı).

1010101010A115B115C82D115E98L82M60F0G80H98I50kuyruktabudandı / olursuzenİyi

L çıkar: sınırı 82 ≤ enİyi = 90 → tekrar sınamada atılır (kuyruğa girerken umut vardı, beklerken enİyi büyüdü).

1010101010A115B115C82D115E98L82M60F0G80H98I50kuyruktabudandı / olursuzenİyi

G çıkar: sınırı 80 ≤ enİyi = 90 → tekrar sınamada atılır (kuyruğa girerken umut vardı, beklerken enİyi büyüdü).

101010101010A115B115C82D115E98L82M60F0G80H98I50J0K90kuyruktabudandı / olursuzenİyi

H kuyruğun başından çıkar ve dallanır: J (al: ağırlık 17 > 16, olursuz); K (alma: s = 90 ≤ 90, budandı). Kuyruk boş: enİyi = 90 (eşya 1 ve 3). 13 düğüm üretildi, 6 genişletme, kuyruk en çok 3.

0/1 Sırt Çantası

Aynı Örnekte Üç Strateji

123456
FIFO: 13 düğüm, 6 genişletme
123546
LIFO: 13 düğüm, 6 genişletme
12345
En iyi önce: 11 düğüm, 5 genişletme

Numaralar genişletme sırasıdır; küçük daireler üretilip genişletilmeyen düğümler (kırmızı kesikli: budanan), halka: optimum (90).

YöntemÜretilen düğümGenişletilenEn büyük kuyruk
Kaba kuvvet (tam ağaç)3115—
FIFO dal sınır1363
LIFO dal sınır (önce "al")1363
En iyi önce (LC)1153

Gezgin Satıcı

Gezgin Satıcı Problemi (TSP): Alt Sınır

  • En küçükleme: aranan, en kısa tur; düğümlerin sınırı alt sınırdır.
  • Düğüm = 0'dan başlayan kısmi yol; çocuklar = ziyaret edilmemiş bir sonraki şehir.
  • Alt sınır: henüz çıkılmamış her şehirden (bulunulan şehir + ziyaret edilmemişler) en az bir kenarla çıkılmak zorundadır:
321521580123kalın: her şehrinen ucuz kenarı2 + 3 + 2 + 5 = 12
0123min
0—32152
13—2153
2221—82
31558—5

4 şehirli simetrik uzaklık matrisi d.

alt(yol) = maliyet(yol) + enKucuk[son şehir] + Σv ziyaret edilmemiş enKucuk[v]

Kök: 2 + 3 + 2 + 5 = 12. Yol 0 → 1: 3 + 3 + (2 + 5) = 13. Her gerçek turun maliyeti bu toplamdan küçük olamaz, bu yüzden sınır geçerlidir.

Gezgin Satıcı · Kodu adım adım çalıştır

tsp(0, 0, 1): Sınırlı Derinlik Öncelikli Arama

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
  }
}
0a=12

Şehir 0’dan başlanır. Kökün alt sınırı = 2 + 3 + 2 + 5 = 12.

30a=121a=13

0 → 1: yeni = 0 + 3 = 3; alt = 13 < ∞ → dallan.

3210a=121a=132a=31

1 → 2: yeni = 3 + 21 = 24; alt = 31 < ∞ → dallan.

32180a=121a=132a=313a=37

2 → 3: yeni = 24 + 8 = 32; alt = 37 < ∞ → dallan.

32180a=121a=132a=313tur 47

Tur 0 → 1 → 2 → 3 → 0 = 32 + 15 = 47 < ∞ → enİyi = 47.

321850a=121a=132a=313tur 473a=15

1 → 3: yeni = 3 + 5 = 8; alt = 15 < 47 → dallan.

3218580a=121a=132a=313tur 473a=152a=18

3 → 2: yeni = 8 + 8 = 16; alt = 18 < 47 → dallan.

3218580a=121a=132a=313tur 473a=152tur 18

Tur 0 → 1 → 3 → 2 → 0 = 16 + 2 = 18 < 47 → enİyi = 18.

32185820a=121a=132a=313tur 473a=152tur 182a=12

0 → 2: yeni = 0 + 2 = 2; alt = 12 < 18 → dallan.

3218582210a=121a=132a=313tur 473a=152tur 182a=121a=31✗

2 → 1: yeni = 23; alt = 31 ≥ enİyi = 18 → budandı.

32185822180a=121a=132a=313tur 473a=152tur 182a=121a=31✗3a=18✗

2 → 3: yeni = 10; alt = 18 ≥ enİyi = 18 → budandı.

3218582218150a=121a=132a=313tur 473a=152tur 182a=121a=31✗3a=18✗3a=25✗

0 → 3: yeni = 15; alt = 25 ≥ enİyi = 18 → budandı.

3218582218150a=121a=132a=313tur 473a=152tur 182a=121a=31✗3a=18✗3a=25✗

Bitti: en kısa tur 0 → 1 → 3 → 2 → 0 = 18; 16 yerine 10 düğüm.

Gezgin Satıcı · Kodu adım adım çalıştır

altSinir(3, 8): Kod İzleme

int altSinir(int son, int maliyet) {
  int alt = maliyet + enKucuk[son];
  for (int v = 0; v < n; v++)
    if (!ziyaret[v])       // gidilmemiş
      alt += enKucuk[v];
  return alt;
}
321521580123yol 0 → 1 → 3, maliyet 8venKucukziy.02✓13✓22—35✓

TSP izlemesindeki 1 → 3 adımı: yol 0 → 1 → 3, maliyet 3 + 5 = 8; ziyaret = {0, 1, 3}. Son şehir 3'ten bir kez daha çıkılacak: alt = 8 + enKucuk[3] = 8 + 5 = 13.

321521580123yol 0 → 1 → 3, maliyet 8venKucukziy.02✓13✓22—35✓

v = 0: ziyaret edildi (yolda) → katkı yok, çıkış kenarı zaten maliyette.

321521580123yol 0 → 1 → 3, maliyet 8venKucukziy.02✓13✓22—35✓

v = 1: ziyaret edildi (yolda) → katkı yok, çıkış kenarı zaten maliyette.

321521580123yol 0 → 1 → 3, maliyet 8venKucukziy.02✓13✓22—35✓

v = 2: henüz gidilmedi → en az enKucuk[2] = 2 ile çıkılmalı: alt = 15.

321521580123yol 0 → 1 → 3, maliyet 8venKucukziy.02✓13✓22—35✓

v = 3: ziyaret edildi (yolda) → katkı yok; 3'ün çıkışı başta eklendi.

321521580123yol 0 → 1 → 3, maliyet 8venKucukziy.02✓13✓22—35✓

alt = 15 döner. Bu daldaki her tur ≥ 15; gerçek tur 0 → 1 → 3 → 2 → 0 = 18. 15 < enİyi = 47 olduğundan TSP izlemesinde dala girildi.

Gezgin Satıcı

Daha Sıkı Bir Alt Sınır: İki En Kısa Kenar

  • Turda her şehre bir kenarla girilir, bir kenarla çıkılır: her şehir tam iki tur kenarına değer.
  • Şehrin bu iki kenarı, ona değen en kısa iki kenardan kısa olamaz. Tüm şehirler için toplanınca her kenar iki kez sayılır:
tur ≥ ½ · Σv (v'nin en kısa iki kenarı)
321521580123v en küçük iki toplam0 2 + 3 = 51 3 + 5 = 82 2 + 8 = 103 5 + 8 = 1336 / 2 = 18

Aynı matriste “en ucuz çıkış kenarı” sınırı 12 veriyordu; bu sınır 18'dir ve optimum tur 0 → 1 → 3 → 2 → 0 = 3 + 5 + 8 + 2 = 18'e eşittir. Kökte sınır = optimum olduğu için ilk tam tur bulunur bulunmaz kalan bütün dallar budanır.

Gezgin Satıcı · Kodu adım adım çalıştır

ikiKenarSinir(): Kod İzleme

double ikiKenarSinir() {
  int toplam = 0;
  for (int v = 0; v < n; v++) {
    int m1 = INF, m2 = INF;     // en küçük iki
    for (int u = 0; u < n; u++) {
      if (u == v) continue;
      if (d[v][u] < m1) { m2 = m1; m1 = d[v][u]; }
      else if (d[v][u] < m2) m2 = d[v][u];
    }
    toplam += m1 + m2;
  }
  return toplam / 2.0;  // her kenar iki kez
}
321521580123m1 = — m2 = — toplam = 0

Simetrik 4 şehirli matris. toplam = 0; her şehir için en kısa iki kenar aranacak.

321521580123m1 = 3 m2 = ∞ toplam = 0

v = 0, u = 1: d = 3 < m1 = ∞ → m1 = 3 (eski m1 m2'ye kayar).

321521580123m1 = 2 m2 = 3 toplam = 0

u = 2: d = 2 < m1 = 3 → m2 = 3, m1 = 2. İki en küçük kayar gibi güncellenir.

321521580123m1 = 2 m2 = 3 toplam = 5

u = 3: 15 ikisinden de büyük, değişmez. toplam += 2 + 3 = 5.

321521580123m1 = 3 m2 = 5 toplam = 13

v = 1: kenarlar 3, 21, 5 → m1 = 3, m2 = 5. toplam = 13.

321521580123m1 = 2 m2 = 8 toplam = 23

v = 2: kenarlar 2, 21, 8 → 2 + 8. toplam = 23.

321521580123m1 = 5 m2 = 8 toplam = 36

v = 3: kenarlar 15, 5, 8 → 5 + 8. toplam = 36.

321521580123m1 = 5 m2 = 8 toplam = 36

36 / 2 = 18 döner. Kalın kenarlar tam da optimum turu (0-1-3-2-0) oluşturur; bu yüzden sınır sıkıdır. Kısmi yolda aynı fikir, yoldaki kenarlar sabitlenerek uygulanır.

Gezgin Satıcı

İndirgenmiş Maliyet Matrisi ile Alt Sınır

  • Köşegen ∞ yapılır. Her satırdan en küçüğü, sonra her sütundan en küçüğü çıkarılır.
  • Her tur her satırdan ve her sütundan tam bir hücre kullanır; çıkarılan toplam her turun maliyetinden düşülmüştür → alt sınır.
  • Örnek: satırlar 2 + 3 + 2 + 5 = 12, sütun 3'ten 2 → kök sınırı 14.
  • Dallanma i → j kenarıyla: i satırı ve j sütunu ∞, (j, i) ∞ yapılır, matris yeniden indirgenir. Çocuğun sınırı = ebeveyn + indirgenmiş c[i][j] + yeni indirgeme.
Kökten dalsınır
0 → 114 + 1 + 3 = 18
0 → 214 + 0 + 4 = 18
0 → 314 + 11 + 3 = 28
0123
0∞1011
10∞180
2019∞4
31003∞

İndirgenmiş matris (toplam 14). Her satırda ve sütunda en az bir 0 var.

0 → 3 dalı 28 ile, optimum 18 bulunduğu anda budanır. Bu yöntem asimetrik (d[i][j] ≠ d[j][i]) TSP'de de geçerlidir (Little ve diğ., 1963).

Gezgin Satıcı · Kodu adım adım çalıştır

indirge(): Satır ve Sütun İndirgemesi

int indirge(int[][] m) {
  int toplam = 0;
  for (int i = 0; i < n; i++) {       // satırlar
    int mn = satirMin(m, i);
    if (mn > 0 && mn < INF) {
      satirdanCikar(m, i, mn); toplam += mn;
    }
  }
  for (int j = 0; j < n; j++) {       // sütunlar
    int mn = sutunMin(m, j);
    if (mn > 0 && mn < INF) {
      sutundanCikar(m, j, mn); toplam += mn;
    }
  }
  return toplam;
}
01230∞321513∞2152221∞831558∞toplam = 0

Köşegeni ∞ olan 4 × 4 uzaklık matrisi; toplam = 0.

01230∞101313∞2152221∞831558∞toplam = 2mn = 2

Satır 0: en küçük 2 → satırdan 2 çıkar: 1, 0, 13. toplam = 2.

01230∞101310∞1822221∞831558∞toplam = 5mn = 3

Satır 1: en küçük 3 → 0, 18, 2. toplam = 5.

01230∞101310∞1822019∞631558∞toplam = 7mn = 2

Satır 2: en küçük 2 → 0, 19, 6. toplam = 7.

01230∞101310∞1822019∞631003∞toplam = 12mn = 5

Satır 3: en küçük 5 → 10, 0, 3. Satır indirgemesi bitti: toplam = 12 (en ucuz çıkış sınırının aynısı).

01230∞101310∞1822019∞631003∞toplam = 12mn = 0

Sütun 0: en küçük 0 → değişiklik yok. Sütun 1 ve 2 de zaten 0 içerir.

01230∞101110∞1802019∞431003∞toplam = 14mn = 2

Sütun 3: değerler 13, 2, 6 → en küçük 2; çıkarılır: 11, 0, 4. toplam = 14. Sütun adımı, “her şehre bir kez girilir” bilgisini de sınıra katar.

01230∞101110∞1802019∞431003∞toplam = 14

Sınır 14 döner: 12'den sıkı, iki kenar sınırından (18) gevşek. Matris, çocuk düğümlerin sınırı için saklanır.

Gezgin Satıcı

Üç TSP Sınırı: Sıkılık ve Maliyet

en ucuz çıkış kenarı12indirgenmiş matris14iki en kısa kenar18optimum tur18
SınırDüğüm başına maliyetNeyi kullanır?Not
En ucuz çıkış kenarıO(n) (önceden enKucuk[])her şehirden bir çıkışen ucuz, en gevşek
İndirgenmiş matrisO(n²)her şehre bir giriş + bir çıkışasimetrik TSP'de de geçerli
İki en kısa kenarO(n²)her şehre değen iki kenarsimetrik TSP için
Sıkı sınır daha çok budar ama her düğümde daha pahalıdır. Daha da sıkı sınırlar (1-ağaç, LP gevşetmesi) büyük örneklerde kullanılır; seçim, budanan düğüm sayısı ile düğüm başına iş arasındaki dengeye göre yapılır.

Gezgin Satıcı

Daha Büyük Örnek: 6 Şehir

012345min
0—292021163116
129—1529284015
22015—15142514
3212915—121812
416281412—2212
53140251822—18
  • Budamasız geri izleme tüm (n−1)! = 120 turu dener; altSinir testiyle aynı sonuç çok daha az düğümle bulunur.
  • Kök alt sınırı: 16 + 15 + 14 + 12 + 12 + 18 = 87; optimum 115.
  • En iyi tur: 0 → 1 → 2 → 3 → 5 → 4 → 0 = 29 + 15 + 15 + 18 + 22 + 16 = 115.
SürümÜretilen düğümtsp çağrısı
Budamasız (geri izleme)326326
En ucuz çıkış sınırı210130
Daha sıkı sınırlarSimetrik TSP'de her şehrin iki en kısa kenarının toplamının yarısı; ya da satır/sütun indirgenmiş maliyet matrisi (Little ve ark., 1963). Sıkı sınır daha çok budar ama her düğümde daha pahalıdır.

Atama Problemi

Atama Problemi: n Kişi, n İş

  • c[i][j]: i. kişinin j. işi yapma maliyeti. Her kişiye farklı bir iş verilerek toplam en küçüklenir; n! olası atama vardır.
  • Durum uzayı: i. seviyede i. kişiye boş bir iş seçilir.
  • Alt sınır: kalan her kişi en az kendi satırının en küçüğünü öder (iş çakışmaları yok sayılır):
alt = yeni + kalanMin[i + 1],  kalanMin[i] = Σr ≥ i minj c[r][j]

alt ≥ enİyi ise dal kesilir. Satır en küçükleri 4, 3, 2 → kalanMin = [9, 5, 2, 0]: kökün sınırı 9.

kişi \ iş012min
05844
17363
22952
Atama problemi polinom zamanda da çözülür (Macar yöntemi, O(n³)). Dal sınır burada yöntemi küçük ve kolay izlenir bir örnekte göstermek içindir; ek kısıtlı (ör. bazı işler birlikte yapılamaz) türevlerinde gerçekten gerekir.

Atama Problemi · Kodu adım adım çalıştır

ata(0, 0): Kod İzleme

void ata(int i, int maliyet) {
  if (i == n) {                     // tam atama
    enIyi = Math.min(enIyi, maliyet);
    return;
  }
  for (int j = 0; j < n; j++) {
    if (kullanildi[j]) continue;
    int yeni = maliyet + c[i][j];
    if (yeni + kalanMin[i + 1] >= enIyi)
      continue;                     // sınır
    kullanildi[j] = true;
    ata(i + 1, yeni);
    kullanildi[j] = false;          // geri al
  }
}
iş 0iş 1iş 2k0584k1736k2295enİyi = ∞

kalanMin = [9, 5, 2, 0]; enİyi = ∞. ata(0, 0) çağrılır: kişi 0 için işler sırayla denenir.

iş 0iş 1iş 2k0584k1736k2295enİyi = ∞alt = 10

k0 → iş 0: yeni = 5, alt = 5 + kalanMin[1] = 10 < ∞ → dallan.

iş 0iş 1iş 2k0584k1736k2295enİyi = ∞alt = 10

k1: iş 0 dolu, atlanır. İş 1: yeni = 8, alt = 8 + 2 = 10 → dallan.

iş 0iş 1iş 2k0584k1736k2295enİyi = 13

k2: yalnız iş 2 boş: yeni = 13 → i = 3, tam atama: enİyi = 13.

iş 0iş 1iş 2k0584k1736k2295enİyi = 13alt = 13

Geri dönülür. k1 → iş 2: yeni = 11, alt = 11 + 2 = 13 ≥ 13 → kesilir.

iş 0iş 1iş 2k0584k1736k2295enİyi = 13alt = 13

k0 → iş 1: yeni = 8, alt = 8 + 5 = 13 ≥ 13 → kesilir; altındaki 2 atama hiç denenmez.

iş 0iş 1iş 2k0584k1736k2295enİyi = 13alt = 9

k0 → iş 2: yeni = 4, alt = 9 < 13 → dallan.

iş 0iş 1iş 2k0584k1736k2295enİyi = 13alt = 13

k1 → iş 0: yeni = 11, alt = 13 ≥ 13 → kesilir.

iş 0iş 1iş 2k0584k1736k2295enİyi = 13alt = 9

k1 → iş 1: yeni = 7, alt = 9 → dallan.

iş 0iş 1iş 2k0584k1736k2295enİyi = 9

k2 → iş 0: yeni = 9 → tam atama, enİyi = 9 (4 + 3 + 2). Sınıra eşit olduğu için daha iyisi yoktur. 7 çağrı; budamasız arama 3! = 6 atamanın hepsini (16 çağrı) gezerdi.

Diğer Uygulamalar

Tam sayılı Doğrusal Programlama (ILP)

  • Doğrusal programın tüm değişkenleri tam sayı olmalı. Dal sınırın en yaygın endüstriyel kullanımı (Land ve Doig, 1960).
  • Sınır: tam sayı koşulunu kaldır, LP gevşetmesini çöz. LP optimumu, ILP optimumu için üst sınırdır.
  • Dallanma: kesirli bir değişken (y = 1,5) için iki alt problem: y ≤ 1 ve y ≥ 2. Aradaki kesirli bölge atılır, hiçbir tam sayı nokta kaybolmaz.
Örnek: en büyükle Z = 5x + 4y; 6x + 4y ≤ 24, x + 2y ≤ 6, x, y ≥ 0 tam sayı.

İkinci örnek: Z = 3x + 2y; x + y ≤ 4, x ≤ 3, y ≤ 2. Kaba kuvvet 0 ≤ x ≤ 3, 0 ≤ y ≤ 2 ızgarasındaki 12 noktanın hepsini dener → (3, 1), Z = 11. Bu örnekte LP gevşetmesi de (3, 1) verir: dal sınır kökte biter.

12345671234560xy6x+4y=24x+2y=6LP: (3; 1,5) Z = 21↑ (4; 0) Z = 20
Gölgeli: LP olurlu bölgesi; noktalar: tam sayı çözümler.

Diğer Uygulamalar · Adım adım

ILP: LP Gevşetmeleriyle Dallanma

x=3, y=1,5Z = 21

Kök: tam sayı koşulu gevşetilir (LP gevşetmesi). LP optimumu (3; 1,5), Z = 21 → üst sınır. y kesirli → y üzerinde dallan.

y ≤ 1y ≥ 2x=3, y=1,5Z = 21x=3,33, y=1Z = 20,67x=2, y=2Z = 18

Dal y ≤ 1: LP optimumu (3,33; 1), Z = 20,67. x kesirli → x ≤ 3 ve x ≥ 4 dalları açılır.

y ≤ 1y ≥ 2x ≤ 3x=3, y=1,5Z = 21x=3,33, y=1Z = 20,67x=2, y=2Z = 18x=3, y=1Z = 19

Dal x ≤ 3: LP çözümü (3; 1) tam sayı → ilk aday çözüm, enİyi = 19.

y ≤ 1y ≥ 2x ≤ 3x ≥ 4x=3, y=1,5Z = 21x=3,33, y=1Z = 20,67x=2, y=2Z = 18x=3, y=1Z = 19x=4, y=0Z = 20

Dal x ≥ 4: LP çözümü (4; 0) tam sayı, Z = 20 > 19 → enİyi = 20.

y ≤ 1y ≥ 2x ≤ 3x ≥ 4x=3, y=1,5Z = 21x=3,33, y=1Z = 20,67x=2, y=2Z = 18x=3, y=1Z = 19x=4, y=0Z = 20

Dal y ≥ 2: LP sınırı Z = 18 ≤ 20 → budandı. Optimum: x = 4, y = 0, Z = 20.

LP optimumu (3; 1,5) yuvarlanırsa (3; 1) → Z = 19 ya da (3; 2) → olursuz olur. Gerçek optimum (4; 0) yuvarlamayla bulunamaz.

Diğer Uygulamalar

Maksimum Klik (Maximum Clique)

012345
6 düğümlü örnek çizge; en büyük klik {0, 1, 2, 3, 4}.
  • Klik: her iki düğümü komşu olan düğüm kümesi.
  • Sınır: |K| + |aday| ≤ |enİyi| ise mevcut klik ne kadar büyütülse de enİyi'yi geçemez.
void klik(List<Integer> K, int bas) {
  if (K.size() > enIyi.size())
    enIyi = new ArrayList<>(K);
  List<Integer> aday = new ArrayList<>();
  for (int v = bas; v < n; v++)
    if (uygun(v, K)) aday.add(v);  // K'ye komşu
  if (K.size() + aday.size() <= enIyi.size())
    return;                        // sınır
  for (int v : aday) {
    K.add(v);
    klik(K, v + 1);
    K.remove(K.size() - 1);          // geri al
  }
}
Sürümklik çağrısı
Sınırsız geri izleme36
|K| + |aday| sınırıyla17

Diğer Uygulamalar · Kodu adım adım çalıştır

klik({}, 0): Sınırlı Arama İzleme

void klik(List<Integer> K, int bas) {
  if (K.size() > enIyi.size())
    enIyi = new ArrayList<>(K);
  List<Integer> aday = new ArrayList<>();
  for (int v = bas; v < n; v++)
    if (uygun(v, K)) aday.add(v);  // K'ye komşu
  if (K.size() + aday.size() <= enIyi.size())
    return;                        // sınır
  for (int v : aday) {
    K.add(v);
    klik(K, v + 1);
    K.remove(K.size() - 1);        // geri al
  }
}
012345|K| + |aday| = 0 + 6 = 6 ; |enİyi| = 0

Altı düğümlü çizge; K boş, enİyi boş. Adaylar 0–5'in hepsi: 0 + 6 > 0, sınır geçilir; ilk aday 0 eklenir ve derine inilir.

012345|K| + |aday| = 1 + 4 = 5 ; |enİyi| = 1

K = {0} enİyi'den büyük → enİyi = {0}. K'nin hepsine komşu adaylar {1, 2, 3, 4}; 1 + 4 > 1 → devam, ilk aday 1 eklenir.

012345|K| + |aday| = 2 + 3 = 5 ; |enİyi| = 2

K = {0, 1} enİyi'den büyük → enİyi = {0, 1}. K'nin hepsine komşu adaylar {2, 3, 4}; 2 + 3 > 2 → devam, ilk aday 2 eklenir.

012345|K| + |aday| = 3 + 2 = 5 ; |enİyi| = 3

K = {0, 1, 2} enİyi'den büyük → enİyi = {0, 1, 2}. K'nin hepsine komşu adaylar {3, 4}; 3 + 2 > 3 → devam, ilk aday 3 eklenir.

012345|K| + |aday| = 4 + 1 = 5 ; |enİyi| = 4

K = {0, 1, 2, 3} enİyi'den büyük → enİyi = {0, 1, 2, 3}. K'nin hepsine komşu adaylar {4}; 4 + 1 > 4 → devam, ilk aday 4 eklenir.

012345|K| + |aday| = 5 + 0 = 5 ; |enİyi| = 5

K = {0, 1, 2, 3, 4}: enİyi = {0, 1, 2, 3, 4} (5 düğüm). Aday kalmadı: 5 + 0 ≤ 5 → return.

012345|K| + |aday| = 4 + 0 = 4 ; |enİyi| = 5

Geri alınır, K = {0, 1, 2, 4} denenir: aday {}, 4 + 0 = 4 ≤ 5 → sınırla budandı; bu klik 5'i geçemez.

012345|K| + |aday| = 3 + 1 = 4 ; |enİyi| = 5

Geri alınır, K = {0, 1, 3} denenir: aday {4}, 3 + 1 = 4 ≤ 5 → sınırla budandı; bu klik 5'i geçemez.

012345|K| + |aday| = 2 + 0 = 2 ; |enİyi| = 5

Aynı biçimde {0, 1, 4}: 3 + 0; {0, 2}: 2 + 2; {0, 3}: 2 + 1; {0, 4}: 2 + 0 — hepsi ≤ 5, budandı.

012345|K| + |aday| = 1 + 2 = 3 ; |enİyi| = 5

Kökte kalan adaylar 1–5 de tek tek denenir ({1}: 4, {2}: 3, {3}: 3, {4}: 2, {5}: 1); hepsi ≤ 5 → budandı. Sonuç {0, 1, 2, 3, 4}, 17 çağrı (sınırsız 36).

Diğer Uygulamalar

Klik İçin Daha Sıkı Sınır: Boyama

  • Bir klikteki her düğüm çifti komşudur; bu yüzden klikteki düğümlerin hepsi farklı renk alır.
  • Adaylar k renkle boyanabiliyorsa adaylardan en çok k düğüm kliğe girebilir: |K| + renk(aday) ≤ |enİyi| ise budanır.
  • Açgözlü boyama O(aday²) sürer ve en iyi boyama olmasa da geçerli bir üst sınır verir (fazla renk kullanmak sınırı yalnızca gevşetir).
  • Örnek: adaylar 5 düğümlü bir halka, K boş, enİyi = 3. Eski sınır 0 + 5 > 3 → dal açılır; renk sınırı 0 + 3 ≤ 3 → budanır (halkadaki en büyük klik 2'dir).
012343 renk:{0, 2} {1, 3} {4}|aday| = 5renk sınırı = 3
Pratikte en hızlı tam klik algoritmalarının çoğu (Tomita'nın MCQ / MCS ailesi) bu fikre dayanır: adayları renk sırasıyla dener ve renk sınırıyla budar.

Diğer Uygulamalar

Dal Sınırla Çözülen Diğer Problemler

Hamilton yoluHer düğümü tam bir kez ziyaret eden yol; ağırlıklı sürümü TSP'ye çok benzer sınırlarla çözülür.
Boole sağlanabilirlik (SAT)Değişkenlere doğruluk değeri ata; çelişen kısmi atamaları buda (DPLL). En büyük SAT için sınır: sağlanabilecek en fazla tümce.
ÇizelgelemeEn büyük yükü (makespan) ya da gecikmeyi en küçükle; sınır: kalan işlerin en iyi durumdaki yükü.
Kutu paketlemeEşyaları en az kutuya yerleştir; alt sınır ⌈Σ boyut / kutu kapasitesi⌉.
Maksimum kapsamaEn fazla öğeyi kapsayan k küme seç; sınır: kalan en büyük kümelerin ekleyebileceği öğe sayısı.
Atama problemin işi n kişiye en düşük maliyetle ata; alt sınır: atanmamış her satırın en küçük maliyeti.

Maksimum akış gibi polinom zamanlı algoritması olan problemlerde dal sınıra gerek yoktur; yöntem NP-zor problemler için anlamlıdır.

Diğer Uygulamalar

Dal Sınır, A* ve Derinlik Öncelikli Dal Sınır

ÖzellikEn iyi önce dal sınır (LC)A*Derinlik öncelikli dal sınır
Seçimen iyi sınır (ĉ)en küçük f = g + hyığın / özyineleme
Sınır / tahmingeçerli (iyimser) sınırkabul edilebilir h (fazla tahmin etmez)geçerli sınır + enİyi
Hedefoptimizasyon (en iyi yaprak)başlangıçtan hedefe en kısa yoloptimizasyon
Bellekcanlı düğümler: üstel olabiliraçık liste: üstel olabilirO(derinlik)
İlk tam çözümgenellikle geç ama iyibulunan ilk hedef optimumdurerken (her an bir çözüm var)
  • A*, ağırlıklı çizgede yol arayan bir LC dal sınırdır: h(x), x'ten hedefe kalan maliyetin alt sınırıdır (8 bulmacasında yanlış taş sayısı).
  • Bellek bittiğinde derinlik öncelikli sürüm ya da IDA* (sınır eşiğini yineleyerek artıran derinlik araması) kullanılır.

Değerlendirme

Tasarım Paradigmaları: Birikimli Karşılaştırma

ParadigmaKararAlt problemler / gezinmeNe zaman?Örnek
Kaba kuvvettüm adayları üret, sonra test ettam arama uzayıuzay çok küçükse8⁸ vezir yerleşimi
Böl ve fethetsabit bölme kuralı; böl, çöz, birleştirbağımsız; yukarıdan aşağıalt problemler örtüşmüyorsabirleştirme sıralaması, Strassen
Açgözlüo an en iyi görüneni seç; geri dönmeseçimden sonra tek alt problemaçgözlü seçim özelliği kanıtlıysaDijkstra, Huffman, Kruskal
Dinamik programlamatüm seçenekleri dene, en iyisini saklaörtüşen; çoğunlukla aşağıdan yukarıoptimal alt yapı, polinom sayıda alt problemFibonacci, 0/1 sırt çantası, LCS
Geri izlemekısmi çözümü genişlet; geçersizse geri aldurum uzayı ağacında DFSkısıt sağlama, tüm çözümlerN vezir, Sudoku
Dal sınırgeri izleme + sınırla budamaDFS, BFS ya da en iyi önceNP-zor eniyileme, kesin sonuç0/1 sırt çantası, TSP
Soru sırası: alt problemler bağımsız mı? → böl ve fethet. Örtüşüyor mu? → dinamik programlama. Yerel en iyi seçim küresel en iyiye götürüyor mu? → açgözlü. Hiçbiri yoksa ve problem NP-zorsa: kesin sonuç için geri izleme / dal sınır, polinom sürede garantili sonuç için yaklaşım algoritması.

Özet

Özet

KonuHatırlanacaklar
Paradigmadurum uzayı ağacı; seç → dallan → sınırla → buda; enİyi en iyi tam çözümü tutar
Sınırgeçerli (iyimser), sıkı, ucuz; gevşetme ile kurulur. En büyüklemede üst, en küçüklemede alt sınır
Budamaolursuzluk, sınır ≤ enİyi (ya da alt ≥ enİyi), tam çözüm / tam sayı LP
StratejilerFIFO (BFS, kuyruk), LIFO (DFS, yığın, az bellek), LC / en iyi önce (öncelikli kuyruk, az düğüm)
Sırt çantasıkesirli sırt çantası üst sınırı; örnekte sınır(kök) = 115, optimum 90; 31 yerine 11 düğüm
TSPalt sınır = maliyet + çıkılmamış şehirlerin en ucuz çıkış kenarları; 4 şehirde 16 → 10 düğüm
ILP / klikLP gevşetmesi + kesirli değişkende dallanma; klikte |K| + |aday| ≤ |enİyi| sınırı
Karmaşıklıken kötü durumda üstel; pratik başarı sınırın kalitesine bağlı
Paradigmalarbağımsız → böl ve fethet; örtüşen → DP; açgözlü seçim → açgözlü; NP-zor kesin → geri izleme / dal sınır

Özet

Etkileşimli Simülatörler

Gezgin Satıcı ProblemiEn fazla 10 rastgele şehirde hızlı en yakın komşu sezgiseli ile tüm turları deneyen kaba kuvvetin karşılaştırması.

Özet

Sık Yapılan Hatalar

Geçersiz (kötümser) sınırSırt çantasında yalnızca tam sığan eşyaları toplamak üst sınır değildir; optimumu içeren dal budanabilir.
Yönü karıştırmakEn büyüklemede sinir ≤ enİyi, en küçüklemede alt ≥ enİyi ise budanır. Tersini yazmak ya optimumu kaçırır ya hiç budamaz.
Kuyruktan çıkınca tekrar sınamamakDüğüm eklendiğinde umut vaat ediyordu; beklerken enİyi büyüdüyse artık gereksizdir (örnekte C ve G).
Eşyaları sıralamamakKesirli sınır, eşyalar pᵢ/wᵢ'ye göre azalan sırada değilse geçerli bir üst sınır vermez.
enİyi'yi yalnızca yapraklarda güncellemekSırt çantasında her olurlu düğüm bir çözümdür; erken güncelleme daha çok budama sağlar.
Geri izleme ile aynı sanmakSınır testi olmayan kod (ör. budamasız TSP araması) dal sınır değildir; yalnızca tüm ağacı gezer.

Özet

Örnek Problemler

Sırt çantası: (p, w) = (20, 2), (30, 5), (35, 7), (12, 3); W = 9 (oranlar 10, 6, 5, 4).

  1. Kökün kesirli üst sınırını hesaplayın.
  2. Optimum kazanç nedir, hangi eşyalar alınır?
  3. "Eşya 1 alınmadı" düğümünün (0, 0) sınırı nedir? Optimum bulunduktan sonra budanır mı?
  4. 4 şehirli TSP örneğinde 0 → 3 → 1 yolunun alt sınırı nedir?
  5. Maksimum klikte K = {3, 4}, aday = {5}, |enİyi| = 5 iken ne olur?
  6. Belleği çok kısıtlı bir sistemde hangi arama stratejisini seçersiniz?
Cevapları göster
  1. 20 + 30 = 50 (ağırlık 7); kalan 2 birim eşya 3'ten: 2 · 35/7 = 10 → 60.
  2. Eşya 1 ve 3: 55 (ağırlık 9).
  3. Eşya 2 tam sığar: 30 (ağırlık 5); eşya 3 sığmaz, kalan 4 birim: 4 · 35/7 = 20 → 50. 50 ≤ 55 → budanır.
  4. maliyet 15 + 5 = 20; + enKucuk[1] = 3 + enKucuk[2] = 2 → 25 (≥ 18, budanır).
  5. 2 + 1 = 3 ≤ 5 → budanır; bu daldan 5'ten büyük klik çıkamaz.
  6. LIFO (DFS): yalnızca geçerli yolun kardeş düğümleri tutulur; bellek O(derinlik · dallanma).

Özet

Alıştırmalar

  1. Sırt çantası kodunu FIFO kuyrukla yazın; bölümdeki örnekte kaç düğüm üretilir?
  2. tsp metoduna en iyi turu kaydeden int[] enIyiYol ekleyin.
  3. 4 şehirli örneğin kökünde "iki en kısa kenar toplamının yarısı" sınırını hesaplayın.
  4. Maliyet matrisi [[9, 2, 7], [6, 4, 3], [5, 8, 1]] olan atama probleminin kök alt sınırı ve optimumu nedir?
  5. Kesirli sırt çantası sınırının her zaman geçerli olduğunu kanıtlayın.
  6. İkinci ILP örneği (Z = 3x + 2y; x + y ≤ 4, x ≤ 3, y ≤ 2) LP gevşetmeli dal sınırla kaç düğümde çözülür?
Cevaplar / ipuçları
  1. ArrayDeque + poll(): 13 düğüm, 6 genişletme; sonuç yine 90.
  2. Döngüde yol[sayac] = s; tur < enIyi ise enIyiYol = yol.clone().
  3. (2+3) + (3+5) + (2+8) + (5+8) = 36 → 36/2 = 18: optimuma eşit.
  4. Satır en küçükleri 2 + 3 + 1 = 6; optimum 2 + 6 + 1 = 9.
  5. Her 0/1 çözüm kesirli bir çözümdür; açgözlü kesirli optimumu verir, o da ≥ 0/1 optimum.
  6. Tek düğüm: LP gevşetmesi zaten tam sayı (3, 1), Z = 11.

Özet

Kaynaklar

  • E. Horowitz, S. Sahni ve S. Rajasekaran, Computer Algorithms, 2. baskı, Silicon Press, 2008 (Bölüm 8: Branch-and-Bound).
  • R. Neapolitan, Foundations of Algorithms, 5. baskı, Jones & Bartlett, 2015 (Bölüm 6).
  • A. Levitin, Introduction to the Design and Analysis of Algorithms, 3. baskı, Pearson, 2012 (Bölüm 12.2).
  • A. H. Land ve A. G. Doig, "An Automatic Method of Solving Discrete Programming Problems", Econometrica 28(3), 1960.
  • J. D. C. Little, K. G. Murty, D. W. Sweeney ve C. Karel, "An Algorithm for the Traveling Salesman Problem", Operations Research 11(6), 1963.
  • R. Carraghan ve P. M. Pardalos, "An Exact Algorithm for the Maximum Clique Problem", Operations Research Letters 9(6), 1990.

Son

Bölüm 10: Dal Sınır Algoritmaları
Sonraki bölüm: Bölüm 11: Yaklaşım Algoritmaları · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.