Programowanie dynamiczne
Z Wikipedii
Programowanie dynamiczne jest techniką, lub strategią, projektowania algorytmów stosowaną przeważnie do rozwiązywania zagadnień optymalizacyjnych, dla których nie istnieją algorytmy zachłanne. Wynalazcą techniki jest amerykański matematyk Richard Bellman, uhonorowany za to odkrycie medalem IEEE (ang. medal of honour) w 1979 roku.
Programowanie dynamiczne opiera się na podziale rozwiązywanego problemu na podproblemy względem kilku parametrów. W odróżnieniu od techniki dziel i rządź podproblemy w programowaniu dynamicznym nie są na ogół rozłączne, ale musi je cechować własność optymalnej podstruktury. Zagadnienia odpowiednie dla programowania dynamicznego cechuje również to, że zastosowanie do nich metody siłowej (and. brute force) prowadzi do ponadwielomianowej liczby rozwiązań podproblemów, podczas gdy sama liczba różnych podproblemów jest wielomianowa.
Zazwyczaj jednym z parametrów definiujących podproblemy jest ilość elementów znajdujących się w rozpatrywanym problemie, drugim jest pewna wartość liczbowa, zmieniająca się w zakresie od 0 do największej stałej występującej w problemie. Możliwe są jednak bardziej skomplikowane dobory parametrów, a także większa ich liczba. Ponieważ jednak uzyskiwany algorytm zazwyczaj wymaga pamięci (i czasu) proporcjonalnego do iloczynu maksymalnych wartości wszystkich parametrów, stosowanie większej ilości parametrów niż 3-4 rzadko bywa praktyczne.
Klucz do zaprojektowania algorytmu tą techniką leży w znalezieniu równania rekurencyjnego opisującego optymalną wartość funkcji celu dla danego problemu jako funkcji optymalnych wartości funkcji celu dla podproblemów o mniejszych rozmiarach. Programowanie dynamiczne znajduje optymalną wartość funkcji celu dla całego zagadnienia rozwiązując podproblemy od najmniejszego do największego i zapisując optymalne wartości w tablicy. Pozwala to zastąpić wywołania rekurencyjne odwołaniami do odpowiednich komórek wspomnianej tablicy i gwarantuje, że każdy podproblem jest rozwiązywany tylko raz. Rozwiązanie ostatniego z rozpatrywanych podproblemów jest na ogół wartością rozwiązania zadanego zagadnienia.
Niejednokrotnie stosowanie techniki programowania dynamicznego daje w rezultacie algorytm pseudowielomianowy. Programowanie dynamiczne jest jedną z bardziej skutecznych technik rozwiązywania problemów NP-trudnych. Niejednokrotnie może być z sukcesem stosowana do względnie dużych przypadków problemów wejściowych, o ile stałe występujące w problemie są stosunkowo nieduże. Na przykład, w przypadku dyskretnego zagadnienia plecakowego jako parametry dynamiczne w metodzie programowania dynamicznego należy przyjąć rozmiar kolejno rozpatrywanych podzbiorów elementów oraz rozmiar plecaka, zmieniający się od 0 do wartości B danej w problemie.
Programowanie dynamiczne może być również wykorzystywane jako alternatywna metoda rozwiązywania problemów zaliczanych do klasy P, o ile złożoność algorytmu wielomianowego nie jest satysfakcjonująca, a w praktyce, nawet dla dużych instancji problemu, wartości liczbowe występujące w problemie są niewielkie.
[edytuj] Przykłady zastosowań
Algorytmy programowania dynamicznego są stosowane między innymi w informatyce, matematyce, bioinformatyce, ekonomii, i logistyce. Oto niektóre przykłady zastosowań programowania dynamicznego:
- Algorytm CYK
- Algorytm Viterbiego
- algorytmy znajdujące najdłuższy wspólny podciąg
- algorytmy rozwiązujące zagadnienie plecakowe
- Parser Earleya
- znajdowanie optymalnej kolejności obliczania długich iloczynów macierzy
- Algorytm Floyda-Warshalla
- obliczanie odległości Levenshteina
- Algorytm Needlemana-Wunscha (dopasowywanie ciągów)
- Wybór instrukcji niskiego poziomu w kompilatorach (ang. instruction selection)
[edytuj] Bibliografia
- Richard Bellman. On the Theory of Dynamic Programming. Proceeding of the National Academy of Sciences (USA). 1952.
- Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, 2001. Introduction to Algorithms, 2nd ed. MIT Press & McGraw-Hill. ISBN 0262032937. Zwłaszcza rozdział 15: 323–69. (klasyczny wykład podręcznikowy na poziomie podstawowym)
- Juraj Hromkovič. Algorithmics for Hard Problems. Introduction to Combinatorial Optimization, Randomization, Approximation, and Heuristics. 2nd ed. Springer Verlag 2004. ISBN 3-540-44134-4. Rozdział 3.2: 152–7 (zwięzła prezentacja teoretyczna)