Bölüm 7: Açgözlü Algoritmalar
Çoktan Seçmeli · Açgözlü Yaklaşım
Soru 1: Açgözlü Seçim Özelliği
Bir problemin açgözlü seçim özelliği taşıması ne anlama gelir?
B: İlk açgözlü seçim hiçbir zaman "yanlış yola" sokmaz; bu genellikle değiştirme argümanıyla kanıtlanır. A, optimal alt yapının tanımıdır; açgözlü yöntemin doğru olması için ikisi birlikte gerekir. D, dinamik programlamanın özelliğidir.
Çıktı Sorusu · Para Üstü
Soru 2: Para Üstü Çıktısı
Para üstü metodu seçtiği her parayı yazdıracak biçimde değiştirildi. Program ne yazar? Bu sonuç bu para sistemi için en iyi midir?
static int paraUstu(int[] para, int tutar) { int adet = 0; for (int p : para) { while (tutar >= p) { tutar -= p; adet++; System.out.print(p + " "); } } return adet; } // main: int[] para = {50, 25, 10, 5, 1}; int adet = paraUstu(para, 87); System.out.println(); System.out.println(adet);
Cevabı göster
Çıktı: 50 25 10 1 1 ve alt satırda 5.
- 87 → 50 (kalan 37) → 25 (12) → 10 (2) → 5 sığmaz → 1, 1 (0).
- {50, 25, 10, 5, 1} kanonik bir para sistemidir: açgözlü sonuç her tutar için en iyidir (dinamik programlama da 5 bulur).
- Süre O(k + adet): k = 5 para türü, 5 para seçildi.
Çoktan Seçmeli · Para Üstü
Soru 3: Kanonik Olmayan Para Sistemi
Paralar {10, 7, 1} ve tutar 15. Açgözlü para üstü algoritması kaç para verir; en iyi çözüm kaç paradır?
A: Açgözlü: 10 + 1 + 1 + 1 + 1 + 1 = 6 para. En iyi: 7 + 7 + 1 = 3 para. İlk seçim (10) küresel en iyiyi kaçırır; bu para sistemi açgözlü seçim özelliğini sağlamaz. Genel durumda dinamik programlama gerekir: enAz[t] = 1 + min enAz[t − p].
Adım Adım Çalıştırma · Etkinlik Seçimi
Soru 4: Etkinlik Seçimi İzleme
Etkinlikler (s, f): (1,4), (3,5), (0,6), (5,7), (3,9), (5,9), (6,10), (8,11), (8,12), (2,14), (12,16); id'ler 1–11. sec(e) hangi etkinlikleri yazdırır?
Etkinlikler zaten bitişe göre sıralı (sort sırayı değiştirmez). En erken biten #1 [1, 4) seçilir; kesikli çizgi son seçilenin bitişi.
#2 [3, 5): 3 < 4 → çakışıyor, atlandı.
#3 [0, 6): 0 < 4 → çakışıyor, atlandı.
#4 [5, 7): 5 ≥ 4 → seçildi, i = 3.
#5 [3, 9): 3 < 7 → çakışıyor, atlandı.
#6 [5, 9): 5 < 7 → çakışıyor, atlandı.
#7 [6, 10): 6 < 7 → çakışıyor, atlandı.
#8 [8, 11): 8 ≥ 7 → seçildi, i = 7.
#9 [8, 12): 8 < 11 → çakışıyor, atlandı.
#10 [2, 14): 2 < 11 → çakışıyor, atlandı.
#11 [12, 16): 12 ≥ 11 → seçildi, i = 10. Sonuç: 4 etkinlik.
static void sec(Etkinlik[] e) { Arrays.sort(e, (x, y) -> x.bitis - y.bitis); int i = 0; // son seçilen System.out.print(e[i].id + " "); for (int j = 1; j < e.length; j++) { if (e[j].bas >= e[i].bitis) { System.out.print(e[j].id + " "); i = j; } } }
Çoktan Seçmeli · Etkinlik Seçimi
Soru 5: Doğru Ölçüt
Tek salonda birbiriyle çakışmayan en fazla sayıda etkinliği seçmek için hangi açgözlü ölçüt her zaman en iyi sonucu verir?
D: En erken biten etkinlik, kalan zamanı en çok bırakan seçimdir; değiştirme argümanı ile bu seçimi içeren bir en iyi çözüm olduğu gösterilir. En erken başlayan, uzun bir etkinliği seçip birçok kısa etkinliği engelleyebilir; en kısa ve en az çakışan ölçütlerinin de karşı örnekleri vardır.
Klasik Soru · Etkinlik Seçimi
Soru 6: Değiştirme Argümanı
Etkinlik seçiminde "en erken biten etkinliği seç" kuralının en iyi sonucu verdiğini değiştirme argümanıyla kanıtlayın.
Cevabı göster
- a₁ en erken biten etkinlik, O = {b₁, b₂, …, bk} bitişe göre sıralı bir en iyi çözüm olsun.
- b₁ = a₁ ise kanıt biter. Değilse O' = O − {b₁} ∪ {a₁} kurulur.
- f(a₁) ≤ f(b₁) ≤ s(b₂) olduğundan a₁, b₂ … bk ile çakışmaz: O' uygundur ve |O'| = |O| = k, yani O' de en iyidir.
- Demek ki a₁'i içeren bir en iyi çözüm vardır (açgözlü seçim özelliği). a₁ ve onunla çakışanlar atılınca kalan problem aynı türdendir (optimal alt yapı); tümevarımla her adımdaki seçim doğrudur.
Aynı kalıp Huffman ve Kruskal kanıtlarında da kullanılır: bir en iyi çözümü, daha kötü yapmadan açgözlü seçimi içerecek biçimde değiştirmek.
Adım Adım Çalıştırma · İş Sıralama
Soru 7: İş Sıralama İzleme
İşler (id, son tarih, kâr): (1, 2, 100), (2, 1, 19), (3, 2, 27), (4, 1, 25), (5, 3, 15). isSirala(is, 5) slotları nasıl doldurur, ne döndürür?
Kâra göre azalan sıra: İş 1 (100), İş 3 (27), İş 4 (25), İş 2 (19), İş 5 (15). n = 5 slot, hepsi boş (−1).
İş 1 (son tarih 2, kâr 100): en geç uygun slot 2 boş → yerleştirildi. toplam = 100.
İş 3 (son tarih 2, kâr 27): slot 2 dolu, bir öncesine bakılır; slot 1 boş → yerleştirildi. toplam = 127.
İş 4 (son tarih 1, kâr 25): slot 1'e kadar hepsi dolu → iş atlanır.
İş 2 (son tarih 1, kâr 19): slot 1'e kadar hepsi dolu → iş atlanır.
İş 5 (son tarih 3, kâr 15): en geç uygun slot 3 boş → yerleştirildi. toplam = 142.
Sonuç: sırayla İş 3, İş 1, İş 5 yapılır; toplam kâr 142. İş 4 ve İş 2 son tarihine yetişemez.
static int isSirala(Is[] is, int n) { Arrays.sort(is, (a, b) -> b.kar - a.kar); int[] slot = new int[n]; Arrays.fill(slot, -1); int toplam = 0; for (int i = 0; i < n; i++) { int j = Math.min(n, is[i].sonTarih) - 1; for (; j >= 0; j--) { if (slot[j] == -1) { slot[j] = is[i].id; toplam += is[i].kar; break; } } } return toplam; }
Çoktan Seçmeli · İş Sıralama
Soru 8: En Geç Boş Slot
İş sıralama algoritması her işi son tarihinden önceki en geç boş slota koyar. Bunun nedeni nedir?
B: Bir işi gereğinden erken bir slota koymak, sonra gelecek ve son tarihi daha erken olan bir işin yerini kapatabilir. En geç boş slot seçimi esnekliği korur. Slot araması yine O(dmax) sürer (en kötü O(n²)); Union-Find ile neredeyse O(n)'e iner.
Çıktı Sorusu · İş Sıralama
Soru 9: Açgözlü İş Sıralama Kârı
İşler (kâr, son tarih): a(90, 2), b(20, 1), c(40, 2), d(30, 1), e(10, 3). isSirala hangi sırayı ve toplam kârı bulur? İşler kâr yerine son tarihe göre sıralansaydı ne olurdu?
Cevabı göster
Kâr sırası a, c, d, b, e:
- a → j = 1; c → j = 1 dolu → j = 0.
- d ve b (son tarih 1): tek slot j = 0 dolu → atlanır.
- e → j = 2.
Sıra c, a, e, toplam kâr 140 (optimum). Son tarih sırası (b, d, a, c, e) b → j = 0, d atlanır, a → j = 1, c atlanır, e → j = 2: yalnızca 20 + 90 + 10 = 120. Açgözlü kural kâr sırasıdır; son tarih yalnızca dilim seçiminde kullanılır.
Çıktı Sorusu · Sırt Çantası
Soru 10: Kesirli Sırt Çantası
Nesneler (kâr, ağırlık): (24, 4), (18, 6), (30, 5), (10, 5), (12, 3); kapasite W = 15. Kesirli sırt çantası metodu ne yazdırır?
static double kesirli(int[][] n, int W) { // n[i] = {kâr, ağırlık}; orana göre azalan Arrays.sort(n, (a, b) -> Double.compare( (double) b[0] / b[1], (double) a[0] / a[1])); double deger = 0; for (int[] x : n) { if (W == 0) break; int al = Math.min(x[1], W); deger += (double) x[0] * al / x[1]; W -= al; } return deger; } // main: n = {{24,4},{18,6},{30,5},{10,5},{12,3}} System.out.println(kesirli(n, 15));
Cevabı göster
Çıktı: 75.0
| nesne | (24, 4) | (30, 5) | (12, 3) | (18, 6) | (10, 5) |
|---|---|---|---|---|---|
| oran | 6 | 6 | 4 | 3 | 2 |
| alınan | 4 (tümü) | 5 (tümü) | 3 (tümü) | 3/6 | — |
| kâr | 24 | 30 | 12 | 9 | — |
24 + 30 + 12 + 9 = 75. Sıralama O(n log n), tek geçiş O(n). Eşit oranlı (24, 4) ve (30, 5) hangi sırada alınırsa alınsın sonuç değişmez.
Çoktan Seçmeli · Minimum Kapsayan Ağaç
Soru 11: MST Hakkında Yanlış İfade
Minimum kapsayan ağaç (MST) hakkındaki ifadelerden hangisi yanlıştır?
D: Ağırlıkların hepsi farklıysa MST tektir; Prim ve Kruskal aynı ağacı bulur. Eşit ağırlıklarda farklı ağaçlar bulabilirler ama toplam ağırlık aynıdır. A doğrudur: her kapsayan ağaç V − 1 kenarlıdır, tüm toplamlar aynı miktar artar ve kenarların sırası değişmez. B doğrudur: Kruskal'da sıralama yönünü çevirmek yeterlidir.
Çoktan Seçmeli · Minimum Kapsayan Ağaç
Soru 12: Kesim Özelliği
Düğümler S ve V − S diye iki kümeye ayrılıyor. Kesim özelliğine göre hangisi doğrudur (ağırlıklar farklı)?
C: Kesimi geçen en hafif kenar MST'dedir; Borůvka (her bileşenden çıkan en hafif kenar), Kruskal (iki bileşeni ayıran en hafif kenar) ve Prim bu özelliği kullanır. Kesimi geçen en ağır kenar, kesimi geçen tek kenarsa MST'dedir; bu yüzden A yanlıştır. B yanlıştır: çizgenin en hafif kenarı her zaman MST'dedir.
Çoktan Seçmeli · Minimum Kapsayan Ağaç
Soru 13: Üç MST Algoritması
Kruskal, Prim ve Borůvka algoritmaları için hangisi doğrudur?
B: Borůvka'da her bileşen kendi kesiminin en hafif kenarını seçer ve seçilenler birlikte eklenir; seçimler birbirinden bağımsız olduğu için paralel çalışmaya uygundur. A Kruskal'ı, C Prim'i anlatır: Prim ağaçtan çıkan en hafif kenarı ekler, Kruskal bir ormanı birleştirir. D yanlıştır: yalnız Kruskal kenarları sıralar; Prim öncelikli kuyruk kullanır, Borůvka her turda kenarları bir kez tarar.
Adım Adım Çalıştırma · Huffman Kodlama
Soru 14: Huffman Ağacı İzleme
Frekanslar a:5, b:9, c:12, d:13, e:16, f:45. huffman(h, f) hangi birleştirmeleri yapar? Kodlar ve toplam bit sayısı ne olur?
Her karakter frekansıyla bir yaprak olarak min-heap'e eklendi: a5, b9, c12, d13, e16, f45.
poll() iki kez: a5 ve b9 → yeni iç düğüm 14 = 5 + 9, kuyruğa eklenir.
poll() iki kez: c12 ve d13 → yeni iç düğüm 25 = 12 + 13, kuyruğa eklenir.
poll() iki kez: (14) ve e16 → yeni iç düğüm 30 = 14 + 16, kuyruğa eklenir.
poll() iki kez: (25) ve (30) → yeni iç düğüm 55 = 25 + 30, kuyruğa eklenir.
poll() iki kez: f45 ve (55) → yeni iç düğüm 100 = 45 + 55, kuyruğa eklenir.
Kök (100) döner. Sol 0, sağ 1: f = 0, c = 100, d = 101, a = 1100, b = 1101, e = 111. Toplam 45·1 + 12·3 + 13·3 + 5·4 + 9·4 + 16·3 = 224 bit (sabit 3 bitle 300).
static Dugum huffman(char[] h, int[] f) { PriorityQueue<Dugum> kuyruk = new PriorityQueue<>((a, b) -> a.f - b.f); for (int k = 0; k < h.length; k++) kuyruk.add(new Dugum(h[k], f[k])); while (kuyruk.size() > 1) { Dugum sol = kuyruk.poll(); Dugum sag = kuyruk.poll(); Dugum ata = new Dugum('\0', sol.f + sag.f); ata.sol = sol; ata.sag = sag; kuyruk.add(ata); } return kuyruk.poll(); }
Çıktı Sorusu · Huffman Kodlama
Soru 15: Huffman ile Çözme
Huffman ağacında sol kenar 0, sağ kenar 1'dir: F = 000, O = 001, E = 01, T = 10, G = 110, R = 111. 0110111001000 bit dizisi hangi metne çözülür? Aynı metin 3 bitlik sabit kodla kaç bit tutardı?
Cevabı göster
Kökten başla, yaprağa gelince karakteri yaz ve köke dön:
01 | 10 | 111 | 001 | 000 → ETROF
- Huffman: 13 bit; sabit kod: 5 × 3 = 15 bit.
- Ayırıcı gerekmez: kodlar önek-özgürdür (her karakter bir yaprakta), bir kod bittiği an kesin olarak bilinir.
- Çözücünün ağaca (ya da kod tablosuna) sahip olması gerekir; ağaç sıkıştırılmış veriyle birlikte gönderilir.
Çoktan Seçmeli · Huffman Kodlama
Soru 16: Önek-Özgür Kod
Aşağıdaki kod kümelerinden hangisi önek-özgürdür (hiçbir kod başka bir kodun öneki değildir)?
C: {0, 10, 110, 111}: hiçbiri diğerinin başlangıcı değildir; bu, bir ikili ağacın dört yaprağına karşılık gelir. A'da 0, 01'in önekidir ("01" → "ab" mi "b" mi?). B'de 1, 10'un; D'de 0, 00 ve 01'in önekidir.