Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
4.8 Dynamische Programmierung
Vereint Ideen verschiedener anderer Muster: aus Greedy: Wahl einer optimalen Teillösung aus Teile-und-Herrsche und Backtracking: Rekursion, Konfigurationsbaum Unterschiede: Divide-and-Conquer löst unabhängige Teilprobleme einzeln Dynamische Programmierung: optimiert abhängige Teilprobleme. Die dynamische Programmierung ist eine „bottom-up“-Realisierung der Backtracking-Strategie. Anwendungsbereich: wie Greedy, jedoch insbesondere dort, wo Greedy nur sub-optimale Lösungen liefert.
2
Prinzip der dynamischen Programmierung
Bei der dynamischen Programmierung werden kleinere Teilprobleme zuerst gelöst, um aus diesen größere Teillösungen zusammenzusetzen (bottom-up). Dabei geschieht das Problemlösen „auf Vorrat“: Man löst aber nur solche Teilpro-bleme, die bei der Lösung des großen Problems auch tatsächlich benötigt werden. Jedes Teilproblem wird nur einmal gelöst, man merkt sich das Ergebnis zur mehr-fachen Verwendung beim großen Problem. Das ergibt einen Gewinn, falls identische Teilprobleme in mehreren Lösungszweigen des Konfigurationsbaumes betrachtet werden. Rekursives Problemlösen wird häufig ersetzt durch Iteration mit Abspeichern der Teilergebnisse.
3
Beispiel 1: Traveling Salesman
Das Problem des Handelsreisenden (Traveling Salesman Problem, TSP) Gegeben: ein Graph mit n Knoten (Städten) und m Kanten (Straßen); Straßen sind mit Entfernungen versehen. Gesucht: kürzeste Route, bei der alle Städte genau einmal besucht werden und dann an den Startpunkt zurückgekehrt wird.
4
Traveling Salesman im Detail
Gegeben: n Städte in S Entfernungsmatrix M = (mi,j ) der Größe n × n mi ,j: Entfernung von Stadt i nach Stadt j Gesucht: Rundreise über alle Städte mit minimaler Länge Also eine Permutation von {1, ..., n }, so dass die Summe der Entfernungen minimal ist.
5
TSP mit dynamischer Programmierung
Betrachte g(i , S): Länge des kürzesten Weges von Stadt i über jede andere Stadt in S nach Stadt 1. Da Rundreise, kann Stadt 1 beliebig gewählt werden. Es gilt: g(i , S) = Idee: baue die Rundreisen von hinten her schrittweise auf Lösung: g(1, { 2, ..., n } ) mi, falls S = { } minj∈S(mi,j + g(j, S - { j } )) sonst
6
Traveling Salesman: Algorithmus
Berechne g bottom-up als Array: for i = 2 to n do g[i,{}] = mi,1; for k = 1 to n-2 for all S with |S| = k and 1 ∉ S do berechne g[i,{S}] nach der Formel; berechne g[1,{2,...,n }] nach der Formel;
7
Traveling Salesman: Beispiel (1)
Vier Städte, symmetrische Entfernungen: M = 1 2 3 4 9 8 12 10 4 1 2 9 2 12 8 3 4 10 Initialisierung g[2,{ }] = 4 g[3,{ }] = 9 g[4,{ }] = 8
8
Traveling Salesman: Beispiel (2)
g[2, { 3, 4 } ] = min(m2,3 + g[3, { 4 } ], m2,4 + g[4, { 3 } ]) = 21 g[3, { 2, 4 } ] = min(m3,2 + g[2, { 4 } ], m3,4 + g[4, { 2 } ]) = 16 g[4, { 2, 3 } ] = min(m4,2 + g[2, { 3 } ], m4,3 + g[3, { 2 } ]) = 23 g[1, { 2, 3, 4 } ] = min(m1,2 + g[2, { 3, 4 } ], m1,3 + g[3, { 2, 4 } ], m1,4 + g[4, { 2, 3 } ]) = 25 Lösung: 1, 2, 4, 3, 1
9
Beispiel 2: Rucksackproblem
Ein Wanderer will seinen Rucksack mit verschiedenen Gegenständen packen. Gegeben: Rucksack mit Kapazität C; n Gegenstände mit Gewicht gi und Wert wi, Gesucht: Auswahl der Gegenstände (Indexierung I ⊆ { 1, , n } ), so dass das Gesamtgewicht die Kapazität C nicht überschreitet: ∑ gi ≤ C, i ϵ I und Summe der Werte maximal ist: ∑ wi , i ϵ I maximal.
10
Rucksackproblem: Beispiel
Kapazität C = 10 Vier Gegenstände: Lösungsraum in Binärbaumdarstellung Knoten: verbleibende Kapazität Ebene: entspricht Gegenstand gepackt (nein/ja) Gewicht g 2 6 5 Wert w 3 4
11
Rucksackproblem: Lösungsraum als Binärbaum
(w,g) 10 nein ja (6,2) 10 8 (3,2) 10 8 8 6 (5,6) 10 4 8 2 8 2 6 (4,5) 10 5 4 8 3 2 8 3 2 6 1 (0,0) (4,5) (5,6) (3,2) (7,7) (8,8) (6,2) (10,7) (11,8) (9,4) (13,9) (14,10) Wie man sofort sieht, werden die mittleren Teilbäume mit 8 an der Wurzel mehrfach berechnet!
12
Lösung mit Backtracking (1)
procedure rucksack (i, Rest: int): int if i = AnzahlObjekte then if Rest < gi then return 0 else return wi else if Rest < gi then return rucksack(i + 1, Rest) else return max ( rucksack(i + 1, Rest), rucksack(i + 1, Rest - gi) + wi)
13
Lösung mit Backtracking (2)
Prinzip: schrittweises Durchlaufen des Konfigurationsbaumes Aufruf mit rucksack(1,C) Parameter 1: Index des Gegenstandes Parameter 2: Restkapazität Problem: mehrfaches Berechnen gleicher Teilbäume (etwa rucksack(3,8) )
14
Dynamische Programmierung für den Rucksack (1)
Vermeiden der wiederholten Auswertung Zwischenspeichern der Aufrufe von rucksack(i,C) im zweidimensionalen Feld f Neues Beispiel erweitert um fünften Gegenstand mit g5 = 4 und w5 = 6 Feld f mit Zwischenergebnissen Gewicht g 2 6 5 4 Wert w 3 i 1 2 3 4 rc 5 6 7 8 9 10 11
15
Dynamische Programmierung für den Rucksack (2)
Feld f für i = 4 und rc = 9 bedeutet (f (4, 9)): Aufruf von rucksack(4,9) liefert 10 bei Restkapazität von 9 können Gegenstand 4 und 5 eingepackt werden (5 + 4 = 9) Wert: = 10 Die letzte Zeile mit f (1, 10) ist nicht dargestellt, da nur dieser eine Wert relevant ist: max(f (2, 10), f (2, 8)+6) = max(11, 9+6) = max(11, 15) = 15
16
Iterative Lösung des Rucksackproblems (1)
algorithm rucksack (n, C: int) f : Array [2..n] [0..C] int; /* Initialisiere für i = n */ for rc = 0 to C do if rc < gi then f (n, rc) := 0 else f (n, rc) := wi
17
Iterative Lösung des Rucksackproblems (2)
/* Berechne Rest von f */ for i = n - 1 downto 2 do for rc = 0 to C do if rc < gi then f (i , rc) := f (i + 1, rc) else f (i , rc) := max(f (i + 1, rc), f (i + 1, rc - gi ) + wi ) /* Berechne f (1, C) */ if C < g1 then return f (2, C) else return max(f (2, C), f (2, C - g1) + w1)
18
Bewertung Optimierung durch Vermeiden mehrfacher Berechnung von Teillösungen! Die angegebene Lösung gilt nur für Integerwerte der Gewichte sonst keine einfache Array-Indexierung möglich Möglicherweise sehr großes Feld f praktikabel nur für „grobe“ Stückelung Kapazität 20 und Gewicht 5 versus Kapazität und Gewicht 5000 Aber: die dynamische Programmierung garantiert das Finden der optimalen Lösung.
19
Schwierigkeiten bei der dynamischen Programmierung
Nicht immer ist es möglich, die Lösungen kleinerer Probleme so zu kombinieren, dass sich die Lösung eines größeren Problems daraus ergibt. Der Gesamtaufwand kann unvertretbar groß werden: zu viele Teillösungen, die dann doch nicht benötigt werden. Gewinn durch Wiederverwendung zu gering, da mehrfache Verwendung von Teillösungen selten.
20
Zusammenfassung Die dynamische Programmierung löst ein Problem durch Konstruieren eines Konfi-gurationsbaums und Errechnen von Teillösungen bottom-up. Man speichert alle Teillösungen für eine mögliche spätere Verwendung. Wegen der Wiederverwendung ist oft ein iteratives Aufschreiben des Algorithmus‘ besser ge-eignet als ein rekursives. Die dynamische Programmierung ist für dieselbe Klasse von Problemen geeignet wie „greedy“. Sie ist aufwändiger, aber sie findet immer die optimale Lösung.
Ähnliche Präsentationen
© 2025 SlidePlayer.org Inc.
All rights reserved.