Dynamické programování prof. Ing. Pavel Tvrdík CSc. Katedra počítačových systémů Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010 Efektivní algoritmy (BI-EFA) ZS 2010/11, Přednáška 11 Evropský sociální fond. Praha & EU: Investujeme do vaší budoucnosti prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 1 / 19
Dynamické programování vs. Rozděl-a-Panuj Dynamické programování vs. Rozděl-a-Panuj Metody Rozděl-a-Panuj je vhodné pro řešení úloh, které lze rozdělit na nezávislé podúlohy: Rozděl úlohu na nezávislé podúlohy. Rekurzivně vyřeš podúlohy. Zkombinuj řešení podúloh do celkového výsledku úlohy. Dynamické programování (DP) je vhodné pro řešení úloh, ve kterých se podúlohy překrývají, t.j., řeší se stejné podpodúlohy. Pro takové úlohy nejsou metody Rozděl-a-Panuj vhodné, protože sdílené podúlohy se opakovaně (redundantně, zbytečně) řeší znovu a znovu, což může vést na řádově vyšší výpočetní složitost. Metody DP si výsledky dříve vyřešených podúloh zapamatují a při jejich znovuobjevení je využijí. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 2 / 19
DP pro řešení optimalizačních úloh Dynamické programování pro řešení optimalizačních úloh Definice 1 Optimalizační úloha: Z více možných řešení hledáme řešení s optimální cenou (maximální či minimální hodnotou,... ). Vytvoření DP algoritmu pro řešení dané optimalizační úlohy se skládá ze 4 kroků: 1 Charakterizuj strukturu optimálního řešení. 2 Rekurzivně definuj cenu optimálního řešení. 3 Vypočítej efektivně cenu optimálního řešení: 1 metodou shora dolů. 2 metodou zdola nahoru. 4 (Zrekonstruuj strukturu optimálního řešení z vypočtených hodnot cen.) Poslední bod odpadá, pokud stačí pouze cena optimálního řešení. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 3 / 19
Řetězové násobení matic Řetězové násobení matic Definice 2 Je dána posloupnost přirozených čísel d 0, d 1, d 2,..., d n a posloupnost matic A 1, A 2,..., A n, kde matice A i má rozměry d i 1 d i. Řetězové násobení matic (ŘNM) je úkol vypočítat součin A = A 1 A 2 A n tak, aby výpočetní aritmetická složitost byla minimální. Jinými slovy, úkolem je najít takové uzávorkování pořadí násobení matic, které vede na násobení s nejmenším počtem aritmetických operací. Cena řešení = výpočetní složitost násobení matic. Budeme předpokládat klasické násobení matic řádky krát sloupce. Výpočetní složitost součinu A i A i+1 budeme aproximovat výrazem d i 1 d i d i+1 (zanedbáváme konstanty a nižší členy). prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 4 / 19
Řetězové násobení matic Vlastnosti ŘNM Vlastnosti ŘNM Poznámky: Násobení matic je asociativní, proto jakékoli uzávorkování dá správný výsledek A. Různé pořadí násobení má dramatický vliv na výpočetní složitost výpočtu. Příklad 3 Uvažujme n = 3 a (d 0, d 1, d 2, d 3 ) = (5, 50, 10, 30). Pak uzávorkování (A 1 A 2 )A 3 má výpočetní složitost 5 50 10 + 5 10 30 = 2500 + 1500 = 4000, kdežto uzávorkování A 1 (A 2 A 3 ) má výpočetní složitost 50 10 30 + 5 50 30 = 15000 + 7500 = 22500!!! Přitom problém ŘNM má kombinatorickou složitost, přesněji exponenciální (viz další slajd), takže řešení hrubou silou, zkoušením všech možností, není myslitelné. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 5 / 19
Řetězové násobení matic Kombinatorická složitost problému ŘNM Počet různých uzávorkování v ŘNM Označme Z(n) počet všech různých způsobů, jak uzávorkovat součin A 1 A 2 A n. Posloupnost matic můžeme rozdělit na dvě části hranicí mezi A k a A k+1 pro libovolné k = 1, 2,..., n 1 a pak uzávorkovat rekurzívně a nezávisle na sobě obě vzniklé podposloupnosti A 1,..., A k a A k+1,..., A n. Proto platí rekurentní vztah Z(n) = { 1 if n = 1, n 1 k=1 Z(k)Z(n k) if n 2. Řešením jsou tzv. Catalanova čísla: Z(n) = C(n 1), viz http://mathworld.wolfram.com/catalannumbers.html, o kterých se ví, že C(n) = 1 n + 1 ( ) ( ) 2n 4 n = Ω n n. n prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 6 / 19
První krok algoritmu DP Charakterizace struktury optimálního řešení 1. krok DP pro ŘNM: Charakterizování optimálního závorkování Označme A i...j matici vzniklou vynásobením A i A i+1... A j, i j. Pro každé optimální závorkování existuje hranice k, 1 k < n, taková, že rekurzivně se zkonstruuje závorkování pro výpočet A 1...k, pak závorkování pro výpočet A k+1...n, a výslednou A = A 1...n získáme vynásobením A 1...k A k+1...n. Výpočetní složitost ŘNM je tedy složitost výpočtu A 1...k + složitost výpočtu A k+1...n + složitost násobení 2 matic A 1...k A k+1...n. Lemma 4 Nechť k je hranice optimálního závorkování (s minimální výpočetní složitostí). Pak závorkování pro výpočet A 1...k i závorkování pro výpočet A k+1...n musejí být optimální. Důkaz. Důkaz sporem. Pokud by např. první nebylo, existovalo by závorkování pro A 1...k s nižší cenou a tím by i výsledná cena byla nižší, což je spor, protože dané závorkování pro A 1...n je optimální. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 7 / 19
Druhý krok algoritmu DP Rekurzivní definice ceny optimálního řešení 2. krok DP pro ŘNM: Rekurzivní definice ceny optimálního závorkování Nechť m[i, j] je minimální cena závorkování (=nejmenší výpočetní složitost násobení) A i A i+1... A j, i j. Pak platí: { 0 if i = j, m[i, j] = min i k<j {m[i, k] + m[k + 1, j] + d i 1 d k d j } if i < j. (1) Označme h[i, j] právě takové k, které v (1) dává minimum, čili m[i, j] = m[i, h[i, j]] + m[h[i, j] + 1, j] + d i 1 d h[i,j] d j. Pak cena optimálního závorkování je m[1, n] = m[1, h[1, n]] + m[h[1, n] + 1, n] + d 0 d h[1,n] d n. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 8 / 19
Třetí krok algoritmu DP Efektivní výpočet ceny optimálního řešení 3. krok DP pro ŘNM: Standardní rekurzivní algoritmus??? Přímý rekurzivní algoritmus RecRNM(d, 1, n) realizující výpočet m[1, n] podle (1) nelze použít, protože má exponenciální složitost!!! procedure RecRNM(d, i, j) // d je posloupnost d 0,..., d n { (1) if (i = j) then return 0; (2) m[i, j] + ; (3) for (k i to j 1) (4) do {q RecRNM(d, i, k) + RecRNM(d, k + 1, j) (5) +d[i 1] d[k] d[j]; (6) if (q < m[i, j]) then { m[i, j] q; h[i, j] k}}; (7) return m[i, j]; } prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 9 / 19
Třetí krok algoritmu DP Efektivní výpočet ceny optimálního řešení Strom rekurzivních volání (SRV) RecRNM Důvod exponenciální složitosti: Celkový počet hodnot m[, ], které je třeba vypočítat pro zjištění hodnoty m[1, n], je počet všech dvojic i, j takových, že 1 i j n, což je pouze ( ) ( n 2 + n = n+1 ). 2 = n 2 2. Dochází však masivně k opakovanému výpočtu stejných hodnot. Lemma 5 Časová složitost t(n) běhu RecRNM(d, 1, n) je Ω(2 n 1 ). prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 10 / 19
Třetí krok algoritmu DP Nerekurzivní záplavová metoda zdola nahoru 3. krok DP pro ŘNM: Nerekurzivní záplavová metoda zdola nahoru Předpoklady: Vstupem je pole d[0,..., n] rozměrů matic. Výstupem jsou 2 pole: m[1,..., n, 1,..., n], kam se ukládají ceny opt. závorkování pro výpočet A i...j, h[1... n 1, 2... n], kam se ukládají příslušné hodnoty hranic optimálního závorkování. Definovány pouze hodnoty h[i, j] pro i < j. Princip: Systematické zaplňování tabulky zdola nahoru pro všechny dvojice i, j, kde 1 i j n (čili pro ( ) n+1 2 hodnot). prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 11 / 19
Třetí krok algoritmu DP Nerekurzivní záplavová metoda zdola nahoru Příklad běhu BottomUpRNM(6, d, m, h) m[1..6,1..6] h[1..5,2..6] 6 1 6 1 5 2 5 2 j 4 3 i j 4 3 i 3 4 3 4 2 5 2 5 1 15750 2625 750 1000 5000 6 1 2 3 4 5 0 0 0 0 0 0 1 m[1..6,1..6] 6 1 5 2 j 4 3 i 3 4 2 7875 4375 2500 3500 5 15750 2625 750 1000 5000 0 0 0 0 0 0 h[1..5,2..6] 6 1 5 2 j 4 3 i 3 4 2 1 3 3 5 5 6 1 2 3 4 5 prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 12 / 19
Třetí krok algoritmu DP Nerekurzivní záplavová metoda zdola nahoru 3. krok DP pro ŘNM: Rekurzivní algoritmus shora dolů s tabelací Princip tabelace (anglické označení je memoization): Algoritmus také vytváří tabulku s hodnotami řešení podúloh. Každá položka tabulky je inicializována speciální hodnotou Neurčeno. Řídící struktura pro zaplňování však není záplavové plnění zdola nahoru jako ve variantě 1, ale pořadí vyvolávané rekurzivním algoritmem. První rekurzivně vyvolané řešení dané podúlohy provede výpočet a výsledek uloží do příslušného místa v tabulce. Následné opakované volání řešení téže podúlohy pouze přečte tuto hodnotu z tabulky. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 13 / 19
Třetí krok algoritmu DP Nerekurzivní záplavová metoda zdola nahoru procedure MemRecRNM(d, n) { (1) for (i 1 to n) (2) for (j i to n) do m[i, j] Neurceno. (3) return LookUpRNM(d, 1, n)} procedure LookUpRNM(d, i, j) { (1) if (m[i, j] Neurceno) (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 LookUpRNM(d, i, k) (7) +LookUpRNM(d, k + 1, j) + d[i 1] d[k] d[j]; (8) if (q < m[i, j]) then {m[i, j] q; h[i, j] k}}; (9) return m[i, j]} prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 14 / 19
Třetí krok algoritmu DP Nerekurzivní záplavová metoda zdola nahoru SRV MemRecRNM 1...4 1...1 2...4 1...2 3...4 1...3 4...4 2...2 3...4 2...3 4...4 1...1 2...2 1...1 2...3 1...2 3...3 3...34...4 2...23...3 Zakroužkované uzly stromu rekurzivních volání se nepočítají, ale pouze načtou z tabulky. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 15 / 19
Třetí krok algoritmu DP Nerekurzivní záplavová metoda zdola nahoru Složitost a srovnání MemRecRNM a BottomUpRNM Lemma 6 Oba algoritmy mají složitost O(n 3 ). Důkaz. Triviálně ze struktury iteračních cyklů v kódu. Srovnání obou metod: Algoritmus MemRecRNM je svojí podstatou metoda shora dolů, kdežto BottomUpRNM je metoda zdola nahoru. Pokud logika výpočtu vyžaduje, aby každá podúloha byla řešena aspoň jednou, pak BottomUpRNM je rychlejší o multiplikativní konstantu. Pravidelnost přístupu do tabulky pak uspoří čas i díky menším výpadkům skrytých pamětí a efektivnějším tokům dat mezi pamětí a procesorem. Pokud rekurzivní sestup způsobí, že některé podúlohy se vůbec nevyvolají, pak MemRecRNM může být rychlejší. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 16 / 19
Čtvrtý krok DP algoritmu Rekonstrukce struktury optimálního řešení 4. krok DP pro ŘNM: Konstrukce optimálního závorkování Tabulka h[1... n 1, 2... n] obsahuje hodnoty hranic pro optimální závorkování při ŘNM. Díky Lemmatu na Slajdu 7 je konstrukce optimálního řešení triviální rekurzivním sestupem. Na nejvyšší úrovni to je h[1, n]: Nejprve rekurzivně optimálně vypočteme A 1 A h[1,n], pak A h[1,n]+1 A n a výsledné matice nakonec vynásobíme. prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 17 / 19
Čtvrtý krok DP algoritmu Rekonstrukce struktury optimálního řešení 4. krok DP pro ŘNM: Konstrukce optimálního závorkování Úloha ŘNM je řešena voláním RNM(A, n, h, 1, n). Vstupní data: posloupnost matic A 1, A 2,..., A n a tabulka hranic h[1... n 1, 2... n]. procedure RNM(A, n, h, i, j) { (1) if (i < j) (2) then { X RNM(A, n, h, i, h[i, j]); (3) Y RNM(A, n, h, h[i, j] + 1, j); (4) return XY } (5) else return A i ; } prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 18 / 19
Příklady úloh dobře řešitelných metodami DP Příklady úloh vhodných pro řešení metodou DP 1 Floydův algoritmus hledání nejkratších cest v grafech. 2 Optimální plánování výpočetních úloh, zadaných časovými intervaly, v kterých mohou běžet. 3 Výpočet Levenshteinovy vzdálenosti mezi 2 textovými řetězci. 4 Určení způsobu, jak nejlépe daný řetězec vygenerovat pomocí dané bezkontextové gramatiky. 5 Hledání nejdelšího společného podřetězce dvou řetězců. 6 Optimální triangulace konvexního mnohoúhelníku. 7 Problém obchodního cestujícího: Obecný případ v exponenciálním, ale o(n!) čase. Spec. případy v polynomiálním čase. 8... prof. Pavel Tvrdík (FIT ČVUT) Dynamické programování BI-EFA, 2010, Předn. 11 19 / 19