Bölüm 12: Rastgele Algoritmalar
Çoktan Seçmeli · Temel Kavramlar
Soru 1: Las Vegas mı, Monte Carlo mu?
Aşağıdaki eşleştirmelerden hangisi doğrudur?
A: Las Vegas her zaman doğru sonuç verir, süresi rastgeledir (QuickSort, QuickSelect, BogoSort, Fisher–Yates). Monte Carlo'nun süresi sınırlıdır ama sonuç küçük bir olasılıkla yanlış olabilir (Miller–Rabin, Karger, π tahmini).
Çoktan Seçmeli · Temel Kavramlar
Soru 2: Kazanana Kadar Beklenen Atış
İki zar atılıyor; toplam 6 ya da 8 gelirse oyuncu kazanıyor, gelmezse yeniden atıyor. Kazanana kadar beklenen atış sayısı kaçtır?
C: P(6) = 5/36, P(8) = 5/36 → p = 10/36. Denemeler bağımsız: geometrik dağılım, beklenen deneme 1/p = 36/10 = 3,6. 0,28 başarı olasılığının kendisidir; 7,20 yalnızca bir toplamı (5/36) saymaktır.
Adım Adım Çalıştırma · Karıştırma
Soru 3: Fisher–Yates İzleme
karistir metodu [10, 20, 30, 40, 50] dizisine uygulanıyor; rastgele sayı üreteci sırasıyla j = 2, 3, 0, 1 değerlerini veriyor. Dizi her adımda nasıl değişir?
a = [10, 20, 30, 40, 50]. Sondan başlayarak her konuma, henüz yerleşmemiş öğelerden biri gelir. Bu izlemede nextInt sırasıyla 2, 3, 0, 1 döndürüyor.
i = 4: zar.nextInt(5) → j = 2; a[0..4] arasındaki 5 öğenin her biri 1/5 olasılıkla seçilebilirdi.
a[4] ↔ a[2] takas → [10, 20, 50, 40, 30]. a[4] = 30 kesinleşti.
i = 3: zar.nextInt(4) → j = 3; a[0..3] arasındaki 4 öğenin her biri 1/4 olasılıkla seçilebilirdi.
j = i: öğe kendisiyle takas edilir, dizi değişmez; a[3] = 40 kesinleşti.
i = 2: zar.nextInt(3) → j = 0; a[0..2] arasındaki 3 öğenin her biri 1/3 olasılıkla seçilebilirdi.
a[2] ↔ a[0] takas → [50, 20, 10, 40, 30]. a[2] = 10 kesinleşti.
i = 1: zar.nextInt(2) → j = 1; a[0..1] arasındaki 2 öğenin her biri 1/2 olasılıkla seçilebilirdi.
j = i: öğe kendisiyle takas edilir, dizi değişmez; a[1] = 20 kesinleşti.
i = 0'da döngü biter: [50, 20, 10, 40, 30]. Olası çekiliş dizisi sayısı 5 · 4 · 3 · 2 = 120 = 5!: her permütasyon tam bir kez → düzgün dağılım. Takas sayısı her zaman n − 1: Θ(n).
static void karistir(int[] a) { for (int i = a.length - 1; i > 0; i--) { int j = zar.nextInt(i + 1); // 0 ≤ j ≤ i int t = a[i]; a[i] = a[j]; a[j] = t; } }
Çoktan Seçmeli · Karıştırma
Soru 4: Saf Karıştırma Neden Yanlı?
Her i için j = zar.nextInt(n) ile takas yapan saf karıştırma n = 4 öğeye uygulanıyor. Eşit olasılıklı çekiliş yolu sayısı ve sonucun yanlı olmasının nedeni nedir?
D: 4 çekilişin her biri 4 değer alır → 4⁴ = 256 eşit olasılıklı yol; 4! = 24 permütasyon. 256/24 tam sayı değildir, bu yüzden bazı permütasyonlar daha sık çıkar. Fisher–Yates'te 4 · 3 · 2 · 1 = 24 yol vardır, her permütasyon bir kez.
Çıktı Sorusu · Karıştırma
Soru 5: nextInt(i + 1) Yerine nextInt(i)
karistir metodunda zar.nextInt(i + 1) yanlışlıkla zar.nextInt(i) yazılıyor. [1, 2, 3] dizisi için hangi sonuçlar hangi olasılıkla çıkar? Bu karıştırma düzgün müdür?
Cevabı göster
i = 2'de j ∈ {0, 1}, i = 1'de j = 0 zorunludur: yalnızca 2 · 1 = 2 yol.
- j = 0: [3, 2, 1] → sonra a[1] ↔ a[0] → [2, 3, 1]
- j = 1: [1, 3, 2] → sonra → [3, 1, 2]
Her biri 1/2; diğer 4 permütasyon (sıralı [1, 2, 3] dahil) hiç çıkmaz. a[i] her zaman daha soldaki bir öğeyle takas edilir, hiçbir öğe yerinde kalamaz: bu Sattolo algoritmasıdır ve yalnızca (n − 1)! çevrimsel permütasyonu üretir. Düzgün karıştırma değildir.
Çoktan Seçmeli · BogoSort
Soru 6: BogoSort Beklenen Karıştırma
Farklı 6 öğeli bir dizi BogoSort ile sıralanıyor (karıştırma: Fisher–Yates). Beklenen karıştırma sayısı kaçtır?
C: Bir karıştırmanın sıralı çıkma olasılığı p = 1/6! = 1/720; denemeler bağımsız → geometrik dağılım, beklenen 1/p = 720. Her tur Θ(n) olduğundan beklenen süre Θ(n · n!). 120 = 5!, 5040 = 7!.
Klasik Soru · BogoSort
Soru 7: BogoSort'un En Kötü Durumu
BogoSort'un en iyi, beklenen ve en kötü durum sürelerini gerekçeleriyle yazın. Beklenen Θ(n · n!) süresi neden O((n + 1)!) ile aynı büyüklüktedir; en kötü durum için neden bir üst sınır verilemez?
Cevabı göster
- En iyi: dizi zaten sıralı → tek
siraliMiçağrısı, O(n). - Beklenen: p = 1/n!, geometrik dağılım → n! karıştırma; her tur karıştırma O(n) + kontrol O(n) → Θ(n · n!). (n + 1)! = (n + 1) · n! olduğundan n · n! ile aynı mertebededir.
- En kötü: karıştırmalar bağımsızdır; k tur boyunca hep sırasız çıkma olasılığı (1 − 1/n!)k > 0'dır. Her k için o kadar süren bir çalıştırma mümkündür → sınırsız (olasılığı 0'a gitse de).
Bu yüzden BogoSort bir Las Vegas algoritmasıdır: sonuç her zaman doğru, süre rastgele.
Adım Adım Çalıştırma · Rastgele QuickSort
Soru 8: Rastgele Parçalama İzleme
bol(a, 0, 6) çağrısı a = {8, 3, 6, 1, 7, 2, 5} için çalışıyor ve zar.nextInt(7) 2 döndürüyor. Her adımda dizi, i ve k nasıl değişir?
zar.nextInt(7) → r = 2: pivot a[2] = 6 (turuncu).
Pivot sona taşınır: a[2] ↔ a[6] → [8, 3, 5, 1, 7, 2, 6].
pivot = 6, k = 0: k, "≤ pivot" bölgesinin (yeşil) bittiği yerdir.
i = 0: a[0] = 8 > 6 → "> pivot" bölgesinde (mavi) kalır.
i = 1: a[1] ≤ 6 → takas(a, 1, 0), k = 1 → [3, 8, 5, 1, 7, 2, 6].
i = 2: a[2] ≤ 6 → takas(a, 2, 1), k = 2 → [3, 5, 8, 1, 7, 2, 6].
i = 3: a[3] ≤ 6 → takas(a, 3, 2), k = 3 → [3, 5, 1, 8, 7, 2, 6].
i = 4: a[4] = 7 > 6 → "> pivot" bölgesinde (mavi) kalır.
i = 5: a[5] ≤ 6 → takas(a, 5, 3), k = 4 → [3, 5, 1, 2, 7, 8, 6].
Pivot k = 4'e yerleşir → [3, 5, 1, 2, 6, 8, 7], dönüş 4. Solunda yalnızca ≤ 6, sağında > 6 var; ust − alt = 6 karşılaştırma yapıldı.
static int bol(int[] a, int alt, int ust) { int r = alt + zar.nextInt(ust - alt + 1); takas(a, r, ust); // pivot sona int pivot = a[ust], k = alt; for (int i = alt; i < ust; i++) if (a[i] <= pivot) takas(a, i, k++); // küçükleri sola takas(a, k, ust); // pivot yerine return k; }
Çıktı Sorusu · Rastgele QuickSort
Soru 9: Sıralı Dizide Karşılaştırma
Pivotu her zaman alt dizinin ilk öğesi seçen QuickSort, zaten sıralı 10 öğeli bir diziyi sıralıyor. Kaç karşılaştırma yapılır? Rastgele pivotlu sürümün aynı dizi için beklenen karşılaştırma sayısı E[X] = 2(n + 1)Hn − 4n kaçtır?
Cevabı göster
İlk öğe hep en küçüktür: parçalardan biri boş, öteki bir eksik. Karşılaştırmalar 9 + 8 + … + 1 = n(n − 1)/2 = 45.
Rastgele pivot: H10 = 1 + 1/2 + … + 1/10 ≈ 2,929 → 2 · 11 · 2,929 − 40 ≈ 24,4. Bu değer girdiden bağımsızdır: sıralı dizi rastgele pivota karşı "kötü" değildir.
n = 1000'de fark çok büyür: 499 500 ile ≈ 10 986.
Çoktan Seçmeli · Rastgele QuickSort
Soru 10: Karşılaştırılma Olasılığı
Rastgele QuickSort'ta öğeler sıralı hâlleriyle z₁ < z₂ < … < zn olsun. z₂ ile z₆'nın birbiriyle karşılaştırılma olasılığı kaçtır?
B: {z₂, …, z₆} kümesinden (5 öğe) ilk seçilen pivot z₂ ya da z₆ olursa karşılaştırılırlar; aradaki z₃, z₄, z₅'ten biri önce seçilirse ayrı parçalara düşerler. Düzgün seçim → 2/5. Genel kural 2/(j − i + 1); komşu öğeler (j = i + 1) her zaman karşılaştırılır.
Adım Adım Çalıştırma · Rastgele QuickSort
Soru 11: QuickSelect İzleme
a = [6, 5, 3, 1, 8, 7, 2, 4] için sec(a, 0, 7, 5); bol sırasıyla r = 2, 6, 5 çekiyor. Çağrılar nasıl ilerler?
İlk çağrı a = [6, 5, 3, 1, 8, 7, 2, 4] üzerinde; bol r = 2 çeker (pivot 3) → p = 2, dizi [1, 2, 3, 6, 8, 7, 5, 4].
s = 5 ≠ 2 ve s > p → yalnızca sağ parçaya inilir: sec(a, 3, 7, 5). Sol parça (soluk) bir daha incelenmez.
bol(a, 3, 7) r = 6 çeker (pivot 5): ≤ 5 olan 4 sola gelir → p = 4, dizi [1, 2, 3, 4, 5, 7, 6, 8].
s = 5 > p = 4 → sec(a, 5, 7, 5).
bol(a, 5, 7) r = 5 çeker (pivot 7) → p = 6, dizi [1, 2, 3, 4, 5, 6, 7, 8].
s = 5 < p = 6 → bu kez sol parça: sec(a, 5, 5, 5).
Taban durum: alt == ust → a[5] = 6 döner.
6 değeri çağrı zincirinden olduğu gibi geri döner: 0 tabanlı 5. en küçük öğe (6. küçük) 6. Her çağrıda tek tarafa inildiği için beklenen süre O(n).
static int sec(int[] a, int alt, int ust, int s) { if (alt == ust) return a[alt]; int p = bol(a, alt, ust); if (s == p) return a[p]; if (s < p) return sec(a, alt, p - 1, s); return sec(a, p + 1, ust, s); }
Çoktan Seçmeli · Rastgele QuickSort
Soru 12: QuickSelect Karmaşıklığı
Rastgele pivotlu QuickSelect (sec) için hangisi doğrudur?
B: Tek tarafa inildiği için beklenen iş n + n/2 + n/4 + … gibi geometrik azalır → O(n) (ortanca için ≈ 3,39 n karşılaştırma). Şanssız pivotlarda parça hep bir küçülür → O(n²). Parçalama zaten Θ(n) olduğu için O(log n) imkânsızdır.
Adım Adım Çalıştırma · Monte Carlo
Soru 13: Monte Carlo π İzleme
System.out.println(piTahmin(6)) çalıştırılıyor; rastgele noktalar verilmiştir. ic nasıl değişir ve ne yazdırılır?
Birim kare ve çeyrek daire (x² + y² ≤ 1). nextDouble sırasıyla şu noktaları veriyor: (0,3; 0,4), (0,9; 0,6), (0,5; 0,5), (0,8; 0,7), (0,1; 0,9), (0,7; 0,7).
t = 0: x² + y² = 0,25 ≤ 1 → içeride (yeşil), ic = 1.
t = 1: x² + y² = 1,17 > 1 → dışarıda (kırmızı), ic değişmez.
t = 2: x² + y² = 0,50 ≤ 1 → içeride (yeşil), ic = 2.
t = 3: x² + y² = 1,13 > 1 → dışarıda (kırmızı), ic değişmez.
t = 4: x² + y² = 0,82 ≤ 1 → içeride (yeşil), ic = 3.
t = 5: x² + y² = 0,98 ≤ 1 → içeride (yeşil), ic = 4.
Döngü biter: 4 · 4 / 6 ≈ 2,667. 6 noktayla tahmin kabadır: hata ≈ 1,64/√n ≈ 0,67. 4.0 ile çarpım double bölme sağlar (4 * ic / n tam sayı bölmesiyle 2 verirdi).
static double piTahmin(int n) { int ic = 0; for (int t = 0; t < n; t++) { double x = zar.nextDouble(), y = zar.nextDouble(); if (x * x + y * y <= 1) ic++; } return 4.0 * ic / n; }
Çoktan Seçmeli · Monte Carlo
Soru 14: Bir Basamak Daha Doğruluk
Monte Carlo π tahmini n = 10 000 noktayla yaklaşık 0,016 hata veriyor. Hatayı yaklaşık 0,0016'ya indirmek için kaç nokta gerekir?
D: Hata ≈ 1/√n ile azalır: hatayı 10'da birine indirmek için √n 10 kat, yani n 100 kat artmalı → 1 000 000. 100 000 noktada hata yalnızca √10 ≈ 3,16 kat azalır. Bu yüzden Monte Carlo yüksek doğruluk için yavaştır.
Adım Adım Çalıştırma · Monte Carlo
Soru 15: Miller–Rabin İzleme
asalMi(221, 2) çağrılıyor; rastgele tabanlar sırasıyla a = 174 ve a = 137 çıkıyor. Her turda x nasıl değişir, sonuç nedir?
n = 221 tek ve ≥ 4: küçük durum ve çift sayı kontrolleri geçilir. (221 = 13 · 17, ama algoritma bunu bilmiyor.)
n − 1 = 220 = 2² · 55 → d = 55, s = 2. Bakılacak dizi: a55, a110 (mod 221).
tur = 0, a = 174: x = 17455 mod 221 = 47. 1 ya da 220 değil → tanik = true.
r = 1: x = 47² mod 221 = 2209 mod 221 = 220 = n − 1 → tanik = false. 174 bir güçlü yalancıdır: 221 bu turu geçer.
tanik false → return edilmez, ikinci tura geçilir. Tek tur yetseydi yanlış olarak "asal" denecekti.
tur = 1, a = 137: x = 13755 mod 221 = 188 → tanik = true.
r = 1: x = 188² mod 221 = 205 ≠ 220. r = 2 < s değil, iç döngü biter; n − 1 hiç görünmedi.
tanik true → false döner: 137 bir tanıktır ve "bileşik" yanıtı kesindir (tek yönlü hata).
static boolean asalMi(long n, int k) { if (n < 4) return n == 2 || n == 3; if (n % 2 == 0) return false; long d = n - 1; int s = 0; // n-1 = 2^s·d while (d % 2 == 0) { d /= 2; s++; } for (int tur = 0; tur < k; tur++) { long a = 2 + zar.nextLong(n - 3); // [2, n-2] long x = usMod(a, d, n); // a^d mod n if (x == 1 || x == n - 1) continue; boolean tanik = true; for (int r = 1; r < s && tanik; r++) { x = x * x % n; if (x == n - 1) tanik = false; } if (tanik) return false; // kesin bileşik } return true; // muhtemelen asal }
Çoktan Seçmeli · Monte Carlo
Soru 16: Kaç Tur Gerekir?
Miller–Rabin'de bileşik bir sayı için tek turun yanılma olasılığı en çok 1/4'tür. Hata olasılığını 10−9'un altına indirmek için en az kaç bağımsız tur gerekir?
A: 4−k < 10−9 ⇔ 4k > 10⁹; 415 = 230 ≈ 1,07 · 10⁹ yeter, 414 ≈ 2,7 · 10⁸ yetmez. 30, 2−k varsaymaktır; 9, 10−k varsaymaktır.
Çoktan Seçmeli · Monte Carlo
Soru 17: Karger Başarı Olasılığı
Karger'in rastgele kenar büzme algoritmasının tek bir çalıştırması, n = 5 düğümlü bir çizgede minimum kesimi en az hangi olasılıkla bulur?
B: Alt sınır 2/(n(n − 1)) = 2/20 = 1/10. Her büzmede minimum kesimin bir kenarını seçmeme olasılığı 1 − 2/k'dir (k: kalan düğüm); çarpım 3/5 · 2/4 · 1/3 = 1/10. Gerçek başarı çizgeye göre daha yüksek olabilir.
Çıktı Sorusu · Monte Carlo
Soru 18: Karger Büzme Sırası
Şekildeki çizgede Karger algoritması sırasıyla (2, 3), (1, 2) ve (4, 5) kenarlarını büzüyor (öz-döngüler silinir, paralel kenarlar korunur). Hangi kesim bulunur, kaç kenarlıdır? Minimum mudur?
Cevabı göster
- (2, 3) → süper düğüm {2, 3}; aralarındaki kenar öz-döngü olur, silinir. 6 kenar kalır.
- (1, 2) → {1, 2, 3}; (1, 3) de öz-döngü olur. 4 kenar kalır.
- (4, 5) → {4, 5}. İki süper düğüm kaldı.
Kesim {1, 2, 3} | {4, 5}: 3 kenar (2–4, 3–4, 3–5). Minimum değildir: 1 ve 5'in derecesi 2'dir, ör. {1} | geri kalanı 2 kenarlık kesimdir. Çıktı yanlış olabildiği için Karger bir Monte Carlo algoritmasıdır; çok kez tekrarlanıp en küçük sonuç alınır.