Bölüm 9: Çevrimiçi Algoritmalar
Giriş
Öğrenme Çıktıları
Çevrimiçi (online) ve çevrimdışı (offline) problem modelini ayırt etmek; geri alınamaz karar kavramını açıklamak.
Rekabet oranını (competitive ratio) tanımlamak; kayak kiralama problemi için 2 − 1/B oranını kanıtlamak.
FIFO, LRU ve OPT ile sayfa hatalarını adım adım hesaplamak; LRU'nun k-rekabetçi, MTF'nin 2-rekabetçi olduğunu yorumlamak.
Hareketli ortalama, çevrimiçi ortanca ve rezervuar örneklemeyi Java ile yazmak; eleman başına zaman ve belleği analiz etmek.
Giriş
Bilgi Olsun Yeter
- Bazen kararlar tüm bilgiye sahip olunmadan alınır.
- Çevrimiçi algoritmalar (online algorithms):
- bilginin adım adım geldiği durumlarda
- o ana kadarki bilgiyle en iyi kararı vermeye çalışır.
- Verilen karar geri alınamaz: sonradan gelen bilgi geçmiş kararı değiştirmez.

Giriş
Çevrimiçi Algoritmalar
- Bir labirentte yolculuk yapmaya benzer.
- Labirentin tamamı görünmez; yalnızca önünüzdeki yolu görürsünüz.
- Her adımda sınırlı bilgi ile en iyi yol seçilmeye çalışılır.
- Bilgi akışının sürekli olmadığı durumlarda hızlı karar vermeyi sağlar.
- Örnekler:
- Trafik sıkışıklığında hangi yol kullanılacak?
- Satranç oynarken bir sonraki hamle ne olacak?
- Anlık trafik yoğunluğuna göre ışıkların ayarlanması.

Giriş
Çevrimiçi ve Çevrimdışı Problem Modeli
Girdi bir istek dizisidir: σ = σ1, σ2, …, σn. Fark, algoritmanın bu diziyi ne zaman gördüğündedir.
| Çevrimdışı (offline) | Çevrimiçi (online) | |
|---|---|---|
| Girdi | Tamamı baştan bilinir | Parça parça gelir; σt gelince σt+1 bilinmez |
| Karar | Tüm girdiye bakılarak verilir | σt geldiği anda verilmeli, geri alınamaz |
| Örnek | Sıralama, Dijkstra, sırt çantası (DP) | Önbellek yönetimi, kayak kiralama, borsa |
| En iyi çözüm | OPT hesaplanabilir | OPT ancak geriye dönüp bakınca bilinir |
| Ölçüt | Zaman / bellek karmaşıklığı | Rekabet oranı: ALG / OPT |
Giriş
Çevrimiçi Algoritma Modeli (Online Algorithms)
- Veri sürekli gelir; algoritma her parçayı geldiğinde işler ve hemen çıktı üretir.
- Bellek (tampon, buffer) tüm girdiyi tutamaz: geçmiş ancak özet olarak saklanabilir (toplam, yığın, örnek…).
- Bu yüzden her eleman için az iş (çoğunlukla O(1) ya da O(log n)) ve az bellek hedeflenir.
Giriş
Uygulama Alanları
Ortak nokta: ortam dinamik, karar gerçek zamanlı, geleceğe dair bilgi eksik.
Giriş
Avantajlar ve Dezavantajlar
Avantajlar
- Dinamik ortamlarda çalışır; girdinin bitmesini beklemez.
- Gerçek zamanlı karar verir; gecikme düşüktür.
- Az bellekle çok büyük, hatta sonsuz akışları işleyebilir.
- Rekabet oranı ile en kötü durum garantisi verilebilir.
Dezavantajlar
- İlk adımlarda yanlış kararlar alınabilir ve sonraki adımları etkiler.
- Satrançta yanlış bir hamle oyunu kaybettirebilir.
- Her zaman en iyi global çözümü bulmayı garanti etmez.
- Başlangıçtaki girdiye duyarlıdır; tasarımı ve analizi daha karmaşıktır.
Giriş
Çevrimiçi Algoritma Tasarım Yaklaşımları
Rekabetçi Analiz
Rekabetçi Analiz (Competitive Analysis)
- Çevrimiçi algoritma ALG, her girdide her şeyi önceden bilen en iyi çevrimdışı algoritma OPT ile karşılaştırılır.
- ALG, c-rekabetçidir (c-competitive), eğer her istek dizisi σ içinALG(σ) ≤ c · OPT(σ) + αkoşulu sağlanır (α: σ'dan bağımsız sabit; α = 0 ise kesin rekabetçi).
- En küçük böyle c değerine rekabet oranı denir: c = supσ ALG(σ) / OPT(σ).
- Oran ne kadar 1'e yakınsa, gelecek bilgisinin eksikliği o kadar az zarar verir.
Rekabetçi Analiz
Düşman (Adversary) Modeli
Rekabet oranını alttan sınırlamak için algoritmaya karşı oynayan bir düşman düşünülür: girdiyi o üretir ve OPT'yi o çalıştırır.
Kayak Kiralama
Kayak Kiralama Problemi (Ski Rental)
- Kayak takımı günlüğü 1 TL'ye kiralanabilir ya da B TL'ye satın alınabilir.
- Kaç gün kayak yapılacağı (d) bilinmez: her sabah "bugün de kayacak mıyım?" sorusu yanıtlanır. Hava bozarsa sezon biter.
- Her gün karar: bugün de kirala mı, yoksa satın al mı?
- Geleceği bilen OPT kolaydır: OPT(d) = min(d, B).
Aynı yapı: bulut sunucusunu saatlik mi kiralayalım, yıllık mı alalım; TCP bağlantısını açık mı tutalım, kapatalım mı.
Kayak Kiralama
Stratejilerin Maliyeti (B = 10)
Geleceği bilen OPT: d < 10 ise hep kiralar (maliyet d), d ≥ 10 ise ilk gün satın alır (maliyet 10).
Hep kirala: maliyet d. d büyüdükçe OPT = 10 sabitken maliyet sınırsız artar → rekabetçi değil.
İlk gün satın al: maliyet hep 10. Ama d = 1 ise OPT = 1 → oran 10 = B. Kötü.
Başa baş: 9 gün kirala, 10. gün satın al. d < 10 iken OPT ile aynı; d ≥ 10 iken maliyet 9 + 10 = 19.
En kötü durum d = 10: ALG = 19, OPT = 10 → oran 1,9 = 2 − 1/B. Hiçbir d bundan kötü değildir.
Kayak Kiralama
Neden Daha İyisi Yok? Alt Sınır
Her deterministik strateji tek bir sayı ile tanımlanır: k = satın alma günü.
- Düşman: satın aldığınız günden sonra hava bozar, yani d = k.
- ALG = (k − 1) kira + B, OPT = min(k, B).
- k < B: oran (k − 1 + B) / k ≥ (2B − 1) / B.
- k ≥ B: oran (k − 1 + B) / B ≥ (2B − 1) / B.
- En iyisi k = B: oran 2 − 1/B.
| k | kira | ALG | OPT | oran |
|---|---|---|---|---|
| 1 | 0 | 10 | 1 | 10 |
| 2 | 1 | 11 | 2 | 5,5 |
| 5 | 4 | 14 | 5 | 2,8 |
| 9 | 8 | 18 | 9 | 2 |
| 10 | 9 | 19 | 10 | 1,9 |
| 11 | 10 | 20 | 10 | 2 |
| 15 | 14 | 24 | 10 | 2,4 |
| 20 | 19 | 29 | 10 | 2,9 |
B = 10; d = k (düşmanın seçimi). Tablo, en kötü oranın k = B'de en küçük olduğunu gösterir.
Kayak Kiralama
Deneyin: Kayak Kiralama
Strateji: k − 1 gün kirala, k. gün hâlâ kayıyorsan satın al. En kötü oran, düşmanın d = k seçtiği durumdur.
Sayfalama
Sayfalama Problemi (Paging)
- Hızlı bellek (önbellek, cache) k sayfa tutar; yavaş bellek sınırsızdır.
- İstenen sayfa önbellekteyse isabet (hit, maliyet 0); değilse sayfa hatası (page fault, maliyet 1): sayfa yüklenir.
- Önbellek doluysa hangi sayfa çıkarılacak? Gelecek istekler bilinmez: tipik bir çevrimiçi problem.
- Amaç: toplam sayfa hatası sayısını en aza indirmek.
Sayfalama
Sayfa Çıkarma Politikaları
| Politika | Hangi sayfayı çıkarır? | Çevrimiçi? | Rekabet oranı |
|---|---|---|---|
| FIFO | Önbelleğe en önce yüklenen sayfayı (kuyruk) | evet | k |
| LRU | En uzun süredir kullanılmayan sayfayı (least recently used) | evet | k |
| FWF | Hata olunca ve önbellek doluysa hepsini boşaltır (flush when full) | evet | k |
| LFU | En az sıklıkla kullanılan sayfayı (least frequently used) | evet | sınırsız |
| LIFO | En son yüklenen sayfayı | evet | sınırsız |
| OPT (MIN) | Bir sonraki kullanımı en uzak gelecekte olanı (Belady, 1966) | hayır | 1 |
Sayfalama · Adım adım
FIFO Adım Adım
FIFO: önbellek bir kuyruk gibi davranır; en önce gelen ilk çıkar. İstek dizisi 7 0 1 2 0 3 0 4 2 3 0 3 2, k = 3. H: hata, ✓: isabet.
İstek 1: sayfa 7 yok → sayfa hatası; boş çerçeve Ç1'e yüklenir. Toplam hata: 1.
İstek 2: sayfa 0 yok → sayfa hatası; boş çerçeve Ç2'e yüklenir. Toplam hata: 2.
İstek 3: sayfa 1 yok → sayfa hatası; boş çerçeve Ç3'e yüklenir. Toplam hata: 3.
İstek 4: sayfa 2 yok → sayfa hatası; en önce yüklenen 7 çıkarılır. Toplam hata: 4.
İstek 5: sayfa 0 önbellekte → isabet. FIFO sırası değişmez. Toplam hata: 4.
İstek 6: sayfa 3 yok → sayfa hatası; en önce yüklenen 0 çıkarılır. Toplam hata: 5.
İstek 7: sayfa 0 yok → sayfa hatası; en önce yüklenen 1 çıkarılır. Toplam hata: 6.
İstek 8: sayfa 4 yok → sayfa hatası; en önce yüklenen 2 çıkarılır. Toplam hata: 7.
İstek 9: sayfa 2 yok → sayfa hatası; en önce yüklenen 3 çıkarılır. Toplam hata: 8.
İstek 10: sayfa 3 yok → sayfa hatası; en önce yüklenen 0 çıkarılır. Toplam hata: 9.
İstek 11: sayfa 0 yok → sayfa hatası; en önce yüklenen 4 çıkarılır. Toplam hata: 10.
İstek 12: sayfa 3 önbellekte → isabet. FIFO sırası değişmez. Toplam hata: 10.
İstek 13: sayfa 2 önbellekte → isabet. FIFO sırası değişmez. Toplam hata: 10.
Sayfalama · Adım adım
LRU Adım Adım
LRU: her sayfanın son kullanım zamanı izlenir; en eskisi çıkar. İstek dizisi 7 0 1 2 0 3 0 4 2 3 0 3 2, k = 3. H: hata, ✓: isabet.
İstek 1: sayfa 7 yok → sayfa hatası; boş çerçeve Ç1'e yüklenir. Toplam hata: 1.
İstek 2: sayfa 0 yok → sayfa hatası; boş çerçeve Ç2'e yüklenir. Toplam hata: 2.
İstek 3: sayfa 1 yok → sayfa hatası; boş çerçeve Ç3'e yüklenir. Toplam hata: 3.
İstek 4: sayfa 2 yok → sayfa hatası; en uzun süredir kullanılmayan 7 çıkarılır. Toplam hata: 4.
İstek 5: sayfa 0 önbellekte → isabet. 0 artık en yeni kullanılan sayfa. Toplam hata: 4.
İstek 6: sayfa 3 yok → sayfa hatası; en uzun süredir kullanılmayan 1 çıkarılır. Toplam hata: 5.
İstek 7: sayfa 0 önbellekte → isabet. 0 artık en yeni kullanılan sayfa. Toplam hata: 5.
İstek 8: sayfa 4 yok → sayfa hatası; en uzun süredir kullanılmayan 2 çıkarılır. Toplam hata: 6.
İstek 9: sayfa 2 yok → sayfa hatası; en uzun süredir kullanılmayan 3 çıkarılır. Toplam hata: 7.
İstek 10: sayfa 3 yok → sayfa hatası; en uzun süredir kullanılmayan 0 çıkarılır. Toplam hata: 8.
İstek 11: sayfa 0 yok → sayfa hatası; en uzun süredir kullanılmayan 4 çıkarılır. Toplam hata: 9.
İstek 12: sayfa 3 önbellekte → isabet. 3 artık en yeni kullanılan sayfa. Toplam hata: 9.
İstek 13: sayfa 2 önbellekte → isabet. 2 artık en yeni kullanılan sayfa. Toplam hata: 9.
Sayfalama · Adım adım
OPT Adım Adım
OPT: geleceği bilir; bir sonraki kullanımı en uzak olan sayfayı çıkarır. İstek dizisi 7 0 1 2 0 3 0 4 2 3 0 3 2, k = 3. H: hata, ✓: isabet.
İstek 1: sayfa 7 yok → sayfa hatası; boş çerçeve Ç1'e yüklenir. Toplam hata: 1.
İstek 2: sayfa 0 yok → sayfa hatası; boş çerçeve Ç2'e yüklenir. Toplam hata: 2.
İstek 3: sayfa 1 yok → sayfa hatası; boş çerçeve Ç3'e yüklenir. Toplam hata: 3.
İstek 4: sayfa 2 yok → sayfa hatası; 7 bir daha hiç istenmiyor → çıkarılır. Toplam hata: 4.
İstek 5: sayfa 0 önbellekte → isabet. Toplam hata: 4.
İstek 6: sayfa 3 yok → sayfa hatası; 1 bir daha hiç istenmiyor → çıkarılır. Toplam hata: 5.
İstek 7: sayfa 0 önbellekte → isabet. Toplam hata: 5.
İstek 8: sayfa 4 yok → sayfa hatası; bir sonraki kullanımı en uzak olan 0 (11. istek) çıkarılır. Toplam hata: 6.
İstek 9: sayfa 2 önbellekte → isabet. Toplam hata: 6.
İstek 10: sayfa 3 önbellekte → isabet. Toplam hata: 6.
İstek 11: sayfa 0 yok → sayfa hatası; 4 bir daha hiç istenmiyor → çıkarılır. Toplam hata: 7.
İstek 12: sayfa 3 önbellekte → isabet. Toplam hata: 7.
İstek 13: sayfa 2 önbellekte → isabet. Toplam hata: 7.
Sayfalama
Üç Politikanın Karşılaştırması
| Politika | Sayfa hatası | İsabet | ALG / OPT | Gerekli bilgi |
|---|---|---|---|---|
| FIFO | 10 | 3 | 1,43 | Yükleme sırası (kuyruk) |
| LRU | 9 | 4 | 1,29 | Son kullanım zamanı |
| OPT | 7 | 6 | 1 | Tüm gelecek istekler |
- İlk k = 3 hata kaçınılmazdır (zorunlu / soğuk hatalar, compulsory misses): her politika öder.
- LRU, yerellik (locality of reference) olan dizilerde iyidir: yakın geçmişte kullanılan sayfa yakında yine kullanılır. Burada 0 sayfası sık istendiği için FIFO onu gereksiz yere çıkarır.
- Gerçek sistemlerde LRU'ya yakın, ucuz yaklaşımlar kullanılır: saat algoritması (clock / ikinci şans).
Sayfalama · Kodu adım adım çalıştır
LRU: Kodu Adım Adım İzle
Önbellek boş, hata = 0. Liste başı en eski, sonu en yeni kullanılan sayfa.
Sayfa 1 listede yok: remove false → else dalı.
hata = 1. Önbellekte yer var (boyut 0 < 3) → çıkarma yok.
Sayfa 1 sona eklenir.
Sayfa 2 listede yok: remove false → else dalı.
hata = 2. Önbellekte yer var (boyut 1 < 3) → çıkarma yok.
Sayfa 2 sona eklenir.
Sayfa 3 listede yok: remove false → else dalı.
hata = 3. Önbellekte yer var (boyut 2 < 3) → çıkarma yok.
Sayfa 3 sona eklenir.
Sayfa 1 listede: remove true döner ve onu listeden çıkarır → isabet.
Sayfa 1 sona eklenir: artık en yeni kullanılan.
Sayfa 4 listede yok: remove false → else dalı.
hata = 4. Önbellek dolu → baştaki (en eski kullanılan) 2 çıkarılır.
Sayfa 4 sona eklenir.
Sayfa 2 listede yok: remove false → else dalı.
hata = 5. Önbellek dolu → baştaki (en eski kullanılan) 3 çıkarılır.
Sayfa 2 sona eklenir.
Dizi bitti: 6 istekte 5 sayfa hatası, 1 isabet. remove listeyi taradığı için her istek O(k); HashMap + çift bağlı liste ile O(1) olur.
int lruHata(int[] istekler, int k) { var onb = new LinkedList<Integer>(); int hata = 0; for (int sayfa : istekler) { if (onb.remove((Integer) sayfa)) { onb.addLast(sayfa); // en yeni yap } else { hata++; if (onb.size() == k) onb.removeFirst(); // en eskiyi at onb.addLast(sayfa); } } return hata; }
Sayfalama
LRU Önbelleği: O(1) Uygulama
class LruOnbellek<A, D> extends LinkedHashMap<A, D> { private final int k; LruOnbellek(int k) { super(16, 0.75f, true); // erişim sırası this.k = k; } @Override protected boolean removeEldestEntry( Map.Entry<A, D> enEski) { return size() > k; // k aşılınca at } }
LinkedHashMap= hash tablosu + çift bağlı liste.true(accessOrder): herget/putelemanı listenin sonuna taşır.removeEldestEntry: boyut k'yı aşınca baştaki (en eski kullanılan) silinir.- Bul, taşı, sil: hepsi O(1); bellek O(k).
false (insertion order) ile kurulur: erişim sırayı değiştirmez.Sayfalama
Teorem: Deterministik Alt Sınır k
- k + 1 farklı sayfa yeter. Düşman her adımda ALG'nin önbelleğinde olmayan tek sayfayı ister → ALG her istekte hata yapar.
- OPT (en uzağı çıkar) bir hata yaptığında, çıkardığı sayfa en az k − 1 istek boyunca istenmez → OPT en çok k istekte bir hata yapar.
- Sonuç: ALG / OPT → k (Sleator ve Tarjan, 1985).
Sayfalama
Teorem: LRU (ve FIFO) k-Rekabetçidir
- Diziyi evrelere (phase) böl: her evre, k farklı sayfa içeren en uzun parça; (k + 1). farklı sayfa yeni evreyi başlatır.
- LRU, bir evrede en çok k hata yapar: evrede istenen bir sayfa, evre bitene kadar çıkarılmaz (ondan daha eski kullanılmış en az bir sayfa hep vardır). Her farklı sayfa en çok bir kez hata verir.
- OPT, ardışık iki evre başına en az 1 hata yapar: bir evrenin 2. isteğinden sonraki evrenin 1. isteğine kadar k + 1 farklı sayfa istenir; k çerçeveye sığmaz.
- m evre için LRU ≤ k · m, OPT ≥ m − 1 → LRU ≤ k · OPT + k.
Sayfalama
Belady Anomalisi: Daha Çok Bellek, Daha Çok Hata
- Dizi: 1 2 3 4 1 2 5 1 2 3 4 5.
- FIFO, k = 3: 9 hata; k = 4: 10 hata. Önbellek büyüdü, hata arttı!
- LRU aynı dizide: k = 3 → 10, k = 4 → 8. LRU ve OPT bir yığın algoritmasıdır (stack algorithm): k çerçevedeki sayfalar, k + 1 çerçevedekilerin alt kümesidir → anomali olmaz.
Sayfalama
Rastgele Sayfalama: İşaretleme Algoritması
İşaretleme (Marking)
- Evre başında tüm sayfaların işaretini kaldır.
- İstenen sayfayı işaretle (isabet ya da hata).
- Hata olursa işaretsiz sayfalardan birini rastgele çıkar.
- Tüm sayfalar işaretliyse yeni evre başlar (adım 1).
Sonuçlar
- Habersiz düşmana karşı beklenen oran 2Hk (Fiat vd., 1991).
- Hk = 1 + 1/2 + … + 1/k ≈ ln k. k = 8 için H8 ≈ 2,72 → oran ≈ 5,4 (deterministikte 8).
- Hiçbir rastgele algoritma Hk'dan iyi olamaz.
- LRU da bir işaretleme algoritmasıdır (en eski işaretsizi seçer).
Sayfalama
Deneyin: Sayfalama Politikaları
0–9 arası rakamlar, boşlukla ayrılmış (en çok 16 istek). Turuncu hücre: yeni yüklenen sayfa · yeşil: isabet. Enter = yeniden çalıştır.
Liste Güncelleme
Liste Güncelleme Problemi (List Update)
- n elemanlı bir bağlı liste; i. konumdaki elemana erişmenin maliyeti i'dir (baştan taranır).
- Erişilen eleman, erişimden sonra ücretsiz olarak öne doğru taşınabilir.
- İstekler çevrimiçi gelir: hangi elemanın sık isteneceği bilinmez.
Liste Güncelleme · Adım adım
Öne Taşı (MTF) Adım Adım
Başlangıç listesi A B C D E; istekler E D E A D E.
İstek E: 5. konumda → maliyet 5; başa taşınır. Toplam: 5.
İstek D: 5. konumda → maliyet 5; başa taşınır. Toplam: 10.
İstek E: 2. konumda → maliyet 2; başa taşınır. Toplam: 12.
İstek A: 3. konumda → maliyet 3; başa taşınır. Toplam: 15.
İstek D: 3. konumda → maliyet 3; başa taşınır. Toplam: 18.
İstek E: 3. konumda → maliyet 3; başa taşınır. Toplam: 21. Aynı dizide hiç taşımayan liste 24, yer değiştirme (transpose) 26 öder.
| Strateji | E | D | E | A | D | E | Toplam |
|---|---|---|---|---|---|---|---|
| Öne taşı (MTF) | 5 | 5 | 2 | 3 | 3 | 3 | 21 |
| Taşıma yok | 5 | 4 | 5 | 1 | 4 | 5 | 24 |
| Yer değiştir | 5 | 5 | 5 | 1 | 5 | 5 | 26 |
Liste Güncelleme
Teorem: MTF 2-Rekabetçidir
- Sleator ve Tarjan (1985): her istek dizisi σ için MTF(σ) ≤ 2 · OPT(σ) (yaklaşık; ücretli takaslar sayılmazsa).
- Kanıt fikri: potansiyel fonksiyonu Φ = MTF listesi ile OPT listesi arasındaki ters sıralı çift (inversion) sayısı. Her erişimde MTF'nin gerçek maliyeti + ΔΦ ≤ 2 · (OPT maliyeti) − 1. Bu, amortize analizdir.
Yer değiştir rekabetçi değil
- Son iki eleman sırayla istenir: xn, xn−1, xn, … Her erişim yerini değiştirir ama hep n. ve (n−1). konumda kalır → istek başına ≈ n. MTF ise ilk ikisinden sonra istek başına 2 öder.
Sıklık sayacı da değil
- Önce x1 n kez, x2 n − 1 kez, … istenir; sonra ters sırada. Sayaç eski sırayı uzun süre korur; maliyet Θ(n) kat kötüleşebilir.
Veri Akışları
Veri Akışı (Data Stream) Modeli
- Elemanlar x1, x2, … tek tek gelir; akış çok uzun ya da sonsuz olabilir.
- Her elemana bir kez bakılır (tek geçiş); geçmiş tümüyle saklanamaz.
- Her an bir sorunun cevabı hazır olmalı: "şu ana kadarki ortalama / ortanca / bir örneklem nedir?"
| Problem | Saklanan özet | Eleman başına | Bellek |
|---|---|---|---|
| Hareketli ortalama (son k) | Kuyruk + toplam | O(1) | O(k) |
| Çevrimiçi ortanca | Max-yığın + min-yığın | O(log n) | O(n) |
| Rezervuar örnekleme | k elemanlık örneklem | O(1) | O(k) |
| Akışta örüntü arama | Son m karakter + kayan hash | O(1) | O(m) |
| Çalışan ortalama | n ve μ | O(1) | O(1) |
Veri Akışları
Hareketli Ortalama (Moving Average)
- Akıştaki son k elemanın ortalaması: sensör verisini yumuşatma, borsada 50 günlük ortalama.
- Saf yöntem her seferinde k elemanı toplar: O(k).
- Akıllı yöntem: kayan pencere (sliding window). Toplamı tut; yeni eleman girerken ekle, en eski çıkarken çıkar: O(1).
ortalama = toplam / min(t, k)
class HareketliOrtalama { private final int k; private final Queue<Integer> pencere = new LinkedList<>(); private int toplam = 0; HareketliOrtalama(int k) { this.k = k; } double sonraki(int deger) { if (pencere.size() == k) toplam -= pencere.poll(); pencere.offer(deger); toplam += deger; return toplam / (double) pencere.size(); } }
Veri Akışları · Kodu adım adım çalıştır
Hareketli Ortalama: Kodu Adım Adım İzle
Yeni değer 4. Pencerede 0 eleman var (< 3) → çıkarma yok.
4 kuyruğa eklenir, toplama katılır: toplam = 4.
Ortalama = 4 / 1 = 4.
Yeni değer 8. Pencerede 1 eleman var (< 3) → çıkarma yok.
8 kuyruğa eklenir, toplama katılır: toplam = 12.
Ortalama = 12 / 2 = 6.
Yeni değer 6. Pencerede 2 eleman var (< 3) → çıkarma yok.
6 kuyruğa eklenir, toplama katılır: toplam = 18.
Ortalama = 18 / 3 = 6.
Yeni değer 2. Pencere dolu (boyut 3 = k) → en eski çıkarılacak.
En eski eleman 4 kuyruktan alınır, toplamdan çıkarılır: toplam = 14.
2 kuyruğa eklenir, toplama katılır: toplam = 16.
Ortalama = 16 / 3 = 5,33.
Yeni değer 10. Pencere dolu (boyut 3 = k) → en eski çıkarılacak.
En eski eleman 8 kuyruktan alınır, toplamdan çıkarılır: toplam = 8.
10 kuyruğa eklenir, toplama katılır: toplam = 18.
Ortalama = 18 / 3 = 6.
double sonraki(int deger) { if (pencere.size() == k) toplam -= pencere.poll(); // en eski pencere.offer(deger); toplam += deger; return toplam / (double) pencere.size(); }
Veri Akışları
Çevrimiçi Ortanca (Running Median)
- Her yeni elemandan sonra o ana kadarki ortanca (median) istenir.
- Her seferinde sıralamak: O(n log n). Sıralı diziye eklemek: O(n).
- İki yığın (heap): küçük yarı bir max-yığında (sol), büyük yarı bir min-yığında (sag).
- Değişmezler: sol'daki her eleman ≤ sag'daki her eleman; |sol| = |sag| ya da |sol| = |sag| + 1.
- Ortanca yığın tepelerinden O(1)'de okunur; ekleme O(log n).
new PriorityQueue<>((a, b) -> b - a).Veri Akışları · Kodu adım adım çalıştır
Çevrimiçi Ortanca: Kodu Adım Adım İzle
x = 5: sol boş → sol yığınına eklenir.
Boyutlar 1 ve 0: denge tamam, taşıma yok.
Eleman sayısı tek: ortanca = sol tepesi = 5.
x = 15: 15 > 5 → sag yığınına eklenir.
Boyutlar 1 ve 1: denge tamam, taşıma yok.
Eleman sayısı çift: ortanca = (5 + 15) / 2 = 10.
x = 1: 1 ≤ 5 → sol yığınına eklenir.
Boyutlar 2 ve 1: denge tamam, taşıma yok.
Eleman sayısı tek: ortanca = sol tepesi = 5.
x = 3: 3 ≤ 5 → sol yığınına eklenir.
Denge bozuldu (|sol| = 3, |sag| = 1): sol tepesi 5 sag yığınına taşınır.
Eleman sayısı çift: ortanca = (3 + 5) / 2 = 4.
x = 8: 8 > 3 → sag yığınına eklenir.
Denge bozuldu (|sol| = 2, |sag| = 3): sag tepesi 5 sol yığınına taşınır.
Eleman sayısı tek: ortanca = sol tepesi = 5.
x = 7: 7 > 5 → sag yığınına eklenir.
Boyutlar 3 ve 3: denge tamam, taşıma yok.
Eleman sayısı çift: ortanca = (5 + 7) / 2 = 6.
void ekle(int x) { if (sol.isEmpty() || x <= sol.peek()) sol.offer(x); // küçük yarı else sag.offer(x); // büyük yarı if (sol.size() > sag.size() + 1) sag.offer(sol.poll()); else if (sag.size() > sol.size()) sol.offer(sag.poll()); } double ortanca() { if (sol.size() == sag.size()) return (sol.peek() + sag.peek()) / 2.0; return sol.peek(); }
Veri Akışları
Rezervuar Örnekleme (Reservoir Sampling)
- Uzunluğu bilinmeyen bir akıştan, her elemanın eşit olasılıkla seçildiği k elemanlı bir örneklem tutmak.
- Algoritma R (Vitter, 1985): ilk k elemanı rezervuara koy. Sonra 0 tabanlı i. eleman için (i ≥ k) j = rastgele[0, i] seç; j < k ise rezervuar[j] ← xi.
- i. eleman k / (i + 1) olasılıkla girer; girerse rastgele bir yerdeki elemanı çıkarır.
İlk k eleman için de aynı: girme olasılığı 1, sonraki çarpım k/(k+1) · … · (n−1)/n = k/n. Bellek O(k), eleman başına O(1).
Veri Akışları · Kodu adım adım çalıştır
Rezervuar Örnekleme: Kodu Adım Adım İzle
İlk k = 3 eleman (10, 20, 30) doğrudan rezervuara konur.
i = 3 (değer 40): j = rastgele[0, 3] → j = 1 çıktı (bu izlemede sabitlendi).
j = 1 < 3 → r[1] = 40 (20 çıkar). 40'in girme olasılığı 3/4.
i = 4 (değer 50): j = rastgele[0, 4] → j = 4 çıktı (bu izlemede sabitlendi).
j = 4 ≥ 3 → 50 rezervuara girmez; rezervuar değişmez.
i = 5 (değer 60): j = rastgele[0, 5] → j = 0 çıktı (bu izlemede sabitlendi).
j = 0 < 3 → r[0] = 60 (10 çıkar). 60'in girme olasılığı 3/6.
Akış bitti: örneklem [60, 40, 30]. Başka j değerleriyle başka sonuç çıkar; her eleman 3/6 = 1/2 olasılıkla seçilir.
List<Integer> rezervuar(int[] akis, int k) { List<Integer> r = new ArrayList<>(); for (int i = 0; i < k; i++) r.add(akis[i]); for (int i = k; i < akis.length; i++) { int j = rastgele.nextInt(i + 1); // 0..i if (j < k) r.set(j, akis[i]); } return r; }
Veri Akışları
Akışta Örüntü Arama: Kayan Hash
Akış karakter karakter gelir; örüntü "AB" (m = 2), h = c0·101 + c1 (A = 65, B = 66, C = 67, D = 68). h("AB") = 6631. Yeni karakter gelince hash O(1)'de güncellenir:
| konum | pencere | hesap | hash | sonuç |
|---|---|---|---|---|
| 0 | CA | 67·101 + 65 | 6832 | — |
| 1 | AB | (6832 − 67·101)·101 + 66 | 6631 | eşleşme |
| 2 | BD | (6631 − 65·101)·101 + 68 | 6734 | — |
| 3 | DA | (6734 − 66·101)·101 + 65 | 6933 | — |
| 4 | AB | (6933 − 68·101)·101 + 66 | 6631 | eşleşme |
Akış "CABDAB": örüntü 1. ve 4. konumda. Hash eşitse karakterler de karşılaştırılır (çakışma olabilir). Hash'i her pencerede baştan hesaplamak O(m) sürer; kayan güncelleme ile O(1)'e iner.
Artımlı Öğrenme · Adım adım
Artımlı Öğrenme (Incremental Learning)
Başlangıçta model özgün veri kümesi ile eğitilir: MODEL 1.
Yeni veri 1 gelir. Tüm veriyle baştan eğitmek yerine model yalnızca yeni veriyle güncellenir.
MODEL 2 hem eski hem yeni verideki bilgiyi temsil eder; eski veri yeniden işlenmez.
Yeni veri 2 gelir; aynı güncelleme tekrarlanır.
MODEL 3 üç veri kümesinin bilgisini taşır. Model hep güncel, maliyet yalnızca yeni veri kadardır.
Artımlı Öğrenme
Artımlı Güncelleme ve Zorlukları
Çalışan ortalama
Ortalama yeni elemanla güncellenir; geçmişi saklamaya gerek yoktur:
Akış 4, 8, 6: μ = 4 → 4 + (8 − 4)/2 = 6 → 6 + (6 − 6)/3 = 6.
Çevrimiçi gradyan inişi
Her örnek bir kez kullanılır; η: öğrenme oranı.
Zorluklar
- Felaket boyutunda unutma (catastrophic forgetting): yeni veriye uyum sağlarken eski bilgi kaybolur.
- Kavram kayması (concept drift): verinin dağılımı zamanla değişir; eski veri yanıltıcı olabilir.
- Sıra etkisi: veri hangi sırayla gelirse model ona göre şekillenir.
- Gürültü: tek bir aykırı örnek modeli bozabilir; küçük η ve kayan pencere yardımcı olur.
Özet
Problemler ve Sonuçlar
| Problem | Çevrimiçi algoritma | Sonuç | Not |
|---|---|---|---|
| Kayak kiralama | B − 1 gün kirala, sonra al | 2 − 1/B | deterministikte en iyi; rastgele e/(e−1) |
| Sayfalama | LRU, FIFO, FWF | k | deterministikte en iyi |
| Sayfalama | LFU, LIFO | sınırsız | rekabetçi değil |
| Sayfalama (rastgele) | İşaretleme | 2Hk | alt sınır Hk |
| Liste güncelleme | Öne taşı (MTF) | 2 | yer değiştirme ve sıklık sayacı rekabetçi değil |
| Hareketli ortalama | Kuyruk + toplam | O(1) | bellek O(k) |
| Çevrimiçi ortanca | İki yığın | O(log n) | ortanca okuma O(1) |
| Rezervuar örnekleme | Algoritma R | O(1) | her eleman k/n olasılıkla |
Üst beş satırdaki sayılar rekabet oranı; alttakiler eleman başına zamandır.
Özet
Özet
| Konu | Hatırlanacaklar |
|---|---|
| Model | girdi parça parça gelir; karar hemen verilir ve geri alınamaz |
| Rekabet oranı | ALG(σ) ≤ c · OPT(σ) + α, her σ için; en kötü durum analizi, düşman modeli |
| Kayak kiralama | OPT = min(d, B); başa baş stratejisi 2 − 1/B; daha iyi deterministik strateji yok |
| Sayfalama | FIFO, LRU k-rekabetçi; OPT en uzak geleceği çıkarır; FIFO'da Belady anomalisi |
| Liste güncelleme | maliyet = konum; MTF 2-rekabetçi (potansiyel fonksiyonu: ters çiftler) |
| Veri akışları | tek geçiş, az bellek: kayan pencere, iki yığın, rezervuar, kayan hash |
| Artımlı öğrenme | model yeni veriyle güncellenir; unutma ve kavram kayması zorlukları |
Özet
Sık Yapılan Hatalar
nextInt(i) yazmak olasılıkları bozar.Özet
Örnek Problemler
- İstek dizisi 1 2 3 4 1 2 5 1 2 3 4 5, k = 3 için OPT kaç sayfa hatası yapar?
- Kayak kiralamada B = 20. Başa baş stratejisinin oranı nedir? 5. gün satın alan stratejinin en kötü oranı nedir?
- A B C D listesinde MTF ile D C D A isteklerinin toplam maliyeti nedir?
- Akış 2, 9, 4, 7 için çevrimiçi ortancaları sırasıyla yazın.
- Rezervuar örneklemede k = 2, akışın 0 tabanlı 9. elemanı rezervuara hangi olasılıkla girer? Akış 10 elemanla biterse bu eleman sonda hangi olasılıkla rezervuardadır?
Cevapları göster
- 7 hata: 1 2 3 (zorunlu), 4 (3'ü at), 5 (4'ü at), 3 (1 ya da 2'yi at), 4. FIFO 9, LRU 10 yapar.
- 2 − 1/20 = 1,95. k = 5: d = 5 iken ALG = 4 + 20 = 24, OPT = 5 → 4,8.
- D: 4 → D A B C; C: 4 → C D A B; D: 2 → D C A B; A: 3 → A D C B. Toplam 13.
- 2 → 2; 2, 9 → 5,5; 2, 4, 9 → 4; 2, 4, 7, 9 → 5,5.
- Girme: k/(i + 1) = 2/10 = 1/5. Son eleman olduğu için sonda da 1/5 = k/n.
Özet
Alıştırmalar
- FIFO sayfalamayı bir
Queueve birHashSetile O(1) zamanda yazın. - OPT'yi (Belady) Java ile yazın. Zaman karmaşıklığı nedir?
- Kayak kiralamada "B/2. gün satın al" stratejisinin oranını bulun.
- Çevrimiçi ortancaya
sil(x)eklemek neden zordur? - k = 1 rezervuarda 3 elemanlı akışın her elemanının 1/3 olasılıkla seçildiğini gösterin.
- Son k elemanın en büyüğünü amortize O(1) zamanda bulun.
Cevaplar / ipuçları
- İsabet:
kume.contains(p). Hata: doluysakume.remove(kuyruk.poll()); sonraoffer+add. - Hata başına ileri tarama: toplam O(n² · k); sonraki kullanım indisleri önceden hesaplanıp yığında tutulursa O(n log k).
- d = B/2 iken ALG = (B/2 − 1) + B, OPT = B/2 → oran 3 − 2/B. Başa baştan (2 − 1/B) kötü.
- Yığın keyfi elemanı hızlı silemez; sayaçlı
TreeMapya da tembel silme gerekir. - 1. eleman: 1 · (1/2) · (2/3) = 1/3; 2. eleman: (1/2) · (2/3) = 1/3; 3. eleman: 1/3.
- Monoton azalan deque: yeni gelen küçükleri arkadan atar, pencere dışı baştan çıkar; baştaki en büyüktür.
Özet
Kaynaklar
- A. Borodin ve R. El-Yaniv, Online Computation and Competitive Analysis, Cambridge University Press, 1998.
- D. D. Sleator ve R. E. Tarjan, "Amortized Efficiency of List Update and Paging Rules", Communications of the ACM 28(2), 1985.
- L. A. Belady, "A Study of Replacement Algorithms for a Virtual-Storage Computer", IBM Systems Journal 5(2), 1966.
- A. Fiat, R. M. Karp, M. Luby, L. A. McGeoch, D. D. Sleator ve N. E. Young, "Competitive Paging Algorithms", Journal of Algorithms 12(4), 1991.
- J. S. Vitter, "Random Sampling with a Reservoir", ACM Transactions on Mathematical Software 11(1), 1985.
- Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, 2022 (Bölüm 27: Online Algorithms).