2. 2
Dinamik Programlama
• Algoritma tasarım tekniği-Divide and conquer
• (Böl ve Yönet)
– Problem bağımsız alprogramlar halinde bölünür
– Altprogramlar rekürsif olarak çözülür
– Orjinal problemi çözmek için çözümler birleştirilir
5. 5
Dinamik Programlama
• Alt problemler bağımsızken uygulanabilir.
– Altproblemler daha küçük altpromlarla da paylaşılır.
Combinations:
– Böl ve Yönet yaklaşımı ortak alt problemleri tekrar tekrar
çözecektir
– Dinamik programlama her alt problemi sadece bir kez çözer ve
cevabı bir tabloda saklar
n
k
n-1
k
n-1
k-1
= +
n
1
n
n
=1 =1
6. 6
Kombinasyon Problemi
+
=
=
=
=
=
=
+ +
+ + + +
+
+ + + + +
+
+
+
+
+ + +
+ + + + + + +
+ +
+
+
+
+
+
+
+
+
+
3
3
Com b (3, 1)
2
Com b (2, 1)
1
Com b (2, 2)
Com b (3, 2)
Com b (4,2)
2
Com b (2, 1)
1
Com b (2, 2)
Com b (3, 2)
1
1
Com b (3, 3)
Com b (4, 3)
Com b (5, 3)
2
Com b (2, 1)
1
Com b (2, 2)
Com b (3, 2)
1
1
Com b (3, 3)
Com b (4, 3)
1
1
1
Com b (4, 4)
Com b (5, 4)
C om b (6,4)
n
k
n-1
k
n-1
k-1
= +
9. 9
// A Dynamic Programming based solution to compute nCr % p
#include <bits/stdc++.h>
using namespace std;
// Returns nCr % p
int nCrModp(int n, int r, int p)
{
// Optimization for the cases when r is large
if (r > n - r)
r = n - r;
// The array C is going to store last row of pascal triangle at the end. And last entry of last row is nCr
int C[r + 1];
memset(C, 0, sizeof(C));
C[0] = 1; // Top row of Pascal Triangle
// One by constructs remaining rows of Pascal Triangle from top to bottom
for (int i = 1; i <= n; i++) {
// Fill entries of current row using previous row values
for (int j = min(i, r); j > 0; j--)
// nCj = (n-1)Cj + (n-1)C(j-1);
C[j] = (C[j] + C[j - 1]) % p;
}
return C[r];
}
// Driver program
int main()
{
int n = 10, r = 2, p = 13;
cout << "Value of nCr % p is " << nCrModp(n, r, p);
return 0;
}
10. 10
Dinamik Programlama
• Optimizasyon problemleri
– En iyi çözümü elde etmek için bir dizi seçenek
yapılmalıdır
– En uygun değere sahip bir çözüm bulunur (minimum
veya maksimum)
– Optimum değere götüren birçok çözüm olabilir
– Hedef: En iyi çözümü bulmak
11. 11
Dinamik Programlama Algoritması
1. Optimal bir çözümün yapısını karakterize edin
2. Optimal bir çözümün değerini tekrar tekrar
tanımlayın
3. En uygun çözümün değerini aşağıdan yukarıya
doğru hesaplayın
4. Hesaplanan bilgilerden optimal bir çözüm
oluşturun
12. 12
Matris-ZinciriÇarpımı
Problem: verilen bir dizi A1, A2, …, An, matrisi için
aşağıdaki çarpımın hesaplanması.
A1 A2 An
• Matris uyumluluğu:
C = A B C=A1 A2 Ai Ai+1 An
colA = rowB coli = rowi+1
rowC = rowA rowC = rowA1
colC = colB colC = colAn
13. 13
MATRIX-MULTIPLY(A, B)
if columns[A] rows[B]
then error “incompatible dimensions”
else for i 1 to rows[A]
do for j 1 to columns[B]
do C[i, j] = 0
for k 1 to columns[A]
do C[i, j] C[i, j] + A[i, k] B[k,
j]
rows[A]
rows[A]
cols[B]
cols[B]
i
j
j
i
A B C
* =
k
k
rows[A] cols[A] cols[B]
multiplications
14. 14
Matris-ZinciriÇarpımı
• Matrisleri hangi sırayla çarpmalıyız? A1 A2
An
• Matrislerin çarpılacağı sırayı almak için ürünü
parantez içine alalım:
Şöyleki: A1 A2 A3 = ((A1 A2) A3)
= (A1 (A2 A3))
• Bu siparişlerden hangisini seçmeliyiz?
• Matrisleri çarpma düzenimiz, çarpımı değerlendirme
maliyeti üzerinde önemlidir.
15. 15
Örnek
A1 A2 A3
• A1: 10 x 100
• A2: 100 x 5
• A3: 5 x 50
1. ((A1 A2) A3): A1 A2 = 10 x 100 x 5 = 5,000 (10 x 5)
((A1 A2) A3) = 10 x 5 x 50 = 2,500
Total: 7,500 skaler çarpım
2. (A1 (A2 A3)): A2 A3 = 100 x 5 x 50 = 25,000 (100 x 50)
(A1 (A2 A3)) = 10 x 100 x 50 = 50,000
Total: 75,000 skaler çarpım
16. 16
Matris-ZinciriÇarpımı Problemi
• Verilen bir matris zincirinde A1, A2, …, An,
burada Ai, pi-1x pi boyutlarınadır. Skaler çarpım
sayısını minimuma indirecek şekilde A1 A2
An çarpımını tam parantezlersek.
A1 A2 Ai Ai+1 An
p0 x p1 p1 x p2 pi-1 x pi pi x pi+1 pn-1 x pn
17. 17
Olası parentezleme sayısı nedir?
Ω(4n
/n3/2
)
4 adet matrisin çarpımı için 5; 10 adet matris için 4862 farklı çarpım
düzeni vardır.
19. 19
1. Optimal parantezleme yapısı
• Gösterim:
Ai…j = Ai Ai+1 Aj, i j
• Diyelim ki Ai…j için bir optimal parentezleme ifadeyi,
Ak ve Ak+1, arasında bölsün.
• Burada i k < j
Ai…j = Ai Ai+1 Aj
= Ai Ai+1 Ak Ak+1 Aj
= Ai…k Ak+1…j
20. 20
Optimal Substructure
Ai…j = Ai…k Ak+1…j
• Ai…k kesinlikle optimal parentezleme olmalı
• Ai…k, için daha az maliyetli bir parentezleme olsaydı,
Bunu Ai…j ‘ninin parantez içindeki yerine koyabilir ve
optimumdan daha düşük maliyetli bir parantez
oluşturabilirdik. Bu da bir çelişki oluşturacaktır.
• Matris zinciri çarpımının bir örneğine en uygun çözüm,
içinde alt sorunlara en uygun çözümleri içerir
21. 21
2. Özyineli bir çözüm
• Altproblem:
Minimum parantezleme maliyeti belirlenir. Ai…j
= Ai Ai+1 Aj for 1 i j n
• m[i, j] = Ai…j ‘yi hesaplamak için gereken minimum
çarpma sayısı
• Ana problem (A1..n): m[1, n]
– i = j: Ai…i = Ai m[i, i] =
0, for i = 1, 2, …, n
22. 22
2. Özyineli bir çözüm
• Parantezleme altproblemini ele aldığımızda
Ai…j = Ai Ai+1 Aj for 1 i j n
= Ai…k Ak+1…j for i k < j
• Eğer optimal parantezleme çarpımı aşağıdaki
gibi bölse Ai Ai+1 Aj k, (i k < j) arasında
m[i, j] =
Ai…khesabı için
minimum çarpma
sayısı
Ai…kAk…jhesabı için
minimum çarpma
sayısı
Ak+1…jhesabı için
minimum çarpma
sayısı
m[i, k] m[k+1,j]
pi-1pkpj
m[i, k] + m[k+1, j] + pi-1pkpj
23. 23
2. Özyineli bir çözüm
m[i, j] = m[i, k] + m[k+1, j] + pi-1pkpj
• k değerini bilmiyoruz.
– k için j – i muhtemel değer var k: k = i, i+1, …, j-1
• Ai Ai+1 Aj ‘yi Parantezleme maliyetini minimuma
indirme problemi şu hale gelecektir.
0 if i = j
m[i, j] = min {m[i, k] + m[k+1, j] + pi-1pkpj} if i < j
ik<j
24. 24
3. Optimal maliyetleri hesaplamak
0 if i
= j
m[i, j] = min {m[i, k] + m[k+1, j] + pi-1pkpj} if i < j
ik<j
• Optimal çözümü rekürsif olarak hesaplamak üstel
zaman maliyeti alır!
• Alt problem sayısı?
– Ai…j‘yi parentezle 1 i j n
– H er i ve j seçimi 1 problem
(n2
)
1
1
2 3 n
2
3
n
j
i
25. 25
3. Optimal maliyetleri hesaplamak
0 if i = j
m[i, j] = min {m[i, k] + m[k+1, j] + pi-1pkpj} if i < j
ik<j
• Bu m[1..n, 1..n] tablosunu nasıl dolduracağız?
– m[i, j] hesabında hangi tablo girişleri kullanılacaktır?
Ai…j = Ai…k Ak+1…j
– Alt problemlerin boyutu orijinal boyuttan küçük
– Idea: m'yi artan uzunluktaki problemleri çözecek şekilde doldurun
26. 26
3. Maliyet
0 if i = j
m[i, j] = min {m[i, k] + m[k+1, j] + pi-1pkpj} if i < j
ik<j
• Length = 1: i = j, i = 1, 2, …, n
• Length = 2: j = i + 1, i = 1, 2, …, n-1
1
1
2 3 n
2
3
n
first
second
Satırlar aşağıdan yukarıya ve
soldan sağa hesaplanır.
m[1, n] :problemin
optimal çözümü
i
j
27. 27
Örnek: min {m[i, k] + m[k+1, j] + pi-1pkpj}
m[2, 2] + m[3, 5] + p1p2p5
m[2, 3] + m[4, 5] + p1p3p5
m[2, 4] + m[5, 5] + p1p4p5
1
1
2 3 6
2
3
6
i
j
4 5
4
5
m[2, 5] = min
m[i, j] değerleri sadece
önceden hesaplanmış
değerlere bağlıdır.
k = 2
k = 3
k = 4
31. 31
4. Optimal Çözümü Yapılandır
• Benzer bir matriste
k'nin optimal
değerlerini saklayalım
• s[i, j] = k;
• k, Ai..j zincirini Ak ve
Ak+1 biçimnde
çarpanlara ayırır.
k
1
1
2 3 n
2
3
n
j
32. 32
4. Optimal Çözümü Yapılandır
• s[1, n], A1..n çarpımının
tamamı ile ilişkilidir.
• Sonuç matris çarpımı
k=s[1, n]’de
bölünecektir.
A1..n = A1..s[1, n] As[1, n]+1..n
– Her bir alt çarpım için,
optimum parantezlemeye
karşılık gelen k değerini
bulunur.
1
1
2 3 n
2
3
n
j
36. 36
Memoization
• Tipik dinamik programlama yaklaşımının verimliliği ile
yukarıdan aşağıya yaklaşım
• Her bir alt problemin çözümü için bir tabloya giriş sağlama
• memoize verimsiz özyinelemeli algoritmayı hatırlamak
• Bir alt problemle ilk karşılaşıldığında çözümü hesaplanır ve
bu tabloda saklanır
• Alt probleme sürekli “çağrılar” ve sadece o anki değere
bakın
37. 37
Memoized Matrix-Chain
Alg.: MEMOIZED-MATRIX-CHAIN(p)
1. n length[p] – 1
2. for i 1 to n
3. do for j i to n
4. do m[i, j]
5. return LOOKUP-CHAIN(p, 1, n)
m tablosunu, m [i, j] değerlerinin
hesaplanıp hesaplanmadığını
gösteren büyük değerlerle
başlatın
Top-down yaklaşım
38. 38
Memoized Matrix-Chain
Alg.: LOOKUP-CHAIN(p, i, j)
1. if m[i, j] <
2. then return m[i, j]
3. if i = j
4. then m[i, j] 0
5. else for k i to j – 1
6. do q LOOKUP-CHAIN(p, i, k) +
LOOKUP-CHAIN(p, k+1, j) + pi-1pkpj
7. if q < m[i, j]
8. then m[i, j] q
9. return m[i, j]
Running time is O(n3
)
39. 39
Dynamik Progamming Memoization
• Dinamik programlamanın kaydedilmiş
algoritmalara göre avantajları
• Özyineleme için ek yük yok, tabloyu korumak
için daha az ek yük
• Zaman veya alan gereksinimlerini azaltmak için
tablo erişimine ilişkin normal desen kullanılabilir
• Kaydedilmiş algoritmaların dinamik
programlamaya göre avantajları
• Bazı alt problemlerin çözülmesine gerek yoktur
40. 41
Dinamik Programlamanın
Bileşenleri
• Optimal AltProblem
– Bir soruna optimal çözüm, alt sorunlara optimal
çözümü içerir
– Ana probleme optimal çözüm, optimal alt problem
çözümlerden aşağıdan yukarıya doğru bir şekilde
oluşturulurur.
• Çakışan Alt Problemler(overlapping subproblems)
– Eğer bir rekürsif algoritma aynı alt problemi tekrar ve
tekrar altprogram çakışması (overlapping
subproblems) problemi vardır.
41. 42
Optimal altyapının parametreleri
• Ana problem için optimal çözümde kaç alt
problem kullanılmaktadır?
– Matris çarpımı:
• Optimum bir çözümde hangi alt sorunların
kullanılacağını belirlemek için kaç seçeneğimiz
var?
– Matrix çarpımı:
İki altprıblem (Ai..k, Ak+1..j)
j - i seçenek k için (çarpımı ayırmak)
42. 43
Optimal altyapının parametreleri
• Sezgisel olarak, bir dinamik programlama
algoritmasının çalışma süresi iki faktöre bağlı:
– Toplam altproblem sayısı
– Her alt problem için kaç seçeneğe bakıyoruz?
• Matrix multiplication:
(n2
) altproblem (1 i j n)
– En fazla n-1 seçim var
(n3
) tamamı