Bölüm 13: Geri Dönüşlü Algoritmalar

Algoritmalar
Geri dönüp deneDurum uzayı ağacıBudamaN vezir problemi En az çakışmaSudokuGraf boyama ve Hamilton yoluKelime aramaKarmaşıklık
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Kavram

Geri dönüşlü aramayı (backtracking) kısmi çözüm, aday, kısıt ve budama kavramlarıyla açıklamak; durum uzayı ağacını çizmek.

Şablon

"seç → keşfet → geri al" özyinelemeli şablonunu Java ile yazmak ve yeni bir probleme uyarlamak.

Uygulamalar

N vezir, Sudoku, labirent, graf boyama, Hamilton yolu ve kelime arama problemlerini adım adım çözmek.

Analiz

En kötü durumun neden üstel olduğunu göstermek; budama ve sezgisellerin (MRV, en az çakışma) etkisini değerlendirmek.

Temel Fikir

Geri Dönüp Dene

  • Bazen bir problemi çözmek için farklı yollar denemek ve yanlış yollardan geri dönmek gerekir.
  • Geri dönüşlü arama (backtracking), karmaşık problemleri çözmek için bu stratejiyi sistemli biçimde kullanır.
  • Çözüm, adım adım kısmi çözüm olarak kurulur; bir adım kısıtları bozuyorsa o dal terk edilir.
  • Tüm olasılıkları körü körüne üreten kaba kuvvetten (brute force) farkı budur: geçersiz kısmi çözümlerin devamı hiç üretilmez.
✗✗✗✗✗✗✗✗GÇ

Bulunan yol (turuncu) ve denenip bırakılan çıkmazlar (✗)

Temel Fikir

Labirentteki Yolcu

  • Geri dönüşlü algoritma, bir labirentte yolculuk yapan kişiye benzetilebilir.
  • Kişi her kavşak noktasında bir karar vererek ilerler.
  • Seçtiği yol çıkışa götürmüyorsa geri dönüp başka bir yol dener.
  • Her adımda bir karar verilir ve kararın doğru olup olmadığı kontrol edilir.
  • Bu deneme-yanılma süreci problem çözülene (ya da tüm seçenekler tükenene) kadar sürer.
  • Labirent, Sudoku ve satranç gibi bulmaca ve yapay zekâ oyunlarında kullanılır.
Önemli: Geri dönmek için nereden gelindiğini hatırlamak gerekir. Özyineleme bunu bedavaya sağlar: çağrı yığını kavşakların listesidir.

Temel Fikir

Labirentte Geri Dönüş Adım Adım

GÇ

Giriş (G) hücresinden başlanır. Yön sırası: aşağı, sağ, yukarı, sol. Her hücre ziyaret edildiğinde işaretlenir; böylece aynı hücreye ikinci kez girilmez.

GÇ

Aşağı iki adım: (2,0). Bir daha aşağısı duvar, bu yüzden bir sonraki yön (sağ) denenir.

GÇ

Sağa iki adım: (2,2) bir kavşak. Önce aşağı denenecek; sağ ve yukarı duvar.

GÇ

Aşağı ve sola ilerleyen koridor (4,0) hücresinde çıkmaza girer: dört yön de duvar, sınır ya da ziyaret edilmiş.

✗✗✗✗GÇ

Geri dönüş: (4,0), (4,1), (4,2), (3,2) yoldan çıkarılır (✗). Kavşak (2,2) yeniden denenir ama kalan yönleri de kapalı.

✗✗✗✗✗✗✗✗GÇ

Geri dönüş girişe kadar sürer: (2,2), (2,1), (2,0), (1,0) de çıkmaz. Girişte sıradaki yön sağ denenir.

✗✗✗✗✗✗✗✗GÇ

Üst koridor boyunca sağa: (0,4). Aşağısı açık.

✗✗✗✗✗✗✗✗GÇ

(1,4), (2,4), (3,4) üzerinden çıkışa (Ç) ulaşıldı. Yol 9 hücre; 8 hücre çıkmaz sokak olarak denendi ve bırakıldı.

Temel Fikir

Durum Uzayı Ağacı (State-Space Tree)

kökx₁=ax₁=bx₁=ca,aa,bb,ab,cb,c,a✗ kısıt✗ kısıt✗ kısıt✗ budandıalt ağacı hiç üretilmez✓ çözümkök1. seçim2. seçim3. seçim
Kısmi çözümKökten bir düğüme giden yol: o ana kadar yapılan seçimler.
AdayBir sonraki seviyede yapılabilecek seçimler: düğümün çocukları.
KısıtKısmi çözüm geçersizse o düğümün alt ağacı budanır.
Hedef testiTam ve geçerli bir çözüme ulaşıldı mı? (yaprak)

Temel Fikir

Genel Şablon: Seç → Keşfet → Geri Al

void geriDon(Durum kismi) {
  if (cozumMu(kismi)) {
    kaydet(kismi);
    return;
  }
  for (Aday a : adaylar(kismi)) {
    if (gecerliMi(kismi, a)) {
      ekle(kismi, a);    // seç
      geriDon(kismi);    // keşfet
      cikar(kismi, a);   // geri al
    }
  }
}
  1. Hedef testi: kısmi çözüm tamamsa kaydet (ya da dur).
  2. Seç: sıradaki adayı kısmi çözüme ekle.
  3. Keşfet: özyinelemeyle bir seviye derine in.
  4. Geri al: adayı çıkar; durum çağrıdan önceki hâline döner, sıradaki aday denenir.
Budama gecerliMi içinde olur: geçersiz aday için özyinelemeli çağrı hiç yapılmaz, böylece o adayın altındaki tüm alt ağaç atlanır. Tek çözüm yetiyorsa geriDon boolean döndürür ve ilk true'da durulur.

Temel Fikir

Kaba Kuvvet ve Budama: 8 Vezir

Yaklaşımİncelenen adayAçıklama
64 kareden 8'ini seç4 426 165 368C(64, 8): her yerleşimi üret, sonra test et
Her satıra bir vezir16 777 2168⁸ tam yerleşim
Her satıra bir vezir, sütunlar farklı40 3208! permütasyon
Geri dönüşlü, tüm çözümler2056güvenli yerleştirme sayısı (92 çözüm)
Geri dönüşlü, ilk çözüm113güvenli yerleştirme; 105 geri alma
Budamanın gücü: Kısmi yerleşim geçersiz olur olmaz geri dönüldüğü için, 16,7 milyon tam yerleşim yerine yalnızca birkaç bin kısmi yerleşim üretilir. En kötü durum yine üsteldir, ama pratikte ağacın çok küçük bir kısmı gezilir.

Temel Fikir

Avantajlar ve Dezavantajlar

Avantajlar

  • Çok çeşitli problemlere uygulanabilen genel bir yöntemdir.
  • Çözümleri ağaç olarak ifade edilebilen problemlerde çoğu zaman verimlidir.
  • Anlaması ve uygulaması kolaydır: kısa, özyinelemeli kod.
  • Tüm çözümleri ya da hiç çözüm olmadığını kesin olarak bulur (tam arama).

Dezavantajlar

  • En kötü durumda zaman karmaşıklığı üsteldir (2ⁿ, n!, 9ᵐ …).
  • Olası çözüm sayısı çok büyük olduğunda yavaşlar; iyi budama ve sezgisel gerekir.
  • Derin özyineleme yığın belleği kullanır: O(derinlik).
  • Aynı alt problem farklı yollardan tekrar tekrar çözülebilir (DP'deki gibi saklanmaz).

N Vezir Problemi

8 Vezir Problemi (Eight Queens)

  • Bir 8×8 satranç tahtasına 8 vezirin yerleştirilmesi.
  • Amaç: hiçbir vezirin diğerini tehdit etmediği bir yerleşim bulmak. Vezir aynı satır, sütun ve çaprazdaki taşları tehdit eder.
  • Genelleştirilmiş hâli: n×n tahtaya n vezir (N-Queens). n = 2 ve n = 3 dışında her n ≥ 1 için çözüm vardır.
  • 8 vezirin 92 çözümü vardır (simetriler ayıklanınca 12 temel çözüm).
  • Geri dönüşlü algoritma bu tür problemleri çözmek için kullanılır.
♛♛♛♛♛♛♛♛

Bir çözüm: a1, b7, c4, d6, e8, f2, g5, h3

N Vezir Problemi

Geri Dönüşlü Çözüm: Adımlar

  1. Tahtanın her hücresi başlangıçta boş.
  2. İlk vezir ilk satırda bir sütuna yerleştirilir.
  3. Yerleştirilen vezirin önceki vezirlerle çakışıp çakışmadığı kontrol edilir (sütun ve iki çapraz).
  4. Çakışma yoksa konum geçerli kabul edilir; bir sonraki vezir bir sonraki satıra yerleştirilir.
  5. Bir satırda tüm sütunlar denenip güvenli yer bulunamazsa, bir önceki vezir yer değiştirilir (geri dönüş).
  6. Tüm 8 vezir yerleştirildiğinde çözüm bulunmuş olur.
Neden satır satır? Her satıra tam olarak bir vezir gelmek zorunda. Bu gözlem satır kısıtını yapının içine gömer: geriye yalnızca sütun ve çapraz denetimi kalır, arama uzayı 64⁸'den 8⁸'e iner.

N Vezir Problemi

4 Vezir: Tahta ve Durum Uzayı Ağacı

01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök

Boş tahta. Vezirler satır satır yerleştirilir; her satırda sütun 0, 1, 2, 3 sırayla denenir. Ağaçtaki düğüm, o satırda seçilen sütunu gösterir.

♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök0

Satır 0: sütun 0 güvenli → vezir yerleştirilir, bir alt seviyeye (satır 1) inilir.

♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök02

Satır 1: sütun 0, 1 tehdit altında; sütun 2 güvenli → vezir yerleştirilir, bir alt seviyeye (satır 2) inilir.

♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök02✗

Satır 2: sütun 0, 1, 2, 3 tehdit altında → güvenli sütun yok (çıkmaz). Geri dön: satır 1'deki vezir (sütun 2) kaldırılır ve o satırda sıradaki sütun denenir.

♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök02✗3

Satır 1: sütun 3 güvenli → vezir yerleştirilir, bir alt seviyeye (satır 2) inilir.

♛♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök02✗31

Satır 2: sütun 0 tehdit altında; sütun 1 güvenli → vezir yerleştirilir, bir alt seviyeye (satır 3) inilir.

♛♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök02✗31✗

Satır 3: sütun 0, 1, 2, 3 tehdit altında → güvenli sütun yok (çıkmaz). Geri dön: satır 2'deki vezir (sütun 1) kaldırılır ve o satırda sıradaki sütun denenir.

♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök02✗3✗1✗

Satır 2: sütun 2, 3 tehdit altında → güvenli sütun yok (çıkmaz). Geri dön: satır 1'deki vezir (sütun 3) kaldırılır ve o satırda sıradaki sütun denenir.

♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök0✗2✗3✗1✗

Satır 1'in denenecek başka sütunu kalmadı. Geri dön: satır 0'daki vezir (sütun 0) da kaldırılır.

♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök0✗2✗3✗1✗1

Satır 0: sütun 1 güvenli → vezir yerleştirilir, bir alt seviyeye (satır 1) inilir.

♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök0✗2✗3✗1✗13

Satır 1: sütun 0, 1, 2 tehdit altında; sütun 3 güvenli → vezir yerleştirilir, bir alt seviyeye (satır 2) inilir.

♛♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök0✗2✗3✗1✗130

Satır 2: sütun 0 güvenli → vezir yerleştirilir, bir alt seviyeye (satır 3) inilir.

♛♛♛♛01230123satır = vezir no, sütun 0–3köksatır 0satır 1satır 2satır 3kök0✗2✗3✗1✗1302

Satır 3: sütun 0, 1 tehdit altında; sütun 2 güvenli → dördüncü vezir yerleşti. satir == n: çözüm bulundu: sütunlar [1, 3, 0, 2]. Toplam 8 yerleştirme, 4 geri dönüş.

Kırmızı hücre: mevcut vezirlerce tehdit edilen kare · turuncu düğüm: son yerleştirilen · kesikli ✗: geri dönülen dal · yeşil: çözüm.

N Vezir Problemi

N Vezir: Java Kodu

boolean guvenliMi(int[][] t,
        int s, int k) {
  // aynı sütun
  for (int i = 0; i < s; i++)
    if (t[i][k] == 1) return false;
  // sol üst çapraz
  for (int i = s-1, j = k-1;
       i >= 0 && j >= 0; i--, j--)
    if (t[i][j] == 1) return false;
  // sağ üst çapraz
  for (int i = s-1, j = k+1;
       i >= 0 && j < n; i--, j++)
    if (t[i][j] == 1) return false;
  return true;
}
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; // yerleştir
      if (coz(t, satir + 1))
        return true;
      t[satir][sutun] = 0; // geri al
    }
  }
  return false;
}
  • t[i][j] == 1: (i, j)'de vezir var; n sınıfın bir alanı. Vezirler yalnızca üst satırlarda olduğundan guvenliMi üç yöne bakar: yukarı, sol üst ve sağ üst çapraz.
  • coz satır satır ilerler; ilk çözümde true döner ve yığın boyunca yukarı taşınır. guvenliMi O(n); coz en kötü durumda O(n!).

N Vezir Problemi · Kodu adım adım çalıştır

coz(t, 0), n = 4: Kodu Adım Adım İzle

01230123

coz(t, 0) çağrıldı: tahta boş, satir = 0.

♛01230123

(0, 0) güvenli → t[0][0] = 1, ardından coz(t, 1) çağrılır.

♛01230123

(1, 0) tehdit altında (aynı sütun: (0, 0)) → guvenliMi false, sonraki sütun.

♛01230123

(1, 1) tehdit altında (çapraz: (0, 0)) → guvenliMi false, sonraki sütun.

♛♛01230123

(1, 2) güvenli → t[1][2] = 1, ardından coz(t, 2) çağrılır.

♛♛01230123

(2, 0) tehdit altında (aynı sütun: (0, 0)) → guvenliMi false, sonraki sütun.

♛♛01230123

(2, 1) tehdit altında (çapraz: (1, 2)) → guvenliMi false, sonraki sütun.

♛♛01230123

(2, 2) tehdit altında (çapraz: (0, 0)) → guvenliMi false, sonraki sütun.

♛♛01230123

(2, 3) tehdit altında (çapraz: (1, 2)) → guvenliMi false, sonraki sütun.

♛♛01230123

Satır 2 için döngü bitti, güvenli sütun yok → return false.

♛01230123

coz(t, 2) false döndü → geri al: t[1][2] = 0; döngü sütun 3 ile sürer.

♛♛01230123

(1, 3) güvenli → t[1][3] = 1, ardından coz(t, 2) çağrılır.

♛♛01230123

(2, 0) tehdit altında (aynı sütun: (0, 0)) → guvenliMi false, sonraki sütun.

♛♛♛01230123

(2, 1) güvenli → t[2][1] = 1, ardından coz(t, 3) çağrılır.

♛♛♛01230123

(3, 0) tehdit altında (aynı sütun: (0, 0)) → guvenliMi false, sonraki sütun.

♛♛♛01230123

(3, 1) tehdit altında (çapraz: (1, 3)) → guvenliMi false, sonraki sütun.

♛♛♛01230123

(3, 2) tehdit altında (çapraz: (2, 1)) → guvenliMi false, sonraki sütun.

♛♛♛01230123

(3, 3) tehdit altında (çapraz: (0, 0)) → guvenliMi false, sonraki sütun.

♛♛♛01230123

Satır 3 için döngü bitti, güvenli sütun yok → return false.

♛♛01230123

coz(t, 3) false döndü → geri al: t[2][1] = 0; döngü sütun 2 ile sürer.

♛♛01230123

(2, 2) tehdit altında (çapraz: (0, 0)) → guvenliMi false, sonraki sütun.

♛♛01230123

(2, 3) tehdit altında (aynı sütun: (1, 3)) → guvenliMi false, sonraki sütun.

♛♛01230123

Satır 2 için döngü bitti, güvenli sütun yok → return false.

♛01230123

coz(t, 2) false döndü → geri al: t[1][3] = 0; döngü sütun 4 ile sürer.

♛01230123

Satır 1 için döngü bitti, güvenli sütun yok → return false.

01230123

coz(t, 1) false döndü → geri al: t[0][0] = 0; döngü sütun 1 ile sürer.

♛01230123

(0, 1) güvenli → t[0][1] = 1, ardından coz(t, 1) çağrılır.

♛01230123

(1, 0) tehdit altında (çapraz: (0, 1)) → guvenliMi false, sonraki sütun.

♛01230123

(1, 1) tehdit altında (aynı sütun: (0, 1)) → guvenliMi false, sonraki sütun.

♛01230123

(1, 2) tehdit altında (çapraz: (0, 1)) → guvenliMi false, sonraki sütun.

♛♛01230123

(1, 3) güvenli → t[1][3] = 1, ardından coz(t, 2) çağrılır.

♛♛♛01230123

(2, 0) güvenli → t[2][0] = 1, ardından coz(t, 3) çağrılır.

♛♛♛01230123

(3, 0) tehdit altında (aynı sütun: (2, 0)) → guvenliMi false, sonraki sütun.

♛♛♛01230123

(3, 1) tehdit altında (aynı sütun: (0, 1)) → guvenliMi false, sonraki sütun.

♛♛♛♛01230123

(3, 2) güvenli → t[3][2] = 1, ardından coz(t, 4) çağrılır.

♛♛♛♛01230123

satir == n → true. true değeri yığın boyunca yukarı taşınır: çözüm [1, 3, 0, 2].

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;
}

N Vezir Problemi

8 Vezir: Algoritmanın İlk Çözümü

♛♛♛♛♛♛♛♛0123456701234567

Satır 0–7 için sütunlar: [0, 4, 7, 5, 2, 6, 1, 3]

  • coz(t, 0) (n = 8) sütunları küçükten büyüğe denediği için her zaman sözlük sırasında ilk çözümü bulur.
  • Bu çözüme ulaşana kadar 876 kez guvenliMi çağrılır, 113 vezir yerleştirilir ve 105 kez geri dönülür.
  • Önceki slayttaki yerleşim (a1, b7, c4, d6, e8, f2, g5, h3) başka bir çözümdür; 92 çözümün hepsi geçerlidir.
  • Tüm çözümleri bulmak için satir == n olduğunda çözümü kaydedip false döndürmek (aramayı sürdürmek) yeterlidir.

N Vezir Problemi

N Vezir: Çözüm ve Yerleştirme Sayıları

nÇözümnⁿ (kaba)Yerleştirme (tümü)İlk çözüme kadar
11111
2042—
30275—
42256168
5103 125535
6446 65615231
740823 5435519
89216 777 2162056113
9352387 420 489839341
1072410 000 000 00035538102
  • n = 2 ve 3 için çözüm yoktur: algoritma tüm ağacı gezip false döner.
  • "Yerleştirme": güvenli bulunup tahtaya konan vezir sayısı (ağaçtaki kök dışı düğüm).
  • Tüm çözümleri bulma maliyeti nⁿ'den çok küçük, ama yine de hızla (yaklaşık n! gibi) büyür.
  • İlk çözüme kadar geçen iş n ile düzgün artmaz: n = 6'da 31, n = 7'de yalnız 9 yerleştirme.

N Vezir Problemi

Daha Hızlı Güvenlik Testi: O(1)

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

void coz(int r) {
  if (r == n) { sayac++; return; }
  for (int c = 0; c < n; c++) {
    int a = r + c, b = r - c + n - 1;
    if (sut[c] || k1[a] || k2[b])
      continue;
    sut[c] = k1[a] = k2[b] = true;
    coz(r + 1);
    sut[c] = k1[a] = k2[b] = false;
  }
}
01231234234534563210432154326543k1: r + ck2: r − c + n − 1
  • Aynı ters köşegendeki hücrelerde r + c sabittir (0 … 2n − 2).
  • Aynı köşegendeki hücrelerde r − c sabittir; + n − 1 ile indis 0'dan başlar.
Her vezir üç bayrak tutar: sütun, ters köşegen, köşegen. guvenliMi O(n) yerine O(1) olur; tahta dizisine bile gerek kalmaz (yalnızca yer[satir] = sutun).

N Vezir Problemi

Deneyin: N Vezir Geri Dönüşlü Arama

Kırmızı kare: tehdit altında · yeşil çerçeve: güvenli deneme · kırmızı çerçeve: reddedilen deneme · yeşil vezirler: çözüm.

En Az Çakışma

En Az Çakışma Sezgiseli (Min-Conflicts)

  • Farklı bir fikir: önce tüm vezirler yerleştirilir (her sütuna bir tane), sonra çakışmalar yerel değişikliklerle onarılır.
  • Her hücreye yazılan sayı: o satıra konacak vezirin kaç vezirle çakışacağı (satır + çaprazlar).
  • Başlangıç: sütun sütun, en az çakışmalı satırı seç (eşitlikte rastgele).
  • Onarım: çakışan bir vezir seç; sütunu içinde en az çakışmalı satıra taşı. Çakışma kalmayınca dur.
  • Bu bir yerel arama (local search) yöntemidir: geri dönüş yığını yoktur, tam değildir, ama büyük n'de son derece hızlıdır.
enAzCakisma(n, maksAdim):
  // başlangıç: açgözlü yerleşim
  for k = 0 .. n-1:
    yer[k] = en az çakışmalı satır
  for adim = 1 .. maksAdim:
    if çakışma yok: return yer
    k = rastgele çakışan sütun
    yer[k] = argmin_r cakisma(k, r)
             // eşitlikte rastgele
  return başarısız

En Az Çakışma

En Az Çakışma: Başlangıç Yerleşimi

000000000123456701234567

Sütun 0: henüz vezir yok, her satırın çakışma sayısı 0. Eşitlikte rastgele seçilir → satır 7.

00000011♛0123456701234567

Sütun 1 için her satırın çakışma sayısı yazıldı (önceki vezirlerle aynı satır/çapraz). En küçük değer 0 (satır 0, 1, 2, 3, 4, 5) → seçilen: satır 2.

01110101♛♛0123456701234567

Sütun 2 için her satırın çakışma sayısı yazıldı (önceki vezirlerle aynı satır/çapraz). En küçük değer 0 (satır 0, 4, 6) → seçilen: satır 4.

10113101♛♛♛0123456701234567

Sütun 3 için her satırın çakışma sayısı yazıldı (önceki vezirlerle aynı satır/çapraz). En küçük değer 0 (satır 1, 6) → seçilen: satır 1.

11311111♛♛♛♛0123456701234567

Sütun 4 için her satırın çakışma sayısı yazıldı (önceki vezirlerle aynı satır/çapraz). En küçük değer 1 (satır 0, 1, 3, 4, 5, 6, 7) → seçilen: satır 4. Hiçbir satır çakışmasız değil; çakışmaya izin verilir (kırmızı çizgi).

02222112♛♛♛♛♛0123456701234567

Sütun 5 için her satırın çakışma sayısı yazıldı (önceki vezirlerle aynı satır/çapraz). En küçük değer 0 (satır 0) → seçilen: satır 0.

23203012♛♛♛♛♛♛0123456701234567

Sütun 6 için her satırın çakışma sayısı yazıldı (önceki vezirlerle aynı satır/çapraz). En küçük değer 0 (satır 3, 5) → seçilen: satır 3.

22313102♛♛♛♛♛♛♛0123456701234567

Sütun 7 için her satırın çakışma sayısı yazıldı (önceki vezirlerle aynı satır/çapraz). En küçük değer 0 (satır 6) → seçilen: satır 6.

♛♛♛♛♛♛♛♛0123456701234567

Sekiz vezir yerleşti: [7, 2, 4, 1, 4, 0, 3, 6] (sütun sırasıyla satırlar). Yalnızca bir çift çakışıyor: (4, 2) ile (4, 4) aynı satırda. Şimdi onarım başlar.

Vurgulu sütun: karar verilen sütun · yeşil sayı: en az çakışma · kırmızı çizgi: çakışan çift.

En Az Çakışma

En Az Çakışma: Onarım Adımları

2333221♛♛♛♛♛♛♛♛0123456701234567

Çakışan vezirlerden biri seçilir: sütun 4 (şu an 1 çakışma). Diğer satırların en küçüğü 1 (satır 7) → vezir satır 7'ye taşınır.

1223212♛♛♛♛♛♛♛♛0123456701234567

Taşıma yeni bir çakışma doğurdu: sütun 0 ile sütun 4 artık aynı satırda (7). Sütun 0'ın seçenekleri: en küçük 1 (satır 0, 5). Toplam çakışan çift: 1.

3231132♛♛♛♛♛♛♛♛0123456701234567

Birkaç onarım adımı sonra: sütun 5'teki vezir satır 3'te, sütun 2 ile çakışıyor. En küçük değer 1 (satır 4, 5) → satır 4.

3231132♛♛♛♛♛♛♛♛0123456701234567

Satır 4'te bu kez (6, 7) ile çapraz çakışma var (1). Satır 3, 4, 5'in hepsi 1 çakışmalı: bir plato. Rastgele seçimle satır 5'e geçer.

3231132♛♛♛♛♛♛♛♛0123456701234567

Satır 5'te sütun 1 ile aynı satırda. Sütun 5 platoda 3 ↔ 4 ↔ 5 arasında birkaç kez gidip gelir; rastgele seçim sayesinde sonunda başka bir vezir seçilir.

2332221♛♛♛♛♛♛♛♛0123456701234567

Sütun 1 seçildi (satır 5, 1 çakışma). En küçük değer 1 (satır 7) → satır 7.

1313223♛♛♛♛♛♛♛♛0123456701234567

Şimdi sütun 1 ile sütun 4 satır 7'de çakışıyor. Sütun 4'ün en küçüğü 1 (satır 0, 2) → satır 2.

2220232♛♛♛♛♛♛♛♛0123456701234567

Sütun 0 ile sütun 4 satır 2'de çakışıyor. Sütun 0'da satır 4 0 çakışmalı → vezir oraya taşınır.

♛♛♛♛♛♛♛♛0123456701234567

Çakışan vezir kalmadı: çözüm [4, 7, 3, 0, 2, 5, 1, 6]. Algoritma 8 vezirin hepsini baştan yerleştirdi, sonra yalnızca yerel değişikliklerle çakışmaları giderdi.

Vurgulu sütundaki sayılar, kırmızı vezirin o satıra taşınması hâlinde kaç vezirle çakışacağını gösterir (vezirin kendi satırı boş bırakıldı).

En Az Çakışma

Geri Dönüşlü Arama ve En Az Çakışma

Geri dönüşlü aramaEn az çakışma
DurumKısmi ama hep geçerli yerleşimTam ama geçersiz olabilen yerleşim
HamleBir vezir ekle / geri alBir veziri sütunu içinde taşı
TamlıkTam: çözüm varsa bulur, yoksa kanıtlarTam değil: platoda dolaşabilir, adım sınırı gerekir
Tüm çözümlerHepsini sayabilir (92)Yalnızca bir çözüm
Büyük nn büyüdükçe hızla yavaşlarn = 1 000 000 için bile ortalama birkaç onlu adımda çözer
BellekO(n) yığınO(n) dizi
İkisi birleştirilebilir: geri dönüşlü aramada sıradaki değeri seçerken en az kısıtlayan değeri (least constraining value) önce denemek, en az çakışma fikrinin sistematik aramadaki karşılığıdır.

Sudoku

Sudoku

  • Sudoku'nun amacı, 9×9'luk bir karede her satır, her sütun ve her 3×3'lük küçük karede 1'den 9'a kadar olan rakamları birer kez kullanmaktır.
  • Bazı hücreler baştan verilir (ipucu); geri kalanlar doldurulur.
  • Bu bir kısıt sağlama problemidir (constraint satisfaction): değişkenler boş hücreler, alan {1, …, 9}, kısıtlar "aynı birimde farklı".
537619598686348317266284195879

Sudoku

Sudoku: Geri Dönüşlü Algoritma

  1. Boş bir hücreye bir rakam ata.
  2. Atanan rakam geçerliyse (satır, sütun ve kutuda yoksa) bir sonraki boş hücreye devam et.
  3. Geçerli değilse sıradaki rakamı dene.
  4. Bir hücrede tüm rakamlar denenmişse: önceki hücreye geri dön (backtrack) ve orada farklı bir rakam dene.
  5. Tüm hücreler dolana kadar adımları tekrarla.
Bu, genel şablonun doğrudan uygulamasıdır: kısmi çözüm = doldurulmuş hücreler, aday = 1–9, kısıt = gecerliMi, hedef = boş hücre kalmaması.

Sudoku

Sudoku: Java Kodu

boolean coz(int[][] t) {
  for (int s = 0; s < 9; s++)
    for (int k = 0; k < 9; k++)
      if (t[s][k] == 0) {
        for (int r = 1; r <= 9; r++)
          if (gecerliMi(t, s, k, r)) {
            t[s][k] = r;
            if (coz(t)) return true;
            t[s][k] = 0;   // geri al
          }
        return false;  // rakam yok
      }
  return true;  // boş hücre yok
}
boolean gecerliMi(int[][] t,
    int s, int k, int r) {
  for (int i = 0; i < 9; i++)
    if (t[s][i] == r || t[i][k] == r)
      return false;
  int bs = s / 3 * 3;
  int bk = k / 3 * 3;
  for (int i = bs; i < bs + 3; i++)
    for (int j = bk; j < bk + 3; j++)
      if (t[i][j] == r)
        return false;
  return true;
}

coz her çağrıda ilk boş hücreyi baştan arar (O(81)); bir hücrede hiçbir rakam olmazsa return false geri dönüşü tetikler.

Sudoku

Sudoku: Geri Dönüşlü Çözüm Adım Adım

537619598686348317266284195879

Bulmaca: 30 ipucu, 51 boş hücre. Boş hücreler satır satır, soldan sağa doldurulur; her hücrede 1–9 sırayla denenir.

53127489✗619598686348317266284195879

İlk beş boş hücreye 1, 2, 4, 8, 9 girildi. (0, 8) için hiçbir rakam geçerli değil: satırda yalnız 6 eksik, o da sütunda var → çıkmaz. (şu ana kadar 5 yerleştirme, 0 geri alma)

531276619598686348317266284195879

Geri dönüş: (0, 7)'deki 9 silinir, (0, 6) 9 ile denenir, yine çıkmaz; geri dönüş (0, 5)'e kadar sürer ve orada 4 yerine 6 denenir. (şu ana kadar 7 yerleştirme, 4 geri alma)

531276498619598686348317266284195879

Satır 0 ilk kez tamamlandı: 5 3 1 2 7 6 4 9 8. Bu satır kendi içinde geçerli, ama çözüme götürüp götürmediği henüz bilinmiyor. (şu ana kadar 10 yerleştirme, 4 geri alma)

53127649✗619598686348317266284195879

Satır 1'deki tüm denemeler çıkmaza girdi. Geri dönüş satır 0'a kadar uzanır: (0, 8)'deki 8 silinir. Erken verilen bir karar ancak çok sonra yanlış çıkabilir. (şu ana kadar 31 yerleştirme, 26 geri alma)

53167849262419573898686348317266284195879

Satır 1 ilk kez tamamlandı. (şu ana kadar 229 yerleştirme, 218 geri alma)

53267819464719532819823456786348317266284195879

Satır 2 ilk kez tamamlandı; ilk üç satır son çözümdekiyle aynı. (şu ana kadar 377 yerleştirme, 360 geri alma)

53267819464719532819823456782156794348317266284195879

Satır 3 ilk kez tamamlandı. (şu ana kadar 395 yerleştirme, 372 geri alma)

5326789146471958321982345678159674234268537917266284195879

Satır 4 ilk kez tamamlandı. (şu ana kadar 1520 yerleştirme, 1492 geri alma)

5346789126721953481983425678597614234268537917139248566284195879

Satır 5 ilk kez tamamlandı. (şu ana kadar 4185 yerleştirme, 4151 geri alma)

5346789126721953481983425678597614234268537917139248569615372844195879

Satır 6 ilk kez tamamlandı. (şu ana kadar 4197 yerleştirme, 4157 geri alma)

534678912672195348198342567859761423426853791713924856961537284287419635879

Satır 7 ilk kez tamamlandı. (şu ana kadar 4202 yerleştirme, 4157 geri alma)

534678912672195348198342567859761423426853791713924856961537284287419635345286179

Çözüm bulundu: 51 boş hücrenin hepsi dolu, tüm kısıtlar sağlanıyor. Toplam 4208 yerleştirme ve 4157 geri alma.

Siyah: ipucu · mavi: algoritmanın yazdığı rakam · turuncu: son yazılan hücre · kırmızı ✗: rakam kalmayan (çıkmaz) hücre.

Sudoku

Sudoku: Çözüm ve Maliyet

534678912672195348198342567859761423426853791713924856961537284287419635345286179
StratejiYerleştirmeGeri alma
Satır satır, ilk boş hücre42084157
MRV: en az adaylı hücre510
  • Kaba kuvvet: 51 boş hücre için 9⁵¹ ≈ 4,6 · 10⁴⁸ atama. Budama bunu birkaç bine indirir.
  • MRV (minimum remaining values): her adımda en az adayı kalan hücreyi doldur. Bu bulmacada her seferinde tek adaylı hücre bulunur: hiç geri dönüş gerekmez.

Diğer Problemler

Graf Boyama (m-Coloring)

Komşu iki düğüm aynı rengi almayacak biçimde düğümlere en fazla m renk ata. Kısmi çözüm: ilk k düğümün renkleri; kısıt: komşuyla aynı renk olmamak.

012345

Altı düğümlü graf, m = 3 renk (1 mavi, 2 yeşil, 3 turuncu). Düğümler 0, 1, 2, … sırasıyla boyanır; her düğümde renk 1, 2, 3 sırayla denenir.

0112345

Düğüm 0: renk 1 (mavi) uygun → atanır.

01122345

Düğüm 1: renk 1 komşuda var; renk 2 (yeşil) uygun → atanır.

011222345

Düğüm 2: renk 1 komşuda var; renk 2 (yeşil) uygun → atanır.

0112223145

Düğüm 3: renk 1 (mavi) uygun → atanır.

01122231435

Düğüm 4: renk 1, 2 komşuda var; renk 3 (turuncu) uygun → atanır.

0112223145

Düğüm 5: renk 1, 2, 3 komşularda kullanılıyor → hiçbir renk uygun değil (çıkmaz). Geri dön: düğüm 4'ün rengi (3) silinir, sıradaki renk denenecek.

011222345

Düğüm 4: denenecek başka renk kalmadı (çıkmaz). Geri dön: düğüm 3'ün rengi (1) silinir, sıradaki renk denenecek.

0112223345

Düğüm 3: renk 2 komşuda var; renk 3 (turuncu) uygun → atanır.

01122233415

Düğüm 4: renk 1 (mavi) uygun → atanır.

011222334153

Düğüm 5: renk 1, 2 komşuda var; renk 3 (turuncu) uygun → atanır. Altı düğüm de boyandı: geçerli 3-boyama bulundu.

Diğer Problemler

Hamilton Yolu (Hamiltonian Path)

Grafın her düğümünü tam bir kez ziyaret eden yol. Kısmi çözüm: yol[0..konum−1]; kısıt: yeni düğüm son düğüme komşu ve yolda yok.

01234yol[]001−12−13−14−1

yol[0] = 0; konum = 1. Her konumda düğümler 0, 1, 2, … sırasıyla denenir: önceki düğüme komşu ve yolda olmayan düğüm eklenebilir.

01234yol[]00112−13−14−1

Konum 1: düğüm 1 uygun → yol[1] = 1.

01234yol[]0011233−14−1

Konum 2: düğüm 3 uygun → yol[2] = 3.

01234yol[]001123324−1

Konum 3: düğüm 2 uygun → yol[3] = 2.

01234yol[]0011233−14−1

Konum 4: son düğüm 2'nin yolda olmayan (denenmemiş) komşusu kalmadı → çıkmaz. Geri dön: yol[3] = −1 (düğüm 2 çıkarılır).

01234yol[]001123344−1

Konum 3: düğüm 4 uygun → yol[3] = 4.

01234yol[]0011233−14−1

Konum 4: son düğüm 4'ün yolda olmayan (denenmemiş) komşusu kalmadı → çıkmaz. Geri dön: yol[3] = −1 (düğüm 4 çıkarılır).

01234yol[]00112−13−14−1

Konum 3: son düğüm 3'ün yolda olmayan (denenmemiş) komşusu kalmadı → çıkmaz. Geri dön: yol[2] = −1 (düğüm 3 çıkarılır).

01234yol[]0011243−14−1

Konum 2: düğüm 4 uygun → yol[2] = 4.

01234yol[]001124334−1

Konum 3: düğüm 3 uygun → yol[3] = 3.

01234yol[]0011243342

Konum 4: düğüm 2 uygun → yol[4] = 2. konum == 5: tüm düğümler yolda, Hamilton yolu bulundu: 0 → 1 → 4 → 3 → 2.

Diğer Problemler

Hamilton Yolu: Java Kodu

boolean bul(int[][] graf, int[] yol, int konum) {
  if (konum == graf.length) return true;
  for (int v = 0; v < graf.length; v++) {
    if (uygunMu(v, graf, yol, konum)) {
      yol[konum] = v;
      if (bul(graf, yol, konum + 1)) return true;
      yol[konum] = -1;     // geri al
    }
  }
  return false;
}

boolean uygunMu(int v, int[][] graf,
                int[] yol, int konum) {
  if (graf[yol[konum - 1]][v] == 0) return false;
  for (int i = 0; i < konum; i++)
    if (yol[i] == v) return false;
  return true;
}
  • graf: komşuluk matrisi; yol[0] = 0 ile başlanır, bul(graf, yol, 1) çağrılır.
  • Örnekteki 0 → 1 → 4 → 3 → 2 yolunda son düğüm 2 ile başlangıç 0 da komşudur; böyle bir yol aynı zamanda bir Hamilton döngüsüdür.
  • En kötü durum O(n!) yol; uygunMu O(n) → O(n · n!).

Diğer Problemler

Kelime Arama (Word Search)

Harf ızgarasında, komşu (yukarı/aşağı/sol/sağ) hücrelerden geçerek kelimeyi oluşturan bir yol var mı? Her hücre bir yolda en fazla bir kez kullanılır.

ABCESFCSADEE

Aranan kelime "SEE". Her hücre başlangıç olarak denenir (satır satır); komşu yönler: yukarı, aşağı, sol, sağ. Bir hücre aynı yolda iki kez kullanılamaz.

ABCESFCSADEE0

(1, 0) = 'S' kelimenin 0. harfiyle eşleşti → ziyaret edildi olarak işaretlenir.

ABCESFCSADEE

(1, 0) hücresinden hiçbir komşu 'E' ile devam etmiyor → geri dön, işaret kaldırılır.

ABCESFCSADEE0

(1, 3) = 'S' kelimenin 0. harfiyle eşleşti → ziyaret edildi olarak işaretlenir.

ABCESFCSADEE01

(0, 3) = 'E' kelimenin 1. harfiyle eşleşti → ziyaret edildi olarak işaretlenir.

ABCESFCSADEE0

(0, 3) hücresinden hiçbir komşu 'E' ile devam etmiyor → geri dön, işaret kaldırılır.

ABCESFCSADEE01

(2, 3) = 'E' kelimenin 1. harfiyle eşleşti → ziyaret edildi olarak işaretlenir.

ABCESFCSADEE012

(2, 2) = 'E' kelimenin 2. harfiyle eşleşti → ziyaret edildi olarak işaretlenir. Son harf de eşleşti: "SEE" bulundu.

Diğer Problemler

Kelime Arama: Java Kodu

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;
}
KelimeSonuç
ABCCEDvar
SEEvar
ABCByok: B iki kez kullanılamaz
SADEvar

Izgara: ABCE / SFCS / ADEE. Geri dönüşte ziyaret işareti kaldırılmalıdır; yoksa hücre başka bir yolda kullanılamaz.

Diğer Problemler

Geri Dönüşle Çözülen Diğer Problemler

ProblemHer seviyedeki seçimBudama (kısıt)
Alt küme toplamı / sırt çantasıi. eleman alınsın mı? (2 dal)toplam / ağırlık sınırı aşıldı
Gezgin satıcı (TSP)sıradaki şehiryol, bilinen en iyi turdan uzun
Kutu yerleştirme (bin packing)eşya hangi kutuya?kutu kapasitesi aşıldı
Maksimum kapsamaküme seçilsin mi?kalan kümelerle iyileşme mümkün değil
Mantıksal doyurulabilirlik (SAT)değişken = doğru / yanlışbir cümle (clause) yanlış oldu
Mayın tarlasıhücre mayın mı?açılmış sayılarla çelişki
Permütasyon / kombinasyon üretimisıradaki elemaneleman zaten kullanıldı

Eniyileme problemlerinde (TSP, sırt çantası) "bilinen en iyiden kötü" dalı kesmek dal ve sınır (branch and bound) yönteminin temelidir: Bölüm 14.

Analiz

Karmaşıklık

ProblemEn kötü zamanAçıklama
N vezirO(n!)satır başına bir vezir, sütunlar farklı; dizili test ile O(n · n!)
SudokuO(9ᵐ)m: boş hücre sayısı; her hücrede 9 aday
Graf m-boyamaO(n · mⁿ)n düğüm, her biri m renk; denetim O(derece)
Hamilton yoluO(n · n!)yoldaki her konum için kalan düğümler
Kelime aramaO(R · C · 3ᴸ)ilk harften sonra en fazla 3 yeni yön (geri gelinen hücre ziyaretli)
Alt kümeler / permütasyonlarO(2ⁿ) / O(n · n!)ağaçtaki yaprak sayısı
Zaman = düğüm sayısı × düğüm başı işBudama düğüm sayısını küçültür ama en kötü durumu (çoğu zaman) değiştirmez.
Bellek: O(derinlik)Yalnızca tek bir kısmi çözüm ve yığındaki çerçeveler tutulur (ör. N vezirde O(n)).

Analiz

Budamayı Güçlendirme: Sezgiseller

Değişken sıralaması (MRV)En az seçeneği kalan değişkeni önce doldur. Sudoku'da geri dönüşü tamamen ortadan kaldırabilir.
Değer sıralamasıÖnce en az kısıtlayan değeri dene (en az çakışma fikri). Çözüm daha erken bulunur.
İleri denetim (forward checking)Atamadan sonra komşu değişkenlerin alanlarından çelişen değerleri sil; alanı boşalan varsa hemen geri dön.
Hızlı kısıt testiN vezirde sütun/köşegen bayrakları, Sudoku'da satır/sütun/kutu bit maskeleri: test O(1).
Simetri kırmaN vezirde ilk vezir yalnızca sol yarıda denenir, sonuç yansıtılır: iş yaklaşık yarıya iner.
Sınır (bound)Eniyilemede kısmi çözümün en iyi olası değeri, bilinen en iyi çözümden kötüyse dalı kes: dal ve sınır.

Analiz

Paradigmaların Karşılaştırması

ParadigmaFikirNe zaman?
Kaba kuvvetTüm adayları üret, sonra test etUzay çok küçükse
Açgözlü (Bölüm 12)Her adımda yerel en iyi; geri dönmezAçgözlü seçim özelliği kanıtlanmışsa
Dinamik programlamaÖrtüşen alt problemleri bir kez çöz, saklaAlt problem sayısı polinom ise
Geri dönüşlüKısmi çözümü genişlet, geçersizse geri alKısıt sağlama; tüm çözümler; karar problemleri
Dal ve sınır (Bölüm 14)Geri dönüş + en iyi çözüme göre sınır ile budamaEniyileme (TSP, sırt çantası)
Geri dönüşlü arama, durum uzayı ağacında derinlik öncelikli aramadır (DFS); ağaç önceden kurulmaz, gezilirken üretilir ve geçersiz dallar hiç üretilmez.

Özet

Özet

KonuHatırlanacaklar
Fikirkısmi çözümü adım adım kur; kısıt bozulursa son kararı geri al, sıradakini dene
Şablonhedef testi → her aday için: geçerliyse seç, özyinele, geri al
Durum uzayıDFS ile gezilen ağaç; budama geçersiz alt ağaçları atlar
N vezirsatır satır; sütun + 2 çapraz denetimi; 8 için 92 çözüm, ilk: [0, 4, 7, 5, 2, 6, 1, 3]
En az çakışmatam yerleşim + yerel onarım; hızlı ama tam değil
Sudokuboş hücreye 1–9; satır/sütun/kutu denetimi; MRV ile çok daha hızlı
Diğerlerigraf boyama, Hamilton yolu, kelime arama (ziyaret işaretini geri al!)
Maliyeten kötü üstel (2ⁿ, n!, 9ᵐ); bellek O(derinlik)

Özet

Sık Yapılan Hatalar

Geri almayı unutmakÖzyinelemeden dönünce t[s][k] = 0, ziyaret = false yapılmazsa eski seçim sonraki dalları bozar.
Sonucu yaymamakif (coz(...)) return true; yerine yalnızca coz(...) yazmak: çözüm bulunsa da arama sürer ve tahta geri alınır.
Erken return falseİlk geçersiz adayda döngüden çıkmak; sıradaki adaylar hiç denenmez.
Paylaşılan listeyi kaydetmekTüm çözümleri toplarken sonuclar.add(yol) yerine kopya (new ArrayList<>(yol)) eklenmeli.
Eksik kısıt denetimiN vezirde yalnız bir çaprazı, Sudoku'da 3×3 kutuyu unutmak: geçersiz "çözümler".
Yerel aramayı tam sanmakEn az çakışma çözüm olmadığını kanıtlayamaz; adım sınırına ulaşmak "çözüm yok" demek değildir.

Özet

Örnek Problemler

  1. 4 vezir: coz(t, 0) ilk çözümü bulana kadar kaç vezir yerleştirir, kaç kez geri döner?
  2. 5 vezir için algoritmanın ilk çözümü nedir? Kaç kez geri dönülür?
  3. {3, 5, 6, 7} içinde toplamı 15 olan alt küme (önce "al" dalı; toplam aşılınca budama). İlk bulunan?
  4. 5 düğümlü döngü grafı (C₅) 2 renkle boyanabilir mi? En az kaç renk gerekir?
  5. ABCE / SFCS / ADEE ızgarasında "ABCB" neden bulunamaz, "SADE" hangi yolla bulunur?
  6. 8 vezir: 8⁸ tam yerleşimi test etmek ile geri dönüşlü aramayı (tüm çözümler) karşılaştırın.
Cevapları göster
  1. 8 yerleştirme, 4 geri dönüş; çözüm [1, 3, 0, 2].
  2. [0, 2, 4, 1, 3]; hiç geri dönülmez (5 yerleştirme).
  3. 3, 5, 6 (14) → +7 = 21 > 15 budanır; 6 çıkarılır → 3, 5, 7 = 15: {3, 5, 7}.
  4. Hayır: tek uzunluklu döngü 2 renkle boyanamaz (5. düğüm hem 1. hem 4. düğümle komşu). 3 renk gerekir.
  5. ABCB: A→B→C'den sonra komşu B, zaten kullanılan (0, 1) hücresi. SADE: (1, 0) S → (2, 0) A → (2, 1) D → (2, 2) E.
  6. 8⁸ = 16 777 216 tam yerleşim; geri dönüşlü arama 2056 güvenli yerleştirme yapar (~8 000 kat az).

Özet

Alıştırmalar

  1. N vezir kodunu tüm çözümleri sayacak biçimde değiştirin (n = 8).
  2. {1, 2, 3}'ün permütasyonlarını geri dönüşle üretin. Ağaçta kök dahil kaç düğüm vardır?
  3. Hamilton yolu kodunu Hamilton döngüsü arayacak biçimde değiştirin; Hamilton yolu slaytındaki 5 düğümlü grafta sonuç?
  4. Sudoku çözücüsüne MRV (en az adaylı hücre önce) ekleyin.
  5. Labirent örneğinde girişten çıkışa kaç farklı basit yol vardır?
  6. Alt küme toplamına "kalan elemanlar yetmiyorsa kes" budamasını ekleyin.
Cevaplar / ipuçları
  1. satir == n iken sayac++; return false; → n = 8 için 92.
  2. 1 + 3 + 6 + 6 = 16 düğüm; 6 yaprak = 3!.
  3. konum == n iken graf[yol[n-1]][yol[0]] == 1 de istenir; 0 → 1 → 4 → 3 → 2 yolu 2 → 0 kenarıyla kapanır: döngü var.
  4. Örnek bulmacada 51 yerleştirme, 0 geri alma (4 208 yerine).
  5. 1 yol: sol-alt bölge çıkmaz, yalnız üst koridor çıkışa varır.
  6. if (toplam + kalan[i] < hedef) return false; (kalan[i]: sonek toplamı).

Özet

Kaynaklar

  • Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, MIT Press, 2022.
  • Levitin, Introduction to the Design and Analysis of Algorithms, 3. baskı, Pearson, 2012 (Bölüm 12: Backtracking).
  • Russell ve Norvig, Artificial Intelligence: A Modern Approach, 4. baskı, 2020 (Bölüm 6: kısıt sağlama, en az çakışma).
  • S. Minton, M. Johnston, A. Philips ve P. Laird, "Minimizing Conflicts: A Heuristic Repair Method for Constraint Satisfaction and Scheduling Problems", Artificial Intelligence 58, 1992.
  • D. E. Knuth, The Art of Computer Programming, Cilt 4B, 2022 (Backtrack programming, Dancing Links).

Son

Bölüm 13: Geri Dönüşlü Algoritmalar
Sonraki bölüm: Bölüm 14: Dal Sınır Algoritmaları
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.