24  Dinamik Programlama 1: SRTBOT

Özyineleme + memoization: alt problemleri SRTBOT çerçevesiyle tanımla, bir recurrence ile ilişkilendir, topolojik sırada bir memo tablosunda sakla — Fibonacci üstelden polinoma iner, bowling ise suffix-DP’de yerel kaba kuvvetle O(n)’e; kursun yepyeni bölümünün, kendi algoritmanı tasarlama bölümünün açılış dersi

NotOturum bilgisi

Bu, kursun yepyeni bölümünün açılışıdır: hazır algoritma uygulamaktan kendi algoritmanı tasarlamaya geçiyoruz. Demaine ile başlayan bu blok, en güçlü algoritmik tasarım paradigmasını öğretir: dinamik programlama (DP). Özü iki kelimedir — özyineleme + memoization — ve tasarımı bir akronime bağlanır: SRTBOT.

24.1 Bu Derste Ne Var?

Kursun yepyeni bölümü başlıyor (Erik Demaine). Şimdiye dek hazır algoritmaları (sıralama, çizge, veri yapısı) uyguluyorduk; bundan sonra kendi algoritmamızı sıfırdan tasarlayacağız — özellikle dinamik programlama (DP), en güçlü algoritmik tasarım paradigması.

“dynamic programming… It’s probably the most powerful algorithmic design paradigm.” — Demaine, 1:00

DP’nin özü iki kelimedir: özyineleme + memoization. Tasarım için bir akronim: SRTBOT.

“when I say dynamic programming, I mean recursion with memoization.” — Demaine, 27:13

Üç ana fikir:

  1. SRTBOT — özyinelemeli algoritma tasarımının 6 adımı: Subproblems, Relations, Topological order, Base case, Original problem, Time.
  2. Memoization — alt problem çözümlerini sakla/yeniden kullan; Fibonacci’yi üstelden polinoma indirir.
  3. Yerel kaba kuvvet (local brute force) — “ilk öğeye ne yapabilirim?” sorusunun polinom seçeneği varsa, polinom bir DP elde edilir.
flowchart TD
    A["Ders 23 (L15): Dinamik Programlama 1 — SRTBOT"] --> D["DP = özyineleme + memoization"]
    D --> Da["en güçlü tasarım paradigması<br/>iki kelimelik öz (Demaine)"]
    A --> S["SRTBOT — 6 adım"]
    S --> Sa["Subproblems / Relations / Topological<br/>Base / Original / Time; en zoru S"]
    A --> M["Memoization"]
    M --> Ma["alt problem çözümünü sakla + yeniden kullan<br/>Fibonacci üstelden polinoma"]
    A --> T["Süre formülü"]
    T --> Ta["alt problemler toplamı çarpı özyineleme-dışı iş<br/>her alt problem en fazla bir kez"]
    A --> B["Yerel kaba kuvvet"]
    B --> Ba["ilk öğenin sabit seçeneklerini dene + reuse<br/>bowling B(i)=max(atla,tek,çift) O(n)"]

    classDef root fill:#fef3c7,stroke:#b45309,stroke-width:3px,color:#1f2937
    classDef branch fill:#f3f4f6,stroke:#374151,stroke-width:2px,color:#1f2937
    classDef leaf fill:#ffffff,stroke:#9ca3af,stroke-width:1px,color:#1f2937
    class A root
    class D,S,M,T,B branch
    class Da,Sa,Ma,Ta,Ba leaf
Şekil 24.1: Ders 23’ün (L15) kavram haritası: kök = Dinamik Programlama 1 ve SRTBOT (Demaine) — DP ünitesinin açılış dersi; algoritma uygulamaktan algoritma TASARLAMAYA geçiş. Beş dal — (1) DP = özyineleme + memoization: en güçlü tasarım paradigması, iki kelimelik öz. (2) SRTBOT 6 adım: Subproblems, Relations, Topological order, Base case, Original problem, Time; en zoru S (doğru alt problemi bulmak). (3) Memoization: alt problem çözümünü sakla, yeniden kullan; Fibonacci üstelden (phi üzeri n) polinoma (n alt problem). (4) Süre formülü: alt problemler toplamı çarpı özyineleme-dışı iş; her alt problem en fazla bir kez. (5) Yerel kaba kuvvet: ilk öğenin sabit sayıda seçeneğini dene plus reuse; bowling suffix-DP B(i) = max(atla, tek, çift) O(n). Sonuç: DAG en kısa yol da bir DP’dir, memo gizli bir DFS’tir; dizi girdide önek/sonek/alt-dizi seç, alt-dizilim ASLA (2 üzeri n).
İpucuBuilder Notu — Memoization = caching

DP’nin tek değiştirdiği şey, saf özyinelemeye “hesaplananı sakla, gerektiğinde yeniden kullan” cümlesini eklemektir. Bu desen gerçek sistemlerde önbelleklemenin (caching) ta kendisidir: pahalı bir hesap (HTTP isteği, veritabanı sorgusu, embedding çıkarımı) bir kez yapılır, sonucu bir tabloya yazılır, aynı girdi tekrar gelince tablodan döner. Fibonacci’nin üstelden polinoma inişi, bir memcache/Redis katmanının neden bu kadar büyük bir hız farkı yarattığının minyatür ispatıdır.

  • İleriye → DP her yerde: dizi hizalama (DNA, diff), Viterbi/DTW (ses/ML), en kısa yol, knapsack, metin akıllı-kırpma — hepsi DP.
  • İleriye → memoization = caching: “hesaplananı sakla/yeniden kullan” deseni, gerçek sistemde önbellekleme.
  • Geriye → DAG shortest paths (Ders 16): DAG relaxation aslında bir DP; SRTBOT içinde gizli bir DFS çalışır.
  • İleriye → DP 2-4 (Ders 24-27): string, ağaç, pseudopolinom alt problemler.

Tek cümle: DP = özyineleme + memoization; SRTBOT ile alt problemleri tanımla, bir recurrence ile ilişkilendir, topolojik sırada çöz, çözümleri bir memo tablosunda sakla — böylece “yerel kaba kuvvet” üstel aramayı polinom zamana indirir.

24.2 1. Yeni Bölüm: Algoritmik Tasarım ve DP

Şimdiye dek “ver(il)en algoritmaya indirge” yaptık. Artık sıfırdan polinom-zaman algoritma tasarlıyoruz. DP, özyinelemeli bir tasarım türüdür ve tümevarımla kanıt tekniğimizle çok iyi uyuşur.

“Today we start a totally new section of the class.” — Demaine, 0:18

DP’nin temeli: alt problemleri tanımla, aralarındaki ilişkiyi (recurrence) yaz, çevrimsiz (DAG) bir alt-problem grafı kur, çözümleri sakla. Tüm dersi tek bir disiplinde toparlayan akronim SRTBOT’tur.

24.3 2. SRTBOT Çerçevesi

Özyinelemeli algoritma tasarımının altı adımı (akronim SRTBOT):

“SRTBOT… sub-problems, relations, topological order, base case, original problem, and time.” — Demaine, 2:33

  • S — Subproblems (alt problemler): problemi polinom sayıda alt probleme böl. En zor adım — doğru alt problemi bulmak.
  • R — Relations (ilişki): bir alt problemi daha küçüklerinden çöz (recurrence).
  • T — Topological order: alt-problem grafı DAG olmalı (çevrim = sonsuz döngü); topolojik sıra.
  • B — Base case (taban durum): özyinelemenin durağı.
  • O — Original problem: çözmek istediğin (genelde alt problemlerden biri).
  • T — Time (süre): \(\sum\) (alt problemler) \(\times\) özyineleme-dışı iş.

DP = SRTBOT + memoization.

Şekil 24.2 altı adımı tek bir yatay zincirde toplar; her kutuda adımın adı, Türkçe tek-satır açıklaması ve altında bu dersin bowling örneğindeki karşılığı yer alır (S: sonek \(B(i)\), R: \(\max\)(atla, tek, çift), …, O: \(B(0) = 109\) — bu sayı motordan canlı hesaplanır, T: \(7\) alt problem \(\times\, O(1) = O(n)\)).

Şekil 24.2: SRTBOT — özyinelemeli tasarımın 6 adımı yatay zincir (Demaine L15 §2): S→R→T→B→O→T. Her kutuda adım adı (İngilizce) + Türkçe tek-satır açıklama + altında BOWLING karşılığı (amber). S: Subproblems — B(i) = i’den sona sonek max skoru. R: Relations — max(atla, tek v_i, çift v_i·v_{i+1}). T: Topological — i azalan (n → 0). B: Base — B(n)=B(6)=0. O: Original — B(0)=109 (motordan canlı). T: Time — 7 alt problem × O(1) = O(n). Amber oklar zinciri kutudan kutuya bağlar. Alt not: Demaine 2:33 — her DP çözümü bu altı adımın bir örneğidir. DP = SRTBOT + memoization. Veri MOTORDAN: bowling_bottom_up([1,9,9,2,−5,−5])[0] == 109 (assert); B(n)=B(6)=0 taban (assert); n=6 → T kutusu ‘7 alt problem × O(1) = O(n)’.

24.4 3. Örnek: Merge Sort SRTBOT ile

Bildiğimiz merge sort’u SRTBOT’a oturtalım. S: \(S(i, j) = A[i..j-1]\)’i sırala. O: \(S(0, n)\). R: \(S(i, j) = \mathrm{merge}(S(i, m), S(m, j))\) (\(m\) = orta). T: \(j - i\) artan sırada. B: boş dizi. Time: \(O(n \log n)\).

(Merge sort memoization’dan yararlanmaz — alt diziler ayrık, tekrar yok. Ama çerçeve uygulanabilir; SRTBOT yalnızca DP’ye değil, her özyinelemeli tasarıma uyar.)

24.5 4. Fibonacci: Memoization’sız Üstel

Fibonacci: \(f_n = f_{n-1} + f_{n-2}\), \(f_1 = f_2 = 1\). S: \(f(i) = i\). Fibonacci. R: \(f(i) = f(i-1) + f(i-2)\). Doğal özyineleme — ama özyineleme ağacı çizilince \(f(n-3), f(n-2)\) gibi alt problemler defalarca hesaplanır.

\(T(n) = T(n-1) + T(n-2) + 1 \to\) çözüm yaklaşık \(\varphi^n\) (altın oran, üstel). Üstel = kötü; yalnız çok küçük \(n\) çözülür.

Şekil 24.3 bu dersin imza karşılaştırmasını verir: solda \(f(6)\)’nın tam özyineleme ağacı (memoization YOK) — motordan sayılan tekrarlar amber tonlarıyla işaretli (\(f(3)\) tam 3 kez, \(f(2)\) 5 kez, \(f(1)\) 3 kez; ağaç \(15\) düğüm = naif \(15\) çağrı); sağda aynı alt problemler memoization ile tek kopya zincir-DAG (\(f(1) \ldots f(6)\)) ve büyük sayılar paneli (\(n = 20\): naif \(13.529\) çağrı, memo TAM \(20\) alt problem; oran \(\mathrm{calls}(20)/\mathrm{calls}(15) = 11{,}10 \approx \varphi^5 = 11{,}09\) — büyüme \(\approx \varphi^n\) üstel).

Şekil 24.3: Fibonacci: özyineleme ağacından memoization’a — üstelden polinoma (Demaine L15 §4-5 İMZA). SOL: f(6) tam özyineleme ağacı (memoization YOK); tekrarlanan alt problemler aynı amber tonuyla — f(3) 3 kez, f(2) 5 kez, f(1) 3 kez (motordan sayıldı); ağaç 15 düğüm = naif 15 çağrı. SAĞ: aynı düğümler memo ile TEK KOPYA zincir-DAG (f(1)..f(6)); her f(i)’den f(i−1) ve f(i−2)’ye geri-ok (bir kez hesapla, sonra oku); büyük sayılar paneli — n=20: naif 13.529 çağrı vs memo TAM 20 alt problem; oran(20/15) = 11.10 ≈ phi^5 = 11.09 → büyüme yaklaşık phi^n ÜSTEL. Veri MOTORDAN (assert): fib_naive_counted(20) = (6765, 13529); fib_naive_counted(15)[1] = 1219; fib_naive_counted(6) = (8, 15); fib_memo_counted(20) = (6765, 20); ratio 13529/1219 = 11.10 ≈ phi^5 = 11.09; f(6) ağaç düğüm 15, f(3) tekrar 3.

24.6 5. Memoization: Üstelden Polinoma

Küçük bir kurnazlık her şeyi değiştirir: memoization — alt problem çözümlerini bir “memo” tablosuna yaz, gerektiğinde yeniden kullan.

“remember and reuse solutions to sub-problems.” — Demaine, 14:14

Generic DP yapısı (her DP böyledir):

memo = {}
def f(subproblem):
    if subproblem in memo:          # daha once cozuldu mu?
        return memo[subproblem]     # tekrar etme, dondur
    if base_case(subproblem):       # taban durum
        result = base_value
    else:                           # recurrence ile ozyinele
        result = relation(f, subproblem)
    memo[subproblem] = result       # sakla
    return result

Memo tablosu genelde bir doğrudan-erişim dizisi veya hash tablosu. Fibonacci için: her alt problem en fazla bir kez çözülür \(\to\) n alt problem \(\times\, O(1)\) \(= O(n)\). (Bir DFS’in “ziyaret edildi mi” kontrolünü oynar memo tablosu.)

Şekil 24.4 bu generic iskeleti bir akış diyagramı olarak çizer: çağrı \(\to\) “alt problem memoda mı?” (EVET \(\to\) tabloyu döndür, tekrar hesaplama YOK) \(\to\) “taban durum mu?” (EVET \(\to\) taban değer; HAYIR \(\to\) recurrence ile özyinele) \(\to\) sonucu sakla \(\to\) döndür. Sağ alt köşede, memonun bir DFS’in “ziyaret edildi mi” kontrolünü oynadığı not edilir. Motor tanığı: \(\mathrm{bowling\_memo\_counted}([1,9,9,2,-5,-5]) = (109, 7)\)\(n+1 = 7\) alt problem, her biri tam bir kez.

Şekil 24.4: Generic DP iskeleti — f(alt problem) akış diyagramı (Demaine L15 §5 pseudocode birebir): memo kontrolü → taban → recurrence → sakla. SOL DİKEY ANA AKIŞ: çağrı → karar ‘ap ∈ memo?’ → (HAYIR) karar ‘taban durum?’ → (EVET) result = taban değer / (HAYIR) result = relation(f, ap), özyinele → her iki dal SAKLA kutusunda birleşir (memo[ap] = result, amber). SAĞ: memo HIT kısa-devresi — ‘ap ∈ memo?’ EVET → memo[ap] döndür, TEKRAR HESAPLAMA YOK (amber kalın) → return result. SAĞ ALT KÖŞE: memo = bir DFS’in ziyaret-edildi-mi kontrolü; DP içinde GİZLİ DFS çalışır (Demaine §7). ALT NOT (motor tanıklı): her alt problem EN FAZLA BİR KEZ çözülür → T = Σ (alt problem) × (özyineleme-dışı iş); tanık bowling([1,9,9,2,−5,−5]) → skor 109, 7 alt problem (n+1). Veri MOTORDAN (assert): bowling_memo_counted([1,9,9,2,−5,−5]) == (109, 7); fib_memo_counted(10) == (55, 10); ikisi de AYNI iskelet.

24.7 6. Çalışma Süresi Formülü

Memoization’lı bir DP’nin süresi:

T = Σ (tüm alt problemler) × (recurrence’ın özyineleme-dışı işi)

“the time it takes is at most the sum over all sub problems of the relation time.” — Demaine, 23:07

Çünkü her alt problem en fazla bir kez çözülür; özyinelemeli çağrılar zaten toplama dahildir. (Fibonacci: \(n \times O(1) = O(n)\).)

Word-RAM inceliği. Fibonacci sayıları \(n\)-bit büyüklüğüne ulaşır; bir \(w\)-bit makine sözcüğünde toplama, \(\lceil n/w \rceil\) sözcük işine mal olur. Dolayısıyla daha hassas süre \(O(n + n^2/w)\)’dir — ama bu da \(w\) sabitken polinom kalır. Asimptotik tablo değişmez: memoization, Fibonacci’yi üstelden polinoma indirir.

24.8 7. DAG En Kısa Yol DP Olarak

DAG tek-kaynak en kısa yol (Ders 16) aslında bir DP’dir. S: \(\delta(s, v)\) tüm \(v\). O: hepsi. R:

\[\delta(s, v) = \min\bigl(\{\delta(s, u) + w(u, v) : (u, v) \text{ gelen kenar}\} \cup \{\infty\}\bigr)\]

T: alt-problem grafı = \(G\)’nin kendisi \(\to\) \(G\)’nin topolojik sırası. B: \(\delta(s, s) = 0\). Time: \(\sum\) (gelen kenar sayısı \(+ 1\)) \(= O(V + E)\).

İlginç: generic DP algoritması (memo-kontrol \(\to\) özyinele) alt-problem grafının tersinde bir DFS çalıştırır; memo tablosu “ziyaret edildi mi” kontrolüdür. Yani DP, içinde DFS + topolojik sıra barındırır — “bedavaya”.

Şekil 24.5 bu denkliği Ders 16 örneğiyle kanıtlar: solda \(8\) düğümlü DAG (topolojik sıra \(a, b, e, f, g, h, d, c\); kaynak \(e\)), her düğümün üstünde motordan hesaplanan \(\delta\) rozeti (\(e{:}0, f{:}3, g{:}5, h{:}6, d{:}3, c{:}8\); \(a = b = \infty\) soluk, erişilmez), ve \(h\) için gelen-kenar min recurrence’ı vurgulu (\(\delta(h) = \min(\delta(f)+8, \delta(g)+1) = \min(11, 6) = 6\); kazanan \(g \to h\) amber, kaybeden \(f \to h\) kesikli + “11” üstü çizik); sağda recurrence kutusu, SRTBOT eşleme tablosu (S/R/T/B/O/T) ve alt tanık rozeti — memoized çağrı sayısı \(= 8 = V\) (gizli DFS tanığı), \(\mathrm{dag\_sp\_memoized}\) ile \(\mathrm{dag\_relaxation}\) aynı \(\delta\)’yı BİREBİR verir (D16 çapraz tanık).

Şekil 24.5: DAG en kısa yol = Dinamik Programlama (Demaine L15 §7; D16 köprüsü): delta(s,v) = min{ gelen δ(s,u)+w(u,v) } ∪ {∞}. SOL: D16 çizgesi (8 düğüm; topo sırası a,b,e,f,g,h,d,c soldan sağa); her düğümün üstünde δ değeri rozetli (e=0 amber kaynak; a,b=∞ soluk erişilemez). h için GELEN-kenar min recurrence vurgulu: δ(h) = min(δ(f)+8, δ(g)+1) = min(11, 6) = 6 — kazanan g→h amber kalın, kaybeden f→h kesikli + ‘11’ üstü çizik. SAĞ: recurrence kutusu + SRTBOT eşleme tablosu (S alt problem / R ilişki / T topo sıra / B taban / O orijinal / T süre = O(V+E)) + alt rozet (memoized çağrı sayısı = 8 = V gizli DFS tanığı; dag_relaxation ile BİREBİR). Veri MOTORDAN (assert): topo == [a,b,e,f,g,h,d,c]; delta == {a:∞,b:∞,e:0,f:3,g:5,h:6,d:3,c:8}; nsub == 8 == V; delta == dag_relaxation (D16 çapraz tanık); δ(f)+8=11, δ(g)+1=6, δ(h)=min(11,6)=6.
İpucuBuilder Notu — DAG = build sistemi

Alt-problem grafının çevrimsiz (DAG) olması bir tesadüf değil, bir zorunluluktur: çevrim olsaydı bir alt problem kendini beklerdi (sonsuz döngü). Bu yapı gerçek mühendislikte her gün karşına çıkar — build sistemleri (Make, Bazel, webpack), paket bağımlılık çözücüler, elektronik tablo hücre yeniden-hesaplaması ve görev zamanlayıcıları hep bir bağımlılık DAG’ını topolojik sırada işler. Memoization’lı DP’nin “her düğümü bir kez çöz, sonucu sakla” mantığı, Make’in “değişmemiş hedefi yeniden derleme” mantığının ta kendisidir; ikisi de aynı gizli DFS’i koşturur.

24.9 8. Alt-Problem Tasarım Aracı: Prefix/Suffix/Substring

Girdi bir dizi ise, doğal alt problem adayları:

“if your input is a sequence, here are some good sub-problems… prefixes… suffixes… substrings.” — Demaine, 43:03

  • Önekler (prefixes): \(x[:i]\), her \(i\) için — \(\Theta(n)\) tane.
  • Sonekler (suffixes): \(x[i:]\), her \(i\) için — \(\Theta(n)\) tane.
  • Alt diziler (substrings): \(x[i:j]\)\(\Theta(n^2)\) tane.

Alt-dizilim (subsequence) KULLANMA\(2^n\) tane (üstel). Önek/sonek genelde denktir ve yeterlidir; yetmezse substring’e geç.

Şekil 24.6 bu dört adayı \(n = 6\) örnek dizide (“ABCDEF”) yan yana sıralar: önek satırı soldan büyür (A, ABC, ABCDEF), sonek sağdan büyür (F, DEF, ABCDEF) — ikisi de yeşil “\(\Theta(n)\) — 7 tane” rozetiyle; substring ortadan bir aralık seçer (CD, BCDE, …) amber “\(\Theta(n^2)\) — 28 tane”; subsequence atlamalı seçim (A_C_E, …) kırmızı üstü-çizik “\(2^n = 64\) — YASAK”. Sayılar figür içinde gerçek enumerasyondan hesaplanır (\(n+1 / n+1 / (n+1)(n+2)/2 / 2^n\)).

Şekil 24.6: Alt-problem tasarım aracı: dizi girdide hangi alt problemi seçeyim? (Demaine L15 §8, 43:03; n=6 ‘ABCDEF’). 4 satır: PREFIX (önekler x[:i]) soldan büyüyen A / ABC / ABCDEF + yeşil ‘Θ(n) — 7 tane’; SUFFIX (sonekler x[i:]) sağdan büyüyen F / DEF / ABCDEF + yeşil ‘Θ(n) — 7 tane’; SUBSTRING (alt diziler x[i:j]) ortadan CD / BCDE / D + amber ‘Θ(n²) — 28 tane’; SUBSEQUENCE (alt dizilim, atlamalı) A C E / B D F / A F üstü-çizik kırmızı + ‘2ⁿ = 64 — YASAK’. ALT NOT: dizi girdide önce prefix/suffix dene → yetmezse substring → subsequence ASLA (Demaine 43:03); n+1 / n+1 / (n+1)(n+2)/2 polinom çözülebilir, 2ⁿ üstel DP tablosu patlar. Veri figür içinde GERÇEK enumerasyondan (assert): prefix = n+1 = 7; suffix = n+1 = 7; substring = (n+1)(n+2)/2 = 28; subsequence = 2ⁿ = 64; sıralama prefix=suffix < substring < subsequence.

24.10 9. Bowling Problemi: SRTBOT Uygulaması

Problem. \(n\) pin, pin \(i\) değeri \(v_i\). Bir pin vurursan \(v_i\) puan; bitişik iki pini (\(i, i+1\)) birlikte vurursan \(v_i \cdot v_{i+1}\) puan. Skoru maksimize et (pinleri atlamak serbest).

Çalışılan Örnek — suffix DP. S: $B(i) = $ pin \(i \ldots n-1\) ile elde edilebilecek maksimum skor. O: \(B(0)\). R: ilk pin \(i\)’ye üç şey yapabilirim — atla, tek vur, ya da \(i+1\) ile çiftle:

\[B(i) = \max\bigl(B(i+1),\; B(i+1) + v_i,\; B(i+2) + v_i \cdot v_{i+1}\bigr)\]

T: \(i\) azalan (for \(i = n-1 \ldots 0\)). B: \(B(n) = 0\). Time: \(n\) alt problem $, O(1) = $ \(O(n)\).

24.11 10. Bottom-Up DP ve Yerel Kaba Kuvvet

SRTBOT’u doğrudan bir for-döngüsü algoritmasına çevirebiliriz (bottom-up): taban durumu yaz, topolojik sırada döngü kur, recurrence’ı uygula, sonunda orijinali döndür.

def bowling(v, n):
    B = [0] * (n + 1)               # B[n] = 0 taban durum
    for i in range(n - 1, -1, -1):  # topolojik sira: i azalan
        B[i] = max(B[i + 1], B[i + 1] + v[i])
        if i + 1 < n:               # cift yalnizca >= 2 pin varsa
            B[i] = max(B[i], B[i + 2] + v[i] * v[i + 1])
    return B[0]                      # orijinal problem

Bu, yerel kaba kuvvettir (local brute force): pin \(i\) için tüm seçenekleri (3 tane) dene, en iyisini al. Normalde \(3 \times 3 \times \ldots\) üstel olurdu; ama alt problemleri yeniden kullandığımızdan doğrusal.

“dp is essentially an idea of using local brute force.” — Demaine, 54:47

DP sezgisi: “çözümün hangi özelliğini bilsem işim biterdi?” Bu özelliğin seçenek sayısı polinomsa, polinom bir DP elde edersin. (Sonek \(\to\) ilk öğeyi düşün; önek \(\to\) son öğe; substring \(\to\) ortadaki öğe.)

“identify some feature of the solution that if we knew that feature we would be done.” — Demaine, 56:00

Şekil 24.7 bu dersin ikinci imza figürüdür ve bowling’i uçtan uca çözer: üstte pin dizisi \(v = [1, 9, 9, 2, -5, -5]\) ve optimal plan izi (tek vuruşlar halka, çift kemerler amber yay; “\((-5) \cdot (-5) \to\) POZİTİFLEŞİR” rozeti) — toplam \(1 + 81 + 2 + 25 = 109\); altta suffix-DP tablosu \(B\) doldurma sırası \(i = 6 \to 0\) (topolojik sıra, sağdan sola amber ok), her hücrede \(B[i]\) değeri ve kazanan seçenek. Motor bunu üç bağımsız yoldan teyit eder: \(\mathrm{bowling\_bottom\_up}(v) = [109, 108, 43, 27, 25, 0, 0]\), \(\mathrm{bowling\_brute\_pairs}(v) = 109\) (bitmask-çift bağımsız tanık), \(\mathrm{bowling\_memo\_counted}(v) = (109, 7)\) (\(n+1\) alt problem).

Şekil 24.7: Bowling suffix-DP — pin dizisi + plan izi + B tablosu (Demaine L15 §9-10 İMZA): B[n]=0 taban; i azalan topolojik sıra; her pin 3 seçenek (atla / tek vuruş +v_i / çift kemer v_i·v_{i+1}); negatif çift çarpımla pozitifleşir. ÜST PANEL: pin dizisi v=[1,9,9,2,−5,−5] (negatifler slate dolgu); optimal plan izi — tek vuruşlar halka (✓ +1, +2), çift kemerler amber yay (9·9=81, (−5)·(−5)=25) + ‘(−5)·(−5) → POZİTİFLEŞİR’ rozeti; sağ toplam kutusu 1 + 81 + 2 + 25 = 109. ALT PANEL: suffix-DP tablosu B 7 hücre i=0..6, doldurma yönü i=6→0 (topolojik sıra, sağdan sola amber ok); her hücre B[i] değeri + kazanan seçenek (← çift/tek/atla) + formül; B[0]=109 CEVAP amber vurgu, B[6]=0 taban (boş sonek). ALT NOT: her pin 3 seçenek, alt problemler YENİDEN KULLANILIR → 3ⁿ kaba kuvvet yerine O(n); yerel kaba kuvvet sabit ≤3 seçenek/pin (Demaine 54:47). Veri MOTORDAN (assert): v=[1,9,9,2,−5,−5]; bowling_bottom_up(v)=[109,108,43,27,25,0,0]; plan=[(0,tek,1),(1,çift,81),(3,tek,2),(4,çift,25)]; bowling_brute_pairs(v)=109 (bağımsız); bowling_memo_counted(v)=(109,7); plan toplam=B[0]=109.
İpucuBuilder Notu — DP → Viterbi / DTW / diff

“İlk öğeye ne yapabilirim?” + memoization şablonu, bowling’in çok ötesine geçer. Aynı yerel-kaba-kuvvet refleksi gerçek ML ve sistem araçlarının çekirdeğidir: Viterbi (gizli Markov modellerinde en olası durum dizisi — her adımda “bu gözlem hangi durumdan geldi?”), DTW (dynamic time warping — ses/zaman serisi hizalama), diff ve git merge (en uzun ortak alt-dizilim üzerinden satır eşleme), sequence alignment (Needleman-Wunsch, Smith-Waterman — DNA/protein). Hepsi bir dizide ilk/son öğenin sabit sayıda seçeneğini deneyip alt problem çözümlerini yeniden kullanır. Bu dersin bir sonraki adımı (Ders 24, LCS/LIS) tam da bu köprünün ilk taşıdır.

24.12 Bu Dersin Özeti

  1. DP = özyineleme + memoization; en güçlü tasarım paradigması.
  2. SRTBOT: Subproblems / Relations / Topological / Base / Original / Time.
  3. Memoization: alt problem çözümünü sakla \(\to\) her biri bir kez \(\to\) Fibonacci \(O(n)\).
  4. Süre formülü: \(\sum\) alt problemler \(\times\) özyineleme-dışı iş.
  5. DAG shortest path = DP; içinde DFS + topolojik sıra gizli.
  6. Alt-problem aracı: prefix/suffix \(\Theta(n)\), substring \(\Theta(n^2)\); subsequence (\(2^n\)) YASAK.
  7. Bowling: suffix DP, \(B(i)\) = max(atla, tek, çift) → \(O(n)\); yerel kaba kuvvet.
ÖnemliTek Bir Cümle

DP, “ilk öğeye ne yapabilirim?” sorusunu polinom sayıda alt problem üzerinde memoization’la çözer: SRTBOT ile alt problemleri tanımla, recurrence ile ilişkilendir, topolojik sırada sakla — yerel kaba kuvvet üstel aramayı polinom zamana indirir.

24.13 Kontrol Soruları

Cevap: Saf özyinelemede \(f(n)\), \(f(n-1)\) ve \(f(n-2)\)’yi çağırır; bunlar da kendi alt çağrılarını yapar — özyineleme ağacında \(f(n-3), f(n-2)\) gibi alt problemler defalarca yeniden hesaplanır. \(T(n) = T(n-1) + T(n-2) + 1 \approx \varphi^n\) (üstel). Memoization, her alt problemi çözünce bir memo tablosuna yazar; aynı alt problem ikinci kez istendiğinde yeniden hesaplanmaz, tablodan döner. Böylece yalnız \(n\) farklı alt problem, her biri \(O(1)\) \(\to\) \(O(n)\). Tek değişiklik “hesaplananı sakla/yeniden kullan”dır.

Cevap: Subproblems (alt problemleri tanımla), Relations (recurrence ile ilişkilendir), Topological order (DAG + çözüm sırası), Base case (taban durum), Original problem (çözmek istediğin), Time (\(\sum\) alt problem \(\times\) özyineleme-dışı iş). En zoru genelde S (ve onunla bağlı R): doğru alt problemleri bulmak. Demaine’in sezgisi: “çözümün hangi özelliğini bilsem işim biterdi?” — o özelliğin polinom seçeneği varsa, alt problemler doğru kurulur.

Cevap: \(n\) öğeli bir dizinin \(2^n\) alt-dizilimi vardır (her öğe ya alınır ya alınmaz) — üstel. Alt problemleri alt-dizilimlerle parametreleştirirsek, alt problem sayısı garantili üstel olur \(\to\) DP’nin tüm avantajı kaybolur. Oysa önek (\(\Theta(n)\)), sonek (\(\Theta(n)\)) ve alt dizi/substring (\(\Theta(n^2)\)) polinom sayıdadır. DP’nin işe yaraması için alt problem sayısı polinom olmalı; bu yüzden dizilerde prefix/suffix/substring tercih edilir, subsequence asla.

Cevap: İlk pin \(i\)’ye yapılabilecek tüm şeyler: (1) atla \(\to\) kalan sonek \(B(i+1)\); (2) tek vur \(\to\) \(B(i+1) + v_i\); (3) \(i+1\) ile çiftle \(\to\) \(B(i+2) + v_i \cdot v_{i+1}\). Bu üç seçenek tüm olasılıkları kapsar; max alarak en iyisini seçeriz. Geri kalan her durumda kalan bir sonektir (daha küçük alt problem) \(\to\) özyineleme geçerli. “Yerel kaba kuvvet”: her adımda yalnız ilk öğenin seçeneklerini (sabit sayıda) dene; alt problemler yeniden kullanıldığından, normalde \(3^n\) olacak arama \(O(n)\)’e iner.

24.14 Egzersizler

Egzersiz 1. Fibonacci’yi hem memoizasyonlu (top-down) hem bottom-up Python’da yaz; her ikisinin de \(O(n)\) toplama yaptığını doğrula.

Egzersiz 2. Bowling’i verilen bir örnek dizide (örn. \([1, 9, 9, 2, -5, -5]\)) elle \(B(i)\) tablosuyla çöz; optimal stratejiyi göster.

Egzersiz 3. DAG en kısa yolu SRTBOT olarak yaz (S/R/T/B/O/T); recurrence’ın gelen kenarlar üzerinden min olduğunu açıkla.

Egzersiz 4. Bir dizi problemi için prefix, suffix ve substring alt problem sayılarını (\(\Theta(n), \Theta(n), \Theta(n^2)\)) ve subsequence’in neden \(2^n\) olduğunu yaz.

Egzersiz 5. Bowling kuralını değiştir (örn. üç bitişik pin de vurulabilsin); recurrence’a yeni seçeneği ekle ve sürenin hâlâ \(O(n)\) kaldığını göster.

24.15 Sonraki Ders İçin Hazırlık

UyarıSonraki: Ders 24 (L16) — Dinamik Programlama 2 (Erik Demaine)

Ders 24 (L16): Dinamik Programlama 2 (string alt problemleri, Erik Demaine). DP’yi dizi/string problemlerine uyguluyoruz: en uzun ortak alt-dizilim (LCS), en uzun artan alt-dizilim (LIS) gibi klasikler, ve oyun ağaçları. SRTBOT aynı kalır; alt problemler önek/sonek/substring olur, recurrence “son karakteri eşleştir/eşleştirme” gibi yerel kaba kuvvetle kurulur. DP ünitesi burada devam eder (Ders 24-27 = L16-L18; araya Ders 25 = PS8 girer); blok, Quiz 3 kapsamının (DP) belkemiğidir ve Ders 30 = PS10/Quiz 3 Gözden Geçirme ile özetlenir.

Ders 24 Öncesi Yapılacak:

  • Bu dersin egzersizlerini, özellikle Egzersiz 1 (Fibonacci iki yöntem) ve 2 (bowling) çöz.
  • SRTBOT’un altı adımını ezberden say; her birine bowling’den örnek ver.
  • Ana cümleyi tekrar oku: “Çözümün hangi özelliğini bilsem işim biterdi? — polinom seçenek → polinom DP.”

24.16 Anahtar Kavramlar (Cheat Sheet)

Kavram Tanım Sayfada
Dinamik programlama Özyineleme + memoization; polinom tasarım Böl. 1
SRTBOT Subproblems/Relations/Topological/Base/Original/Time Böl. 2
Memoization Alt problem çözümünü sakla/yeniden kullan Böl. 5
Süre formülü \(\sum\) alt problem \(\times\) özyineleme-dışı iş Böl. 6
Alt-problem aracı prefix/suffix \(\Theta(n)\), substring \(\Theta(n^2)\); subsequence \(2^n\) YASAK Böl. 8
Bowling recurrence \(B(i)\) = max(atla, tek \(v_i\), çift \(v_i \cdot v_{i+1}\)) Böl. 9
Bottom-up DP Base \(\to\) topolojik for \(\to\) relation \(\to\) original Böl. 10
Yerel kaba kuvvet İlk öğenin seçeneklerini dene + max/min; reuse Böl. 10

24.17 Builder ve OMSCS Bağlantıları

İpucu6 köprü

Bu ders, hazır algoritma uygulamaktan kendi algoritmanı tasarlamaya geçişin kapısıdır; SRTBOT disiplini ve memoization sezgisi, ML ve sistem mühendisliğindeki çok sayıda araca doğrudan bağlanır — köprülerin özeti:

  1. DP → dizi hizalama (DNA/diff), Viterbi/DTW (ses, ML), metin akıllı-kırpma, knapsack, en kısa yol.
  2. SRTBOT → algoritma tasarım disiplini; her DP’yi altı adımla yazma alışkanlığı (OMSCS CS 6515 — her DP probleminde “önce S/R/T/B/O/T çıkar” refleksi).
  3. Memoization → caching/önbellekleme; saf hesaplamayı tekrar etmeden sakla.
  4. Yerel kaba kuvvet → “her adımda sabit seçenek + reuse” → üstel aramayı polinoma indirme.
  5. Alt-problem grafı = DAG → bağımlılık çözümü, build sistemi; DP içinde gizli DFS.
  6. Optimal alt yapı → en kısa yol + DP köprüsü; alt-problem çözümlerini birleştirme.

ÖnemliTek bir şey alıp gideceksen

Dinamik programlama = özyineleme + memoization. SRTBOT’la alt problemleri tanımla, bir recurrence ile ilişkilendir, topolojik sırada çöz, çözümleri bir memo tablosunda sakla. Sihir “yerel kaba kuvvettedir”: her adımda yalnız ilk öğenin sabit sayıda seçeneğini dener, en iyisini alırsın — alt problemleri yeniden kullandığından, üstel görünen arama polinom zamana iner. Tek soru: “çözümün hangi özelliğini bilsem işim biterdi?” Bu, kendi algoritmanı tasarlama bölümünün açılışıdır; sırada DP’yi string ve oyunlara taşıyan Ders 24 var.