Dynamisches Programmieren SS10
Inhaltsverzeichnis |
Autoren:
Katja Lemberg (sikalemb@hs-zigr.de)
Marlene Knoche (simaknoc@hs-zigr.de)
Einführung
Das Ziel der dynamischen Programmierung ist die Suche nach effizienten Algorithmen für Optimierungs- und Entscheidungsprobleme. Dabei ist der Begriff „Dynamisches Programmieren“ eher unpassend, da sich der Begriff „Programmieren“ in diesem Zusammenhang auf die tabellarische Methode und nicht auf das Schreiben von Code bezieht. Besser wäre der Begriff „Dynamisches Optimieren“, da eigentlich die Optimierung des Programmablaufes angestrebt wird. Die Grundlage für die „Dynamische Programmierung“ war „Teile und Herrsche“.
Dynamisches Programmieren
Bottom up Ansatz
Dieser Ansatz besagt, dass sich die optimale Lösung eines Problems aus optimalen Lösungen von Teilproblemen des Gesamtproblems zusammen setzt, was man auch als Optimalitätsbedingung bezeichnet. Dabei werden alle Teillösungen „von unten her“ betrachtet und die Lösungen werden in eine Tabelle eingetragen. Die Berechnung jeweils aufeinander folgender Tabelleneinträge nutzt bereits vorhandene Einträge zur Berechnung. Die Entwicklung eines dynamischen Programmes kann man in vier Schritten darstellen.
- Charakterisieren der Struktur einer optimalen Lösung
- Wert einer optimalen Lösung rekursiv definieren
- Wert einer optimalen Lösung durch Bottom-Up-Ansatz berechnen
- zugehörige optimale Lösung aus schon berechneten Daten konstruieren
Auch bei der „Dynamischen Programmierung“ gibt es gewisse Schwierigkeiten. Zum einen ist die Zerlegung eines großen Problems in kleinere unabhängige und überlappungsfreie Teilprobleme meist eine Illusion und die Teilprobleme sind meist nicht ausgewogen, das heißt, dass ein besonders aufwändig zu lösendes Teilproblem den Erfolg der Methode zunichte machen kann. Die Optimalitätsbedingung muss nicht in jedem Fall erfüllt sein. Das bedeutet, dass nicht zwingend ein Zusammenfügen aller optimalen Teillösungen eine optimale Gesamtlösung ergibt. Außerdem kann die Anzahl der Teilprobleme, die gelöst werden müssten, unvertretbar hoch sein, somit wäre der Aufwand für die Anwendung der „Dynamischen Programmierung“ höher als der Aufwand für die Lösung des Gesamtproblems.
Der Berechnungsprozess wird traditionell iterativ organisiert. Es werden also die Zeilen einer entsprechenden Tabelle nacheinander ausgefüllt. Auf den ersten Blick ist diese Berechnungsmethode aus Aufwandsgründen der rekursiven vorzuziehen, da für jedes Feld der Tabelle oder Matrix mit der Form (z,s) genau ein Resultat ermittelt werden muss. Es kann bei Lösungen, die rekursiv definiert und durch rekursive Prozeduren berechnet wurden, zu Mehrfachberechnungen von Teilausdrücken kommen.
Bei „Dynamischer Programmierung“ wird der Aufwand für wiederholte und somit unnötige Berechnungen vermieden, was jedoch nicht einfach so passiert. Um diese Vermeidung herbeizuführen berechnet man alle Teillösungen, also auch diejenigen, die mit der optimalen Gesamtlösung am Ende nichts zu tun, somit keinen Einfluss auf diese haben. Wesentlich problematischer als diese zusätzlichen Berechnungen ist es den rekursiven Top-Down-Ansatz in einen Bottom-Up-Algorithmus umzuwandeln. Ein Bottom-Up-Algorithmus durchläuft eine zweidimensionale Tabelle im Allgemeinen mittels zwei verschachtelter Schleifen. Deswegen kann die Umwandlung schwierig sein, da sie mentalen Zusatzaufwand erfordert und somit fehleranfällig ist. Dazu kommt das eine Lösung durch eine rekursive Beschreibung fixiert ist und sich der „Geist dagegen sträubt“ die Transformation durchzuführen.
Der Ausweg aus dieser Zwickmühle heißt „Memoizing“. Die Idee besteht darin rekursiv erzeugte Teilprobleme einmal zu berechnen und die Lösungen danach in eine Tabelle einzutragen. So kann und wird vor der Ausführung jeder Berechnung geprüft, ob der Wert schon in der Tabelle vorhanden ist. Sollte dem so sein, wird der Wert einfach übernommen, anderenfalls wird der Wert ganz einfach berechnet und danach in die Tabelle eingetragen.
Vergleich zu "Teile und Herrsche"
0/1 Rucksackproblem
Die Optimalitätsbedingung ist erfüllt, da der Gegenstand i in den bis dahin optimal gepackten Rucksack, natürlich bisher ohne i, gepackt wird. So erhält man auf jeden Fall einen optimal gepackten Rucksack, der den Gegenstand i enthält. Dadurch werden alle Gegenstände, wenn sie noch hineinpassen, in einen optimal gepackten Rucksack eingepackt.
Aufwandsbetrachtung
Memoizing
Rundreiseproblem
Quellen
Literatur
- [1] Christian Wagenknecht
- Algorithmen und Komplexität.- Fachbuchverlag Leipzig, 2003. - ISBN 3-446-22314-2