Bölüm 11: Böl ve Fethet Yaklaşımı

Algoritmalar
Böl · Parçala · Yönet · BirleştirÖzyineleme ağacıAna teorem İkili arama ve sıralamaHızlı üs almaQuickhull En yakın nokta çiftiKaratsubaStrassen
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Paradigma

Böl ve fethet (divide and conquer) yaklaşımının adımlarını açıklamak; bir problemin bu yaklaşıma uygun olup olmadığına karar vermek.

Analiz

Özyineleme bağıntısını (recurrence) kurmak; özyineleme ağacı ve ana teorem (master theorem) ile çözmek.

Geometrik algoritmalar

Quickhull ile dışbükey örtüyü ve şerit yöntemiyle en yakın nokta çiftini adım adım bulmak.

Hızlı çarpma

Karatsuba (tam sayı) ve Strassen (matris) çarpımının, bir özyinelemeli çağrıyı eksilterek nasıl kazanç sağladığını göstermek.

Paradigma

Böl–Parçala–Yönet Paradigması

Karmaşık problemleri çözmek için kullanılan etkili bir yöntemdir (divide and conquer, böl ve fethet / böl ve yönet). Şu adımları izler:

  1. Böl: karmaşık problemi daha küçük, yönetilebilir alt problemlere böl.
  2. Parçala: alt problemleri, doğrudan çözülebilecek kadar küçülene dek bölmeye devam et (özyineleme).
  3. Yönet: her bir alt problemi ayrı ayrı çöz.
  4. Birleştir: alt problemlerin çözümlerini birleştirerek asıl çözümü kur.
Problem (n)n/2n/2n/4n/4n/4n/4çözümçözümÇözüm (n)1 Böl2 Parçala3 Yönet4 Birleştir
Anahtar: alt problemler asıl problemle aynı türdendir ama daha küçüktür ve birbirinden bağımsızdır; bu yüzden aynı fonksiyon kendini özyinelemeli çağırır.

Paradigma

Neden Böl ve Fethet?

  • Karmaşık problemi küçük ve yönetilebilir parçalara ayırır; problem daha anlaşılır hale gelir, çözümü kolaylaşır.
  • Alt problemlerin çözüm yöntemi (aynı fonksiyon) her düzeyde tekrar kullanılır: kısa ve yeniden kullanılabilir kod.
  • Sıralama, arama, hesaplamalı geometri, büyük sayı ve matris aritmetiği, yapay zekâ oyunları gibi alanlarda kullanılır.

Avantajlar

  • Çoğu zaman asimptotik kazanç: O(n²) → O(n log n), O(n) → O(log n).
  • Bağımsız alt problemler paralel çözülebilir (Bölüm 10).
  • Alt problemler küçüldükçe önbelleğe sığar: iyi bellek yerelliği.
  • Doğruluk kanıtı tümevarımla kolaydır.

Dezavantajlar

  • Özyineleme yükü: çağrı yığını, ek bellek (ör. birleştirerek sıralamada O(n)).
  • Alt problemler örtüşüyorsa aynı iş tekrar tekrar yapılır → üstel süre.
  • Küçük n için sabit çarpanlar ağır basar; pratikte bir eşiğin altında basit yönteme geçilir.

Paradigma

Genel Şablon ve Bağıntı

Sonuc bolVeFethet(Problem p) {
  if (p.boyut() <= ESIK)
    return dogrudanCoz(p);          // taban durumu
  Problem[] alt = bol(p);           // a alt problem, boyut n/b
  Sonuc[] cozum = new Sonuc[alt.length];
  for (int i = 0; i < alt.length; i++)
    cozum[i] = bolVeFethet(alt[i]); // yönet: özyineleme
  return birlestir(cozum);          // birleştir
}
Çalışma süresi:
T(n) = a·T(n/b) + f(n)
a: alt problem sayısı · n/b: alt problem boyutu · f(n): bölme + birleştirme maliyeti
  • Taban durumu olmadan özyineleme bitmez.
  • Bölme dengeli olmalı: n/2 + n/2 iyi, 1 + (n − 1) kötü.
  • Hız kazancı genellikle a'yı azaltmaktan (Karatsuba, Strassen) ya da f(n)'yi küçültmekten gelir.

Paradigma

Klasik Böl ve Fethet Algoritmaları

AlgoritmaBölBirleştirBağıntıSüre
İkili aramaortadaki elemana bak, bir yarıyı atyokT(n/2) + O(1)O(log n)
Birleştirerek sıralamadiziyi ortadan ikiye bölsıralı yarıları birleştir2T(n/2) + O(n)O(n log n)
Hızlı sıralamapivota göre bölümleyok (yerinde)T(k) + T(n−k−1) + O(n)ort. O(n log n)
Hızlı üs almaxⁿ = (x⌊n/2⌋)²·(x)kare alT(n/2) + O(1)O(log n)
Quickhullen uzak noktayla üçgenörtü parçalarını ekleT(n₁) + T(n₂) + O(n)ort. O(n log n)
En yakın nokta çiftix'e göre ortadan bölorta şeridi tara2T(n/2) + O(n)O(n log n)
Karatsubasayıyı iki yarıya böl3 çarpımı topla3T(n/2) + O(n)O(n1,585)
Strassenmatrisi 4 bloğa böl7 çarpımı topla7T(n/2) + O(n²)O(n2,807)

Özyineleme Bağıntıları

Özyineleme Ağacı (Recursion Tree)

Her düğüm bir çağrının kendi işini (bölme + birleştirme) gösterir. Düzey toplamları alt alta toplanınca T(n) bulunur.

nnn/2n/22 · n/2 = nn/4n/4n/4n/44 · n/4 = n⋮111…111n · Θ(1) = ndüzey maliyetilog₂ n düzey × n → T(n) = Θ(n log n)

T(n) = 2T(n/2) + n (birleştirerek sıralama): her düzeyin toplamı n, düzey sayısı log₂ n → Θ(n log n).

nnn/2n/2n/23 · n/2 = 1,5 nn/4n/4n/4n/4n/4n/4n/4n/4n/49 · n/4 = 2,25 n⋮111…1113log₂ n = nlog₂ 3düzey maliyetiartan geometrik seri → yapraklar baskın: T(n) = Θ(n1,585)

T(n) = 3T(n/2) + n (Karatsuba): düzey toplamları 1,5 kat büyür; en çok iş yapraklarda → Θ(nlog₂3).

n1n/21n/41⋮11düzey maliyetilog₂ n düzey × O(1) → T(n) = Θ(log n)

T(n) = T(n/2) + 1 (ikili arama, hızlı üs alma): tek dal, her düzey O(1) → Θ(log n).

Özyineleme Bağıntıları

Ana Teorem (Master Theorem)

a ≥ 1, b > 1 olmak üzere T(n) = a·T(n/b) + f(n). Kritik üs c* = logb a: yaprak sayısı nc* olur. f(n) ile nc* karşılaştırılır:

DurumKoşulSonuçYorum
1f(n) = O(nc* − ε), ε > 0Θ(nc*)yapraklar baskın
2f(n) = Θ(nc*)Θ(nc* · log n)her düzey eşit pay
3f(n) = Ω(nc* + ε) ve a·f(n/b) ≤ k·f(n), k < 1Θ(f(n))kök baskın
Uygulanamadığı durumlar: eşit olmayan bölmeler (T(n) = T(n/3) + T(2n/3) + n), sabit azaltma (T(n) = T(n − 1) + n), arada kalan f(n) (T(n) = 2T(n/2) + n/log n). Bunlarda özyineleme ağacı veya yerine koyma yöntemi kullanılır.

Özyineleme Bağıntıları

Ana Teorem Uygulamaları

Algoritmaabf(n)nlogb aDurumT(n)
İkili arama, hızlı üs alma121n⁰ = 12Θ(log n)
Birleştirerek sıralama, en yakın çift22nn2Θ(n log n)
Karatsuba32nn1,5851Θ(n1,585)
Saf blok matris çarpımı82n²n³1Θ(n³)
Strassen72n²n2,8071Θ(n2,807)
Ağaç gezinme (dengeli)221n1Θ(n)
T(n) = 2T(n/2) + n²22n²n3Θ(n²)

Karatsuba ve Strassen'in tüm kazancı a'yı bir azaltmaktan gelir: 4 → 3 ve 8 → 7. Durum 1'de üs doğrudan logb a'dır.

Temel Örnekler

İkili Arama (Binary Search): 23'ü Ara

205182123164235386567728919altortaust

alt = 0, ust = 9 → orta = 4: dizi[4] = 16 < 23 → sol yarı atılır, alt = 5.

205182123164235386567728919altortaust

alt = 5, ust = 9 → orta = 7: dizi[7] = 56 > 23 → sağ yarı atılır, ust = 6.

205182123164235386567728919alt,ortaust

alt = 5, ust = 6 → orta = 5: dizi[5] = 23 = 23 → bulundu. Yalnızca 3 karşılaştırma (doğrusal aramada 6).

int ara(int[] dizi, int alt, int ust, int aranan) {
  if (alt > ust) return -1;                  // boş aralık
  int orta = (alt + ust) / 2;
  if (dizi[orta] == aranan) return orta;
  if (dizi[orta] < aranan)
    return ara(dizi, orta + 1, ust, aranan); // sağ yarı
  return ara(dizi, alt, orta - 1, aranan);   // sol yarı
}
  • Böl: ortadaki eleman. Yönet: yalnızca bir yarıda devam. Birleştir: yok.
  • T(n) = T(n/2) + O(1) = O(log n); dizi sıralı olmalı.
  • Tek dallı olduğu için "azalt ve fethet" (decrease and conquer) de denir.

Temel Örnekler

Birleştirerek Sıralama (Merge Sort)

Böl382743398210BölBölTabanBirleştirBirleştirBirleştir

Dizi: [38, 27, 43, 3, 9, 82, 10], n = 7.

Böl382743398210Böl382743398210BölTabanBirleştirBirleştirBirleştir

Böl: orta = (0 + 6)/2 = 3 → [38 27 43 3] ve [9 82 10].

Böl382743398210Böl382743398210Böl382743398210TabanBirleştirBirleştirBirleştir

Yarılar yeniden bölünür: [38 27] [43 3] [9 82] [10].

Böl382743398210Böl382743398210Böl382743398210Taban382743398210BirleştirBirleştirBirleştir

Tek elemanlı diziler zaten sıralıdır: taban durumu.

Böl382743398210Böl382743398210Böl382743398210Taban382743398210Birleştir273834398210BirleştirBirleştir

Birleştir: ikililer sıralı birleşir: [27 38] [3 43] [9 82] [10].

Böl382743398210Böl382743398210Böl382743398210Taban382743398210Birleştir273834398210Birleştir327384391082Birleştir

[3 27 38 43] ve [9 10 82]: her birleştirme, iki yarının uzunluk toplamı kadar adım.

Böl382743398210Böl382743398210Böl382743398210Taban382743398210Birleştir273834398210Birleştir327384391082Birleştir391027384382

Son birleştirme: [3 9 10 27 38 43 82]. Her düzey O(n), ⌈log₂ 7⌉ = 3 düzey.

Temel Örnekler

Birleştirerek Sıralama: Kod ve Analiz

void birlestirSirala(int[] dizi, int alt, int ust) {
  if (alt >= ust) return;               // taban: 0-1 eleman
  int orta = (alt + ust) / 2;
  birlestirSirala(dizi, alt, orta);     // sol yarı
  birlestirSirala(dizi, orta + 1, ust); // sağ yarı
  birlestir(dizi, alt, orta, ust);      // birleştir: O(n)
}
void birlestir(int[] dizi, int alt, int orta, int ust) {
  int[] t = new int[ust - alt + 1];
  int i = alt, j = orta + 1, k = 0;
  while (i <= orta && j <= ust)
    t[k++] = (dizi[i] <= dizi[j]) ? dizi[i++] : dizi[j++];
  while (i <= orta) t[k++] = dizi[i++];
  while (j <= ust)  t[k++] = dizi[j++];
  System.arraycopy(t, 0, dizi, alt, t.length);
}
  • İş birleştirme adımında yapılır; bölme O(1).
  • T(n) = 2T(n/2) + Θ(n) → durum 2 → Θ(n log n); en iyi, ortalama ve en kötü durumda aynı.
  • dizi[i] <= dizi[j] eşitlikte soldakini alır → kararlı (stable).
  • Ek bellek: O(n) geçici dizi; çağrı yığını O(log n).
  • Ayrıntılı görselleştirme: Bölüm 2.

Temel Örnekler

Hızlı Sıralama (Quick Sort)

100801302903404505706pivot

Dizi [10 80 30 90 40 50 70]; Lomuto bölümlemesi: son eleman pivot (70).

100301402503704905806pivot

bölümle(dizi, 0, 6), pivot 70 → indis 4'e yerleşti. Sol: [10 30 40 50], sağ: [90 80].

100301402503704905806pivot

bölümle(dizi, 0, 3), pivot 50 → indis 3'e yerleşti. Sol: [10 30 40], sağ: [—]. Dengesiz bölme!

100301402503704905806pivot

bölümle(dizi, 0, 2), pivot 40 → indis 2'ye yerleşti. Sol: [10 30], sağ: [—]. Dengesiz bölme!

100301402503704905806pivot

bölümle(dizi, 0, 1), pivot 30 → indis 1'e yerleşti. Sol: [10], sağ: [—]. Dengesiz bölme!

100301402503704805906pivot

bölümle(dizi, 5, 6), pivot 80 → indis 5'e yerleşti. Sol: [—], sağ: [90]. Dengesiz bölme!

100301402503704805906

Sıralı: [10 30 40 50 70 80 90]. Birleştirme adımı yok; iş bölümlemede yapılır.

Dengeli bölmePivot ortanca civarındaysa T(n) = 2T(n/2) + O(n) → O(n log n) (ortalama durum).
Dengesiz bölmeSıralı girişte son eleman pivot: T(n) = T(n − 1) + O(n) → O(n²). Çare: rastgele pivot, üçün ortancası.

Temel Örnekler · Kodu adım adım çalıştır

Hızlı Üs Alma: 3¹³ İzleme

long us(long x, int n) {
  if (n == 0) return 1;         // taban
  long y = us(x, n / 2);
  if (n % 2 == 0) return y * y; // çift
  return x * y * y;             // tek
}

Saf yöntem 12 çarpım; bu yöntem 4 düzeyde en çok 2'şer çarpım → O(log n): T(n) = T(n/2) + O(1).

n=13n=6n=3n=1n=03¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

us(3, 13) çağrıldı → önce us(3, 6) hesaplanmalı (n/2 = 6).

n=13n=6n=3n=1n=03¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

us(3, 6) çağrıldı → önce us(3, 3) hesaplanmalı (n/2 = 3).

n=13n=6n=3n=1n=03¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

us(3, 3) çağrıldı → önce us(3, 1) hesaplanmalı (n/2 = 1).

n=13n=6n=3n=1n=03¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

us(3, 1) çağrıldı → önce us(3, 0) hesaplanmalı (n/2 = 0).

n=13n=6n=3n=1n=0= 13¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

n = 0 → taban durumu: 3⁰ = 1 döner.

n=13n=6n=3n=1= 3n=0= 13¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

us(3, 1): y = 1; 1 tek → x·y·y = 3·1·1 = 3.

n=13n=6n=3= 27n=1= 3n=0= 13¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

us(3, 3): y = 3; 3 tek → x·y·y = 3·3·3 = 27.

n=13n=6= 729n=3= 27n=1= 3n=0= 13¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

us(3, 6): y = 27; 6 çift → y·y = 27·27 = 729.

n=13= 1594323n=6= 729n=3= 27n=1= 3n=0= 13¹³ = 3·(3⁶)²; 3⁶ = (3³)²; 3³ = 3·(3¹)²

us(3, 13): y = 729; 13 tek → x·y·y = 3·729·729 = 1594323.

Temel Örnekler

Ne Zaman Uygun Değil? Örtüşen Alt Problemler

F(5)F(4)F(3)F(2)F(1)F(0)F(1)F(2)F(1)F(0)F(3)F(2)F(1)F(0)F(1)
long fib(int n) {
  if (n < 2) return n;
  return fib(n - 1) + fib(n - 2);
}
  • F(5) için 15 çağrı: F(3) 2 kez, F(2) 3 kez hesaplanır.
  • Alt problemler bağımsız değil, örtüşüyor → T(n) = T(n−1) + T(n−2) + O(1) = O(φⁿ) ≈ O(1,618ⁿ).
  • Çözüm: sonuçları sakla → dinamik programlama (Bölüm 6), O(n).
Fibonacci özyinelemesi böl ve fethet biçiminde yazılabilir; sonuç doğrudur, ama bu kötü bir örnektir: böl ve fethet, alt problemler birbirinden bağımsız olduğunda verimlidir.

Dışbükey Örtü

Dışbükey Örtü (Convex Hull)

  • Düzlemde n noktalı bir küme S verilsin. S'nin dışbükey örtüsü, S'yi içeren en küçük dışbükey çokgendir.
  • Sezgi: noktalara çivi çakıp etrafına bir lastik bant geçirin; bandın aldığı şekil örtüdür.
  • Örtünün köşeleri S'nin noktalarıdır; çıktı bu köşelerin (saat yönünün tersine) sıralı listesidir.
  • Dışbükey: içindeki herhangi iki noktayı birleştiren doğru parçası tamamen çokgenin içindedir.
010203001020
Kullanım: çarpışma algılama (oyunlar, robotik), coğrafi bilgi sistemleri, görüntü işlemede şekil analizi, en uzak nokta çifti, kümeleme.

Dışbükey Örtü

Quickhull Algoritması

  1. x'i en küçük (A) ve en büyük (B) noktaları bul; ikisi de örtüdedir.
  2. AB doğrusu ile noktaları iki alt kümeye ayır: doğrunun üstü (solu) ve altı (sağı).
  3. Bir alt kümede AB'ye en uzak C noktasını bul; C örtüdedir.
  4. ACB üçgeninin içindeki noktaları yok say: örtüde olamazlar.
  5. AC'nin dışında kalanlar ve CB'nin dışında kalanlar için özyinele.
  6. Hiç nokta kalmayınca dur; bulunan noktalar örtüyü oluşturur.
010203001020AB

Adım 1–2: en soldaki A ve en sağdaki B örtüdedir; AB doğrusu noktaları iki kümeye ayırır (üst / alt).

010203001020ABC

Adım 3–5: üst kümede AB'ye en uzak C (13,27) örtüdedir. ACB üçgeninin içindeki 4 nokta elenir; AC ve CB dışında kalanlarla özyineleme.

010203001020

Adım 6: dışarıda nokta kalmayana dek özyineleme → 7 köşeli örtü.

Hızlı sıralamaya benzer (adı da buradan): "pivot" en uzak nokta, bölümleme üçgenin iki kenarına göre yapılır.

Dışbükey Örtü

Geometri: Yönelim Testi ve Uzaklık

Quickhull yalnızca tam sayı çarpımıyla çalışır; açı, karekök, bölme gerekmez:

long capraz(Nokta A, Nokta B, Nokta P) {
  return (long)(B.x - A.x) * (P.y - A.y)
       - (long)(B.y - A.y) * (P.x - A.x);
}
  • capraz > 0: P, A→B'nin solunda; < 0: sağında; = 0: aynı doğruda.
  • |capraz| = 2 × (ABP üçgeninin alanı) = |AB| × uzaklık. |AB| sabit olduğundan en uzak nokta = en büyük capraz.
uzaklıkABP: capraz > 0 (sol)Q: capraz < 0 (sağ)
Örnek: A = (2,18), B = (35,11). C = (13,27) için capraz = 33·9 − (−7)·11 = 374; (28,23) için 33·5 + 7·26 = 347. En büyük değer C'de → C en uzak nokta.

Dışbükey Örtü · Kodu adım adım çalıştır

Quickhull: Kod İzleme

void quickHull(List<Nokta> P) {
  Nokta A = enSol(P), B = enSag(P);
  ortu.add(A); ortu.add(B);
  bul(solda(P, A, B), A, B); // üst küme
  bul(solda(P, B, A), B, A); // alt küme
}
void bul(List<Nokta> S, Nokta A, Nokta B) {
  if (S.isEmpty()) return;   // AB örtü kenarı
  Nokta C = enUzak(S, A, B); // max capraz
  ortu.add(C);
  bul(solda(S, A, C), A, C); // AC'nin dışı
  bul(solda(S, C, B), C, B); // CB'nin dışı
}  // ACB üçgeninin içi elenir
010203001020AB

En sol A = (2,18), en sağ B = (35,11) örtüye eklenir.

010203001020AB

AB'nin solunda (üst) 8, sağında (alt) 6 nokta. Önce üst küme.

010203001020

|S| = 8: en uzak C = (13,27) örtüye girer. Üçgen içinde 4 nokta elenir; AC dışında 1, CB dışında 2 nokta.

010203001020

|S| = 1: en uzak C = (4,25) örtüye girer. Üçgen içinde 0 nokta elenir; AC dışında 0, CB dışında 0 nokta.

010203001020

S boş → (2,18)–(4,25) bir örtü kenarıdır; geri dön.

010203001020

S boş → (4,25)–(13,27) bir örtü kenarıdır; geri dön.

010203001020

|S| = 2: en uzak C = (28,23) örtüye girer. Üçgen içinde 1 nokta elenir; AC dışında 0, CB dışında 0 nokta.

010203001020

S boş → (13,27)–(28,23) bir örtü kenarıdır; geri dön.

010203001020

S boş → (28,23)–(35,11) bir örtü kenarıdır; geri dön.

010203001020

|S| = 6: en uzak C = (20,2) örtüye girer. Üçgen içinde 4 nokta elenir; AC dışında 0, CB dışında 1 nokta.

010203001020

S boş → (35,11)–(20,2) bir örtü kenarıdır; geri dön.

010203001020

|S| = 1: en uzak C = (10,5) örtüye girer. Üçgen içinde 0 nokta elenir; AC dışında 0, CB dışında 0 nokta.

010203001020

S boş → (20,2)–(10,5) bir örtü kenarıdır; geri dön.

010203001020

S boş → (10,5)–(2,18) bir örtü kenarıdır; geri dön.

010203001020

Bitti: 7 köşe bulundu, 9 nokta elendi. Toplam 12 bul çağrısı.

Dışbükey Örtü

Quickhull: 104 Noktalı Örnek

050100050100

104 nokta. En sol (-14,46) ve en sağ (106,20) birleştirilir; üstte 71, altta 31 nokta.

050100050100

(-14,46)→(106,20) için en uzak: (54,120); üçgen içindeki 56 nokta elendi. Aday kaldı: 45.

050100050100

(-14,46)→(54,120) için en uzak: (8,84); üçgen içindeki 2 nokta elendi. Aday kaldı: 42.

050100050100

(-14,46)→(8,84) için en uzak: (-4,69); üçgen içindeki 0 nokta elendi. Aday kaldı: 41.

050100050100

(8,84)→(54,120) için en uzak: (42,111); üçgen içindeki 1 nokta elendi. Aday kaldı: 39.

050100050100

(54,120)→(106,20) için en uzak: (104,74); üçgen içindeki 6 nokta elendi. Aday kaldı: 32.

050100050100

(54,120)→(104,74) için en uzak: (77,103); üçgen içindeki 0 nokta elendi. Aday kaldı: 31.

050100050100

(106,20)→(-14,46) için en uzak: (11,-25); üçgen içindeki 25 nokta elendi. Aday kaldı: 5.

050100050100

(106,20)→(11,-25) için en uzak: (88,-5); üçgen içindeki 4 nokta elendi. Aday kaldı: 0.

050100050100

Bitti: 104 noktanın örtüsü 10 köşe. Her adımda noktaların çoğu elendiği için iş hızla azalır.

Dışbükey Örtü

Quickhull Analizi ve Diğer Örtü Algoritmaları

  • Her çağrı S'yi bir kez tarar (en uzak nokta + iki bölümleme): O(|S|).
  • T(n) = T(n₁) + T(n₂) + O(n), n₁ + n₂ ≤ n − 1.
  • Ortalama (dengeli bölmeler, çok nokta elenir): O(n log n); rastgele düzgün dağılımda çoğu zaman daha da hızlı.
  • En kötü durum: her adımda yalnızca bir nokta ayrılır → T(n) = T(n − 1) + O(n) = O(n²).
  • Çıktıya duyarlı sınır: h köşeli örtü için O(n·h).
AlgoritmaSüre
Kaba kuvvet (her kenar adayı)O(n³)
Jarvis yürüyüşü (gift wrapping)O(n·h)
Graham taramasıO(n log n)
Andrew monoton zincirO(n log n)
Quickhullort. O(n log n), en kötü O(n²)
ChanO(n log h)
Alt sınır: örtü sıralamayı da çözebildiği için (noktaları y = x² parabolüne yerleştirin) karşılaştırmalı modelde Ω(n log n) zaman gerekir.

En Yakın Nokta Çifti

En Yakın Nokta Çifti (Closest Pair)

Düzlemde n nokta verilsin; aralarındaki Öklid uzaklığı d(p, q) = √((pₓ − qₓ)² + (py − qy)²) en küçük olan çifti bulun.

double kabaKuvvet(List<Nokta> p) {
  double enAz = Double.MAX_VALUE;
  for (int i = 0; i < p.size(); i++)
    for (int j = i + 1; j < p.size(); j++)
      enAz = Math.min(enAz, mesafe(p.get(i), p.get(j)));
  return enAz;
}
  • Kaba kuvvet: n(n − 1)/2 çift → O(n²). n = 10⁶ için ≈ 5·10¹¹ uzaklık.
  • Tek boyutta kolay: sırala, yalnızca komşuları karşılaştır → O(n log n).
  • İki boyutta x'e göre sıralı komşular yetmez; böl ve fethet ile O(n log n) mümkün.
Uygulamalar: hava trafiği kontrolünde en yakın iki uçak, kümeleme, çarpışma algılama, coğrafi verilerde yakın tesisler.

En Yakın Nokta Çifti

Böl ve Fethet: Orta Şerit

  1. Noktaları bir kez x'e ve bir kez y'ye göre sırala.
  2. Böl: ortadaki noktanın x'inden geçen L doğrusu ile iki yarı.
  3. Yönet: iki yarıda özyinelemeyle δL ve δR; δ = min(δL, δR).
  4. Birleştir: daha yakın bir çift varsa L'yi keser → yalnızca |x − L| < δ olan şerit noktalarına bak.
  5. Şeridi y sırasıyla tara; her nokta yalnızca y farkı δ'dan küçük olan sonrakilerle karşılaştırılır.
L (x = orta)pδδδsol yarısağ yarı
Neden en çok 7? p'nin üstündeki δ × 2δ dikdörtgen, kenarı δ/2 olan 8 kareye bölünür. Bir karedeki iki nokta aynı yarıda olur ve aralarındaki uzaklık < δ olurdu; bu imkânsız → her karede ≤ 1 nokta → p en çok 7 noktayla karşılaştırılır.

En Yakın Nokta Çifti · Kodu adım adım çalıştır

En Yakın Çift: Kod İzleme

double enYakin(List<Nokta> X, List<Nokta> Y) {
  int n = X.size(), orta = n / 2;
  if (n <= 3) return kabaKuvvet(X);
  Nokta m = X.get(orta); // Ysol/Ysag: Y'nin yarıları
  double dSol = enYakin(X.subList(0, orta), Ysol);
  double dSag = enYakin(X.subList(orta, n), Ysag);
  double d = Math.min(dSol, dSag);
  List<Nokta> s = new ArrayList<>();  // şerit
  for (Nokta p : Y)                   // y sırası
    if (Math.abs(p.x - m.x) < d) s.add(p);
  for (int i = 0; i < s.size(); i++) {
    Nokta p = s.get(i);
    for (int j = i + 1; j < s.size()
         && s.get(j).y - p.y < d; j++)
      d = Math.min(d, mesafe(p, s.get(j)));
  }
  return d;
}
01020304002550x = 12

n = 10 > 3 → orta = 5, m = (12,10). Sol: 5, sağ: 5 nokta.

01020304002550x = 5

n = 5 > 3 → orta = 2, m = (5,1). Sol: 2, sağ: 3 nokta.

01020304002550d = 1,41

n = 2 ≤ 3 → kaba kuvvet: (2,3), (3,4). En yakın (2,3)–(3,4), d = 1,41.

01020304002550d = 6,32

n = 3 ≤ 3 → kaba kuvvet: (5,1), (7,7), (12,30). En yakın (5,1)–(7,7), d = 6,32.

01020304002550x = 5

İki yarı döndü: dSol = 1,41, dSag = 6,32 → d = 1,41.

01020304002550x = 5d = 1,41

Şerit |x − 5| < 1,41: [(5,1)]; tek nokta → karşılaştırma yok. Dönüş: 1,41.

01020304002550x = 27

n = 5 > 3 → orta = 2, m = (27,27). Sol: 2, sağ: 3 nokta.

01020304002550d = 8,60

n = 2 ≤ 3 → kaba kuvvet: (12,10), (17,17). En yakın (12,10)–(17,17), d = 8,60.

01020304002550d = 1,00

n = 3 ≤ 3 → kaba kuvvet: (27,27), (28,27), (40,50). En yakın (27,27)–(28,27), d = 1,00.

01020304002550x = 27

İki yarı döndü: dSol = 8,60, dSag = 1,00 → d = 1,00.

01020304002550x = 27d = 1,00

Şerit |x − 27| < 1,00: [(27,27)]; tek nokta → karşılaştırma yok. Dönüş: 1,00.

01020304002550x = 12

İki yarı döndü: dSol = 1,41, dSag = 1,00 → d = 1,00.

01020304002550x = 12d = 1,00

Şerit |x − 12| < 1,00: [(12,10), (12,30)]; y farkı d'den büyük → hiç karşılaştırma yok. Dönüş: 1,00.

En Yakın Nokta Çifti

En Yakın Çift: Analiz

AdımMaliyetNot
x ve y'ye göre ön sıralamaO(n log n)yalnızca bir kez, özyinelemeden önce
Bölme (X ikiye, Y'yi sırayı koruyarak Ysol/Ysag'ye)O(n)yeniden sıralama yok
Şeridi kurmaO(n)Y zaten y'ye göre sıralı
Şeridi taramaO(7n) = O(n)her nokta ≤ 7 komşu
ToplamO(n log n)T(n) = 2T(n/2) + O(n)
Yaygın tuzakŞeridi her çağrıda yeniden sıralamak: T(n) = 2T(n/2) + O(n log n) = O(n log² n).
Örnekte10 noktanın en yakın çifti (27,27)–(28,27), d = 1,00. Kaba kuvvet 45 uzaklık hesaplardı.

Karatsuba Çarpımı

Karatsuba: 4 Çarpım Yerine 3

n basamaklı x, y sayılarını m = ⌊n/2⌋ noktasından böl: x = a·10m + b, y = c·10m + d.

Saf böl ve fethetx·y = ac·102m + (ad + bc)·10m + bd
4 çarpım: ac, ad, bc, bd
T(n) = 4T(n/2) + O(n) = O(n²) → kazanç yok!
Karatsuba (1962)(a + b)(c + d) = ac + (ad + bc) + bd
⇒ ad + bc = (a + b)(c + d) − ac − bd
3 çarpım: z2 = ac, z0 = bd, z1 = (a + b)(c + d)
T(n) = 3T(n/2) + O(n) = O(n1,585)
Örnek: 1234 · 5678 (m = 2, 10m = 100)
a = 12, b = 34, c = 56, d = 78z2 = 12·56 = 672 · z0 = 34·78 = 2652
z1 = (12 + 34)(56 + 78) = 46·134 = 6164z1 − z2 − z0 = 6164 − 672 − 2652 = 2840 (= ad + bc)
672·10⁴ + 2840·10² + 2652 = 6 720 000 + 284 000 + 2652 = 7 006 652 ✓

Karatsuba Çarpımı · Kodu adım adım çalıştır

Karatsuba: 1234 · 5678 İzleme

1234·5678

karatsuba(1234, 5678): n = 4, p = 100 → a = 12, b = 34, c = 56, d = 78. Üç çağrı: (34, 78), (46, 134), (12, 56).

1234·567834·78

karatsuba(34, 78): n = 2, p = 10 → a = 3, b = 4, c = 7, d = 8. Üç çağrı: (4, 8), (7, 15), (3, 7).

1234·567834·784·8= 32

4 · 8: tek basamaklı çarpan var → taban, doğrudan 32.

1234·567834·784·8= 327·15= 105

7 · 15: tek basamaklı çarpan var → taban, doğrudan 105.

1234·567834·784·8= 327·15= 1053·7= 21

3 · 7: tek basamaklı çarpan var → taban, doğrudan 21.

1234·567834·78 = 26524·8= 327·15= 1053·7= 21

21·100 + (105 − 21 − 32)·10 + 32 = 2100 + 520 + 32 = 2652.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·134

karatsuba(46, 134): n = 3, p = 10 → a = 4, b = 6, c = 13, d = 4. Üç çağrı: (6, 4), (10, 17), (4, 13).

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·1346·4= 24

6 · 4: tek basamaklı çarpan var → taban, doğrudan 24.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·1346·4= 2410·17

karatsuba(10, 17): n = 2, p = 10 → a = 1, b = 0, c = 1, d = 7. Üç çağrı: (0, 7), (1, 8), (1, 1).

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·1346·4= 2410·170·7= 0

0 · 7: tek basamaklı çarpan var → taban, doğrudan 0.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·1346·4= 2410·170·7= 01·8= 8

1 · 8: tek basamaklı çarpan var → taban, doğrudan 8.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·1346·4= 2410·170·7= 01·8= 81·1= 1

1 · 1: tek basamaklı çarpan var → taban, doğrudan 1.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·1346·4= 2410·17 = 1700·7= 01·8= 81·1= 1

1·100 + (8 − 1 − 0)·10 + 0 = 100 + 70 + 0 = 170.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·1346·4= 2410·17 = 1700·7= 01·8= 81·1= 14·13= 52

4 · 13: tek basamaklı çarpan var → taban, doğrudan 52.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·134 = 61646·4= 2410·17 = 1700·7= 01·8= 81·1= 14·13= 52

52·100 + (170 − 52 − 24)·10 + 24 = 5200 + 940 + 24 = 6164.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·134 = 61646·4= 2410·17 = 1700·7= 01·8= 81·1= 14·13= 5212·56

karatsuba(12, 56): n = 2, p = 10 → a = 1, b = 2, c = 5, d = 6. Üç çağrı: (2, 6), (3, 11), (1, 5).

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·134 = 61646·4= 2410·17 = 1700·7= 01·8= 81·1= 14·13= 5212·562·6= 12

2 · 6: tek basamaklı çarpan var → taban, doğrudan 12.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·134 = 61646·4= 2410·17 = 1700·7= 01·8= 81·1= 14·13= 5212·562·6= 123·11= 33

3 · 11: tek basamaklı çarpan var → taban, doğrudan 33.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·134 = 61646·4= 2410·17 = 1700·7= 01·8= 81·1= 14·13= 5212·562·6= 123·11= 331·5= 5

1 · 5: tek basamaklı çarpan var → taban, doğrudan 5.

1234·567834·78 = 26524·8= 327·15= 1053·7= 2146·134 = 61646·4= 2410·17 = 1700·7= 01·8= 81·1= 14·13= 5212·56 = 6722·6= 123·11= 331·5= 5

5·100 + (33 − 5 − 12)·10 + 12 = 500 + 160 + 12 = 672.

1234·5678 = 700665234·78 = 26524·8= 327·15= 1053·7= 2146·134 = 61646·4= 2410·17 = 1700·7= 01·8= 81·1= 14·13= 5212·56 = 6722·6= 123·11= 331·5= 5

672·10000 + (6164 − 672 − 2652)·100 + 2652 = 6720000 + 284000 + 2652 = 7006652.

long karatsuba(long x, long y) {
  if (x < 10 || y < 10) return x * y; // taban
  int n = Math.max(basamak(x), basamak(y));
  long p = (long) Math.pow(10, n / 2);
  long a = x / p, b = x % p;   // x = a·p + b
  long c = y / p, d = y % p;   // y = c·p + d
  long z0 = karatsuba(b, d);
  long z1 = karatsuba(a + b, c + d);
  long z2 = karatsuba(a, c);
  return z2 * p * p + (z1 - z2 - z0) * p + z0;
}

Karatsuba Çarpımı

Karatsuba Analizi

  • T(n) = 3T(n/2) + O(n) → durum 1 → Θ(nlog₂3) ≈ Θ(n1,585).
  • Toplama, çıkarma ve 10m ile kaydırma O(n); çarpım sayısını 4'ten 3'e indirmek üssü 2'den 1,585'e düşürür.
  • Örnekte 16 çağrı, 11 tek basamaklı çarpım (okul yöntemi 16).
  • Küçük sayılarda ek toplamalar yüzünden yavaştır → bir eşik altında okul yöntemi.
  • Java BigInteger.multiply büyük sayılarda Karatsuba ve Toom-Cook kullanır. Daha hızlıları: Schönhage–Strassen O(n log n log log n), Harvey–van der Hoeven O(n log n) (2019).
n (basamak)n²n1,585oran
10100382,6×
10010 0001 4796,8×
1 0001,0·10656 87117,6×
10 0001,0·1082,2·10645,7×
1,0·1061,0·10123,2·109309,2×

Strassen Çarpımı

Matris Çarpımı: Klasik ve Blok

Klasik: Θ(n³)
for (int i = 0; i < n; i++)
  for (int j = 0; j < n; j++)
    for (int k = 0; k < n; k++)
      C[i][j] += A[i][k] * B[k][j];

n² hücrenin her biri n çarpım → n³ çarpım.

Blok böl ve fethet

A, B, C'yi n/2 × n/2'lik dört bloğa böl:

C11 = A11·B11 + A12·B21
C12 = A11·B12 + A12·B22
C21 = A21·B11 + A22·B21
C22 = A21·B12 + A22·B22
8 blok çarpımı + 4 blok toplamı: T(n) = 8T(n/2) + Θ(n²) → nlog₂8 = Θ(n³). Sadece bölmek yetmez; çarpım sayısı azaltılmalı.

Strassen Çarpımı

Strassen (1969): 8 Yerine 7 Çarpım

ÇarpımTanım
P1A11 · (B12 − B22)
P2(A11 + A12) · B22
P3(A21 + A22) · B11
P4A22 · (B21 − B11)
P5(A11 + A22) · (B11 + B22)
P6(A12 − A22) · (B21 + B22)
P7(A11 − A21) · (B11 + B12)
Sonuç blokları
C11 = P5 + P4 − P2 + P6
C12 = P1 + P2
C21 = P3 + P4
C22 = P5 + P1 − P3 − P7

7 çarpım + 18 blok toplama/çıkarma. Bloklar da Strassen ile özyinelemeli çarpılır; taban 1×1.

Dikkat: C22'de P7 çıkarılır. "+ P7" yazılırsa program hata vermeden yanlış matris üretir; uygulamayı küçük bir örnekte klasik yöntemle karşılaştırarak test edin.

Strassen Çarpımı

Strassen Adım Adım: 2 × 2 Örnek

A =
13
75
×
B =
68
42
P1A11 · (B12 − B22)1 · (8 − 2)6
P2(A11 + A12) · B22…
P3(A21 + A22) · B11…
P4A22 · (B21 − B11)…
P5(A11 + A22) · (B11 + B22)…
P6(A12 − A22) · (B21 + B22)…
P7(A11 − A21) · (B11 + B12)…

P1 = 1 · (8 − 2) = 6.

P1A11 · (B12 − B22)1 · (8 − 2)6
P2(A11 + A12) · B22(1 + 3) · 28
P3(A21 + A22) · B11…
P4A22 · (B21 − B11)…
P5(A11 + A22) · (B11 + B22)…
P6(A12 − A22) · (B21 + B22)…
P7(A11 − A21) · (B11 + B12)…

P2 = (1 + 3) · 2 = 8.

P1A11 · (B12 − B22)1 · (8 − 2)6
P2(A11 + A12) · B22(1 + 3) · 28
P3(A21 + A22) · B11(7 + 5) · 672
P4A22 · (B21 − B11)…
P5(A11 + A22) · (B11 + B22)…
P6(A12 − A22) · (B21 + B22)…
P7(A11 − A21) · (B11 + B12)…

P3 = (7 + 5) · 6 = 72.

P1A11 · (B12 − B22)1 · (8 − 2)6
P2(A11 + A12) · B22(1 + 3) · 28
P3(A21 + A22) · B11(7 + 5) · 672
P4A22 · (B21 − B11)5 · (4 − 6)−10
P5(A11 + A22) · (B11 + B22)…
P6(A12 − A22) · (B21 + B22)…
P7(A11 − A21) · (B11 + B12)…

P4 = 5 · (4 − 6) = −10.

P1A11 · (B12 − B22)1 · (8 − 2)6
P2(A11 + A12) · B22(1 + 3) · 28
P3(A21 + A22) · B11(7 + 5) · 672
P4A22 · (B21 − B11)5 · (4 − 6)−10
P5(A11 + A22) · (B11 + B22)(1 + 5) · (6 + 2)48
P6(A12 − A22) · (B21 + B22)…
P7(A11 − A21) · (B11 + B12)…

P5 = (1 + 5) · (6 + 2) = 48.

P1A11 · (B12 − B22)1 · (8 − 2)6
P2(A11 + A12) · B22(1 + 3) · 28
P3(A21 + A22) · B11(7 + 5) · 672
P4A22 · (B21 − B11)5 · (4 − 6)−10
P5(A11 + A22) · (B11 + B22)(1 + 5) · (6 + 2)48
P6(A12 − A22) · (B21 + B22)(3 − 5) · (4 + 2)−12
P7(A11 − A21) · (B11 + B12)…

P6 = (3 − 5) · (4 + 2) = −12.

P1A11 · (B12 − B22)1 · (8 − 2)6
P2(A11 + A12) · B22(1 + 3) · 28
P3(A21 + A22) · B11(7 + 5) · 672
P4A22 · (B21 − B11)5 · (4 − 6)−10
P5(A11 + A22) · (B11 + B22)(1 + 5) · (6 + 2)48
P6(A12 − A22) · (B21 + B22)(3 − 5) · (4 + 2)−12
P7(A11 − A21) · (B11 + B12)(1 − 7) · (6 + 8)−84

P7 = (1 − 7) · (6 + 8) = −84.

C11 = P5 + P4 − P2 + P648 + (−10) − 8 + (−12)18
C12 = P1 + P26 + 814
C21 = P3 + P472 + (−10)62
C22 = P5 + P1 − P3 − P748 + 6 − 72 − (−84)66

C = [[18, 14], [62, 66]]. Kontrol: 1·6 + 3·4 = 18, 7·8 + 5·2 = 66 ✓. 7 çarpım kullanıldı (klasik 8).

Strassen Çarpımı

Strassen Analizi ve Pratik

  • T(n) = 7T(n/2) + Θ(n²) → durum 1 → Θ(nlog₂7) ≈ Θ(n2,807).
  • n = 2k için skaler çarpım: 7k (klasik 8k). n = 1024: 7¹⁰ ≈ 2,8·10⁸, 8¹⁰ ≈ 1,07·10⁹ → yaklaşık 3,8 kat az.
  • n 2'nin kuvveti değilse matris sıfırlarla doldurulur (padding).
  • Eşik: 18 ek toplama ve geçici matrisler yüzünden küçük n'de yavaş; kütüphaneler n ≲ 64–128'de klasik yönteme geçer.
  • Sayısal kararlılık: kayan noktalı sayılarda çıkarma işlemleri hatayı büyütebilir.
  • Bellek: her düzeyde geçici bloklar → ek O(n²).
  • Kuramsal rekor ω < 2,372 (2024); sabitler çok büyük, pratikte kullanılmaz.
Ders: çarpımı toplamalarla takas etmek, a'yı bir azaltarak üssü düşürür. Aynı fikir Karatsuba'da 4 → 3, Strassen'de 8 → 7.

Değerlendirme

Saf Yöntem ve Böl ve Fethet

ProblemSaf yöntemBöl ve fethetBağıntı
SıralamaO(n²) (kabarcık)O(n log n)2T(n/2) + n
Sıralı dizide aramaO(n)O(log n)T(n/2) + 1
Üs alma xⁿO(n) çarpımO(log n)T(n/2) + 1
Dışbükey örtüO(n³)ort. O(n log n)T(n₁) + T(n₂) + n
En yakın nokta çiftiO(n²)O(n log n)2T(n/2) + n
Tam sayı çarpımıO(n²)O(n1,585)3T(n/2) + n
Matris çarpımıO(n³)O(n2,807)7T(n/2) + n²

Kazancın kaynağı: ya iş dengeli bölünüp her düzey O(n)'de birleştiriliyor (sıralama, en yakın çift) ya da alt problem sayısı azaltılıyor (Karatsuba, Strassen) ya da yarısı atılıyor (arama, üs).

Değerlendirme

Böl ve Fethet, Dinamik Programlama, Açgözlü

Böl ve fethetDinamik programlamaAçgözlü
Alt problemlerbağımsızörtüşentek bir alt problem kalır
Yönyukarıdan aşağı (özyineleme)çoğunlukla aşağıdan yukarı (tablo)adım adım, geri dönüş yok
Kararsabit bölme kuralıtüm seçenekleri dener, en iyisini saklaro anda en iyi görüneni seçer
Örnekbirleştirerek sıralama, StrassenFibonacci, sırt çantasıDijkstra, Huffman, Kruskal
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ü (Bölüm 12).

Özet

Özet

KonuHatırlanacaklar
Paradigmaböl → (parçala) → yönet → birleştir; bağımsız, aynı türden alt problemler; taban durumu şart
AnalizT(n) = aT(n/b) + f(n); özyineleme ağacı; ana teorem: f(n)'yi nlogb a ile karşılaştır
Temel örneklerikili arama ve hızlı üs O(log n); birleştirerek sıralama O(n log n); hızlı sıralama ort. O(n log n), en kötü O(n²)
QuickhullA, B uçlar; en uzak C (max capraz); üçgen içi elenir; ort. O(n log n), en kötü O(n²)
En yakın çiftx'e göre böl; δ = min(δL, δR); 2δ şeritte ≤ 7 komşu; O(n log n)
Karatsubaad + bc = (a + b)(c + d) − ac − bd; 3 çarpım → O(n1,585)
Strassen7 blok çarpımı → O(n2,807); C22 = P5 + P1 − P3 − P7

Özet

Etkileşimli Simülatörler

Özyineleme ve Ana TeoremT(n) = aT(n/b) + f(n) biçimindeki bağıntıların özyineleme ağacını düzey düzey çizer ve ana teorem durumunu belirler.
Sıralama AlgoritmalarıBirleştirerek ve hızlı sıralama dahil on sıralama algoritmasını adım adım görselleştirir.
Matris AlgoritmalarıMatris toplama, çarpma, devrik, determinant ve Gauss eliminasyonu; klasik Θ(n³) çarpım ile Strassen'in O(n2,807) sınırı.

Özet

Sık Yapılan Hatalar

Taban durumunu unutmakYa da hiç ulaşılamayan bir taban yazmak: sonsuz özyineleme, StackOverflowError. Karatsuba'da x < 10 || y < 10.
Dengesiz bölmeSıralı dizide son eleman pivot ya da Quickhull'da her adımda tek nokta: T(n) = T(n − 1) + n = O(n²).
Örtüşen alt problemlerFibonacci'yi düz özyinelemeyle hesaplamak üstel süre alır; sonuçları saklayan dinamik programlama gerekir.
Birleştirme maliyetini küçümsemekŞeridi her çağrıda sıralamak O(n log² n) yapar; 2T(n/2) + n log n ≠ Θ(n log n).
Ana teoremi yanlış yerde kullanmakT(n) = T(n − 1) + n, eşit olmayan bölmeler veya f(n) = n/log n için geçerli değildir.
İşaret hatasıStrassen'de C22 = P5 + P1 − P3 − P7; tek işaret hatası hata vermeden yanlış matris üretir. Küçük örnekle klasik yönteme karşı test edin.

Özet

Örnek Problemler

  1. T(n) = 4T(n/2) + n bağıntısını ana teoremle çözün.
  2. T(n) = 2T(n/2) + n² bağıntısını çözün; düzenlilik koşulunu kontrol edin.
  3. Karatsuba ile 21 · 43'ü hesaplayın (m = 1).
  4. A = (0,0), B = (10,0). P = (3,4), Q = (5,−2), R = (7,6) için capraz(A, B, ·) değerlerini bulun. Quickhull üst kümede hangi noktayı seçer?
  5. us(3, 10) kaç çarpım yapar? Saf yöntemle kıyaslayın.
  6. [5, 1, 4, 2, 3] dizisini birleştirerek sıralarken son birleştirmede hangi iki sıralı dizi birleşir?
Cevapları göster
  1. a = 4, b = 2 → nlog₂4 = n²; f(n) = n daha küçük → durum 1 → Θ(n²).
  2. nlog₂2 = n; f(n) = n² daha büyük; 2·(n/2)² = n²/2 ≤ ½·n² ✓ → durum 3 → Θ(n²).
  3. a = 2, b = 1, c = 4, d = 3: z2 = 8, z0 = 3, z1 = 3·7 = 21 → 21 − 8 − 3 = 10 → 800 + 100 + 3 = 903.
  4. P: 10·4 = 40 (sol), Q: 10·(−2) = −20 (sağ), R: 10·6 = 60 (sol). Üst kümede en büyük capraz → R.
  5. n: 10 → 5 → 2 → 1 → 0. Çarpımlar: n=1: 2, n=2: 1, n=5: 2, n=10: 1 → 6 (saf: 9). Sonuç 59049.
  6. orta = 2: [5, 1, 4] → [1, 4, 5] ve [2, 3] → [1, 4, 5] + [2, 3] → [1, 2, 3, 4, 5].

Özet

Alıştırmalar

  1. Dizinin en büyük elemanını böl ve fethet ile bulun; bağıntıyı çözün.
  2. Birleştirerek sıralamayı değiştirip ters çiftleri (i < j, a[i] > a[j]) sayın. [2, 4, 1, 3, 5] için sonuç?
  3. En büyük toplamlı alt dizi: [−2, 1, −3, 4, −1, 2, 1, −5, 4] için böl ve fethet çözümü ve süresi.
  4. A = [[1, 2], [3, 4]], B = [[5, 6], [7, 8]] çarpımını Strassen ile hesaplayın; C22'yi ± P7 ile deneyin.
  5. Quickhull için O(n²) süren bir girdi tarif edin.
  6. En yakın çift algoritmasında taban durumu n ≤ 3 yerine n ≤ 1 olsaydı ne değişirdi?
Cevaplar / ipuçları
  1. max(sol yarı, sağ yarı); T(n) = 2T(n/2) + O(1) → durum 1 → Θ(n).
  2. Birleştirmede sağdan eleman alınınca soldaki kalan sayısı eklenir; O(n log n). Sonuç 3.
  3. max(sol, sağ, ortadan geçen); 2T(n/2) + O(n) = O(n log n). Sonuç 6 ([4, −1, 2, 1]).
  4. P1..P7 = −2, 24, 35, 8, 65, −30, −22 → C = [[19, 22], [43, 50]]; C22 = 65 − 2 − 35 + 22 = 50 ✓ (+P7 ile 6 ✗).
  5. Noktalar dışbükey bir eğride ve en uzak nokta hep bir uca komşu (üstel aralıklı): T(n) = T(n − 1) + O(n).
  6. Tek noktalı yarı ∞ döndürür; sonuç yine doğru (şerit kaçan çifti bulur) ama çağrı sayısı artar.

Özet

Kaynaklar

  • Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, 2022 (Bölüm 4: Böl ve fethet; Bölüm 33: Hesaplamalı geometri).
  • Kleinberg ve Tardos, Algorithm Design, 2005 (Bölüm 5: Divide and Conquer).
  • Sedgewick ve Wayne, Algorithms, 4. baskı, 2011.
  • Barber, Dobkin ve Huhdanpaa, "The Quickhull Algorithm for Convex Hulls", ACM TOMS 22(4), 1996.
  • Karatsuba ve Ofman, "Multiplication of Multidigit Numbers on Automata", 1962; Strassen, "Gaussian Elimination is not Optimal", Numerische Mathematik 13, 1969.

Son

Bölüm 11: Böl ve Fethet Yaklaşımı
Sonraki bölüm: Bölüm 12: Açgözlü Algoritmalar
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.