Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

Ähnliche Präsentationen


Präsentation zum Thema: "LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)"—  Präsentation transkript:

1 LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)

2 LS 2 / Informatik 2 Organisatorisches Test (18.5.) Bitte seien Sie um 12 Uhr im Audimax Hilfsmittel: ein handbeschriebenes DIN A4 Blatt Übungsgruppen Wenn ihre Übungsgruppe wegen eines Feiertags ausfällt, gehen Sie in eine andere Falls Sie an keiner Übung teilnehmen, wird dies als Fehlen gewertet

3 LS 2 / Informatik 3 Dynamische Programmierung Fibonacci-Zahlen F(1) = 1 F(2) = 1 F(n) = F(n-1) + F(n-2)

4 LS 2 / Informatik 4 Dynamische Programmierung Fib(n) 1. if n=1 return 1 2. if n=2 return 1 3. return Fib(n-1) + Fib(n-2)

5 LS 2 / Informatik 5 Dynamische Programmierung Lemma Die Laufzeit von Fib(n) ist (1.6 ). Beweis Wir zeigen, dass die Laufzeit T(n) von Fib(n) größer als. n

6 LS 2 / Informatik 6 Dynamische Programmierung Lemma Die Laufzeit von Fib(n) ist (1.6 ). Beweis Wir zeigen, dass die Laufzeit T(n) von Fib(n) größer als. Damit folgt das Lemma wegen. n

7 LS 2 / Informatik 7 Dynamische Programmierung Lemma Die Laufzeit von Fib(n) ist (1.6 ). Beweis Wir zeigen, dass die Laufzeit T(n) von Fib(n) größer als. Damit folgt das Lemma wegen. Beweis per Induktion über n. (I.A.) Für n=1 ist T(1) 1. n

8 LS 2 / Informatik 8 Dynamische Programmierung Lemma Die Laufzeit von Fib(n) ist (1.6 ). Beweis Wir zeigen, dass die Laufzeit T(n) von Fib(n) größer als. Damit folgt das Lemma wegen. Beweis per Induktion über n. (I.A.) Für n=1 ist T(1) 1. Für n=2 ist T(2) 1. n

9 LS 2 / Informatik 9 Dynamische Programmierung Lemma Die Laufzeit von Fib(n) ist (1.6 ). Beweis (I.V.) Für m<n ist T(n). n

10 LS 2 / Informatik 10 Dynamische Programmierung Lemma Die Laufzeit von Fib(n) ist (1.6 ). Beweis (I.V.) Für m<n ist T(n). (I.S.) Wir haben T(n) T(n-1) + T(n-2) da der Algorithmus für n>2 Fib(n-1) und Fib(n-2) rekursiv aufruft. Nach (I.V.) gilt somit n

11 LS 2 / Informatik 11 Dynamische Programmierung Lemma Die Laufzeit von Fib(n) ist (1.6 ). Beweis (I.V.) Für m<n ist T(n). (I.S.) Wir haben T(n) T(n-1) + T(n-2) da der Algorithmus für n>2 Fib(n-1) und Fib(n-2) rekursiv aufruft. Nach (I.V.) gilt somit n

12 LS 2 / Informatik 12 Dynamische Programmierung Warum ist die Laufzeit so schlecht? Betrachten wir Rekursionbaum für Aufruf Fib(6) 6 5 4 4 33 2 32 2 1 2 1 2 1

13 LS 2 / Informatik 13 Dynamische Programmierung Warum ist die Laufzeit so schlecht? Betrachten wir Rekursionbaum für Aufruf Fib(6) 6 5 4 4 33 2 32 2 1 2 1 2 1 Bei der Berechnung von Fib(6) wird Fib(3) dreimal aufgerufen!

14 LS 2 / Informatik 14 Dynamische Programmierung Warum ist die Laufzeit so schlecht? Betrachten wir Rekursionbaum für Aufruf Fib(6) 6 5 4 4 33 2 32 2 1 2 1 2 1 Es wird also mehrmals dieselbe Rechnung durchgeführt!

15 LS 2 / Informatik 15 Dynamische Programmierung Warum ist die Laufzeit so schlecht? Betrachten wir Rekursionbaum für Aufruf Fib(6) 6 5 4 4 33 2 32 2 1 2 1 2 1 Bei großem n passiert dies sehr häufig!

16 LS 2 / Informatik 16 Dynamische Programmierung Memoisation Memoisation bezeichnet die Zwischenspeicherung der Ergebnisse von Funktionsaufrufen eines rekursiven Algorithmus.

17 LS 2 / Informatik 17 Dynamische Programmierung Fib2(n) 1. Initialisiere Feld F[1..n] 2. for i 1 to n do 3. F[i] 0 4. F[1] 1 5. F[2] 1 6. return FibMemo(n,F) FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n]

18 LS 2 / Informatik 18 Dynamische Programmierung Fib2(n) 1. Initialisiere Feld F[1..n] Initialisiere Feld für Funktionswerte 2. for i 1 to n do 3. F[i] 0 4. F[1] 1 5. F[2] 1 6. return FibMemo(n,F) FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n]

19 LS 2 / Informatik 19 Dynamische Programmierung Fib2(n) 1. Initialisiere Feld F[1..n] Initialisiere Feld für Funktionswerte 2. for i 1 to n do Setze Feldeinträge auf 0 3. F[i] 0 4. F[1] 1 5. F[2] 1 6. return FibMemo(n,F) FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n]

20 LS 2 / Informatik 20 Dynamische Programmierung Fib2(n) 1. Initialisiere Feld F[1..n] Initialisiere Feld für Funktionswerte 2. for i 1 to n do Setze Feldeinträge auf 0 3. F[i] 0 4. F[1] 1 Setze F[1] auf korrekten Wert 5. F[2] 1 Setze F[2] auf korrekten Wert 6. return FibMemo(n,F) FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n]

21 LS 2 / Informatik 21 Fib2(n) 1. Initialisiere Feld F[1..n] Initialisiere Feld für Funktionswerte 2. for i 1 to n do Setze Feldeinträge auf 0 3. F[i] 0 4. F[1] 1 Setze F[1] auf korrekten Wert 5. F[2] 1 Setze F[2] auf korrekten Wert 6. return FibMemo(n,F) FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n] Dynamische Programmierung

22 LS 2 / Informatik 22 Fib2(n) 1. Initialisiere Feld F[1..n] Initialisiere Feld für Funktionswerte 2. for i 1 to n do Setze Feldeinträge auf 0 3. F[i] 0 4. F[1] 1 Setze F[1] auf korrekten Wert 5. F[2] 1 Setze F[2] auf korrekten Wert 6. return FibMemo(n,F) FibMemo(n,F) 1. if F[n]>0 then return F[n] Gib Wert zurück, falls schon berechnet 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n] Dynamische Programmierung

23 LS 2 / Informatik 23 Fib2(n) 1. Initialisiere Feld F[1..n] Initialisiere Feld für Funktionswerte 2. for i 1 to n do Setze Feldeinträge auf 0 3. F[i] 0 4. F[1] 1 Setze F[1] auf korrekten Wert 5. F[2] 1 Setze F[2] auf korrekten Wert 6. return FibMemo(n,F) FibMemo(n,F) 1. if F[n]>0 then return F[n] Gib Wert zurück, falls schon berechnet 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) Ansonsten berechne Wert und speichere Wert ab 3. return F[n] Dynamische Programmierung

24 LS 2 / Informatik 24 Fib2(n) 1. Initialisiere Feld F[1..n] Initialisiere Feld für Funktionswerte 2. for i 1 to n do Setze Feldeinträge auf 0 3. F[i] 0 4. F[1] 1 Setze F[1] auf korrekten Wert 5. F[2] 1 Setze F[2] auf korrekten Wert 6. return FibMemo(n,F) FibMemo(n,F) 1. if F[n]>0 then return F[n] Gib Wert zurück, falls schon berechnet 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) Ansonsten berechne Wert und speichere Wert ab 3. return F[n] Gib Wert zurück Dynamische Programmierung

25 LS 2 / Informatik 25 Dynamische Programmierung Fib2(n) Laufzeit: 1. Initialisiere Feld F[1..n] O(n) 2. for i 1 to n do O(n) 3. F[i] 0 O(n) 4. F[1] 1 O(1) 5. F[2] 1 O(1) 6. return FibMemo(n,F) 1+T(n) FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n]

26 LS 2 / Informatik 26 Dynamische Programmierung Beispiel FibMemo(6,F) 6 i:123456 F[i]:110000

27 LS 2 / Informatik 27 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:110000

28 LS 2 / Informatik 28 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:110000 4

29 LS 2 / Informatik 29 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:110000 4 3

30 LS 2 / Informatik 30 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:110000 4 3 2

31 LS 2 / Informatik 31 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:110000 4 3 2

32 LS 2 / Informatik 32 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:110000 4 3 2 1

33 LS 2 / Informatik 33 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:110000 4 3 2 1 1

34 LS 2 / Informatik 34 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:110000 4 3 2 1 1 1

35 LS 2 / Informatik 35 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112000 4 3 2 1 1 1 2

36 LS 2 / Informatik 36 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112000 4 3 2 1 1 1 2 2

37 LS 2 / Informatik 37 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112000 4 3 2 1 1 1 2 2 1

38 LS 2 / Informatik 38 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112300 4 3 2 1 1 1 2 2 1 3

39 LS 2 / Informatik 39 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112300 4 3 2 1 1 1 2 2 1 3 3

40 LS 2 / Informatik 40 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112300 4 3 2 1 1 1 2 2 1 3 3 2

41 LS 2 / Informatik 41 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112350 4 3 2 1 1 1 2 2 1 3 3 2 5

42 LS 2 / Informatik 42 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112350 4 3 2 1 1 1 2 2 1 3 3 2 5 4

43 LS 2 / Informatik 43 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112350 4 3 2 1 1 1 2 2 1 3 3 2 5 4 3

44 LS 2 / Informatik 44 Dynamische Programmierung Beispiel FibMemo(6,F) 6 5 i:123456 F[i]:112358 4 3 2 1 1 1 2 2 1 3 3 2 5 4 3 8

45 LS 2 / Informatik 45 Dynamische Programmierung FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n] Laufzeit Jeder Aufruf FibMemo(m,F) generiert höchstens einmal die rekursiven Aufrufe FibMemo(m-1,F) und FibMemo(m-2,F)

46 LS 2 / Informatik 46 Dynamische Programmierung FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n] Laufzeit Jeder Aufruf FibMemo(m,F) generiert höchstens einmal die rekursiven Aufrufe FibMemo(m-1,F) und FibMemo(m-2,F) Also wird für jedes m<n die Funktion FibMemo(m,F) höchstens zweimal aufgerufen

47 LS 2 / Informatik 47 Dynamische Programmierung FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n] Laufzeit Jeder Aufruf FibMemo(m,F) generiert höchstens einmal die rekursiven Aufrufe FibMemo(m-1,F) und FibMemo(m-2,F) Also wird für jedes m<n die Funktion FibMemo(m,F) höchstens zweimal aufgerufen Ohne die Laufzeit für die rekursiven Aufrufe benötigt FibMemo O(1) Zeit

48 LS 2 / Informatik 48 Dynamische Programmierung FibMemo(n,F) 1. if F[n]>0 then return F[n] 2. F[n] FibMemo(n-1, F) + FibMemo(n-2, F) 3. return F[n] Laufzeit Jeder Aufruf FibMemo(m,F) generiert höchstens einmal die rekursiven Aufrufe FibMemo(m-1,F) und FibMemo(m-2,F) Also wird für jedes m<n die Funktion FibMemo(m,F) höchstens zweimal aufgerufen Ohne die Laufzeit für die rekursiven Aufrufe benötigt FibMemo O(1) Zeit Wir zählen jeden Aufruf mit Parameter 1..n. Daher müssen wir den Aufwand für die rekursiven Aufrufe nicht berücksichtigen. Damit ergibt sich eine Laufzeit von T(n)=O(n)

49 LS 2 / Informatik 49 Dynamische Programmierung Beobachtung Die Funktionswerte werden bottom-up berechnet Grundidee der dynamischen Programmierung Berechne die Funktionswerte iterativ und bottom-up FibDynamischeProgrammierung(n) 1. Initialisiere Feld F[1..n] 2. F[1] 1 3. F[2] 1 4. for i 3 to n do 5. F[i] F[i-1] + F[i-2] 6. return F[i]

50 LS 2 / Informatik 50 Dynamische Programmierung Beobachtung Die Funktionswerte werden bottom-up berechnet Grundidee der dynamischen Programmierung Berechne die Funktionswerte iterativ und bottom-up FibDynamischeProgrammierung(n) 1. Initialisiere Feld F[1..n] 2. F[1] 1 3. F[2] 1 4. for i 3 to n do 5. F[i] F[i-1] + F[i-2] 6. return F[i] Laufzeit O(n)

51 LS 2 / Informatik 51 Dynamische Programmierung Formuliere Problem rekursiv Löse die Rekursion bottom-up durch schrittweises Ausfüllen einer Tabelle der möglichen Lösungen Wann ist dynamische Programmierung effizient? Die Anzahl unterschiedlicher Funktionsaufrufe (Größe der Tabelle) ist klein Bei einer normalen Ausführung des rekursiven Algorithmus ist mit vielen Mehrfachausführungen zu rechnen

52 LS 2 / Informatik 52 Dynamische Programmierung Analyse der dynamischen Programmierung Korrektheit: Für uns wird es genügen, eine Korrektheit der rekursiven Problemformulierung zu zeigen (für einen vollständigen formalen Korrektheitsbeweis wäre auch noch die korrekte Umsetzung des Auffüllens der Tabelle mittels Invarianten zu zeigen. Dies ist aber normalerweise offensichtlich) Laufzeit: Die Laufzeitanalyse ist meist recht einfach, da der Algorithmus typischerweise aus geschachtelten for-Schleifen besteht Hauptschwierigkeit bei der Algorithmenentwicklung Finden der Rekursion

53 LS 2 / Informatik 53 Dynamische Programmierung Problem: Partition Eingabe: Menge M mit n natürlichen Zahlen Ausgabe: Ja, gdw. man M in zwei Mengen L und R partitionieren kann, so dass x = x gilt; nein sonst Beispiel 4, 7, 9, 10, 13, 23 x Lx R

54 LS 2 / Informatik 54 Dynamische Programmierung Problem: Partition Eingabe: Menge M mit n natürlichen Zahlen Ausgabe: Ja, gdw. man M in zwei Mengen L und R partitionieren kann, so dass x = x gilt; nein sonst Beispiel 4, 7, 9, 10, 13, 23 x Lx R

55 LS 2 / Informatik 55 Dynamische Programmierung Problem: Partition Eingabe: Menge M mit n natürlichen Zahlen Ausgabe: Ja, gdw. man M in zwei Mengen L und R partitionieren kann, so dass x = x gilt; nein sonst Beispiel 4, 7, 9, 10, 13, 23 4 + 7 + 9 + 13 = 33 x Lx R

56 LS 2 / Informatik 56 Dynamische Programmierung Problem: Partition Eingabe: Menge M mit n natürlichen Zahlen Ausgabe: Ja, gdw. man M in zwei Mengen L und R partitionieren kann, so dass x = x gilt; nein sonst Beispiel 4, 7, 9, 10, 13, 23 4 + 7 + 9 + 13 = 33 10 +23 = 33 x Lx R

57 LS 2 / Informatik 57 Dynamische Programmierung Problem: Partition Eingabe: Menge M mit n natürlichen Zahlen Ausgabe: Ja, gdw. man M in zwei Mengen L und R partitionieren kann, so dass x = x gilt; nein sonst Beispiel 4, 7, 9, 10, 13, 23 4 + 7 + 9 + 13 = 33 10 +23 = 33 Ausgabe: Ja x Lx R

58 LS 2 / Informatik 58 Dynamische Programmierung Beobachtung Sei M eine Menge mit n natürlichen Zahlen. M kann genau dann in zwei Mengen L,R mit x = x partitioniert werden, wenn es eine Teilmenge L von M gibt mit x =W/2, wobei W= x die Summe aller Zahlen aus M ist. x Lx R x L x M

59 LS 2 / Informatik 59 Dynamische Programmierung Beobachtung Sei M eine Menge mit n natürlichen Zahlen. M kann genau dann in zwei Mengen L,R mit x = x partitioniert werden, wenn es eine Teilmenge L von M gibt mit x =W/2, wobei W= x die Summe aller Zahlen aus M ist. Neue Frage Gibt es L M mit x = W/2 ? x Lx R x L x M x L

60 LS 2 / Informatik 60 Dynamische Programmierung Allgemeinere Frage Welche Zahlen lassen sich als Summe einer Teilmenge von M darstellen?

61 LS 2 / Informatik 61 Dynamische Programmierung Noch allgemeiner Sei M(i) die Menge der ersten i Zahlen von M Für jedes i: Welche Zahlen lassen sich als Summe einer Teilmenge von M(i) darstellen? Formulierung als Funktion Sei G(i,j) = 1, wenn man die Zahl j als Summe einer Teilmenge der ersten i Zahlen aus M darstellen kann Sei G(i,j) = 0, sonst

62 LS 2 / Informatik 62 Dynamische Programmierung Noch allgemeiner Sei M(i) die Menge der ersten i Zahlen von M Für jedes i: Welche Zahlen lassen sich als Summe einer Teilmenge von M(i) darstellen? Formulierung als Funktion Sei G(i,j) = 1, wenn man die Zahl j als Summe einer Teilmenge der ersten i Zahlen aus M darstellen kann Sei G(i,j) = 0, sonst Sei G(0,0) = 1 (Man kann die Null als Summe über die leere Menge darstellen)

63 LS 2 / Informatik 63 Dynamische Programmierung Noch allgemeiner Sei M(i) die Menge der ersten i Zahlen von M Für jedes i: Welche Zahlen lassen sich als Summe einer Teilmenge von M(i) darstellen? Formulierung als Funktion Sei G(i,j) = 1, wenn man die Zahl j als Summe einer Teilmenge der ersten i Zahlen aus M darstellen kann Sei G(i,j) = 0, sonst Sei G(0,0) = 1 (Man kann die Null als Summe über die leere Menge darstellen) Sei G(0,j) = 0 für j0 (Man kann keine Zahl ungleich 0 als Summe über die leere Menge darstellen)

64 LS 2 / Informatik 64 Dynamische Programmierung Noch allgemeiner Sei M(i) die Menge der ersten i Zahlen von M Für jedes i: Welche Zahlen lassen sich als Summe einer Teilmenge von M(i) darstellen? Formulierung als Funktion Sei G(i,j) = 1, wenn man die Zahl j als Summe einer Teilmenge der ersten i Zahlen aus M darstellen kann Sei G(i,j) = 0, sonst Sei G(0,0) = 1 (Man kann die Null als Summe über die leere Menge darstellen) Sei G(0,j) = 0 für j0 (Man kann keine Zahl ungleich 0 als Summe über die leere Menge darstellen)

65 LS 2 / Informatik 65 Dynamische Programmierung Beispiel M = {13, 7, 10, 15} G(1,20) = 0, da man 20 nicht als Summe einer Teilmenge der ersten Zahl aus M darstellen kann G(2,20) = 1, da man 20= 13 +7 als Summe einer Teilmenge der erste beiden Zahlen aus M darstellen kann

66 LS 2 / Informatik 66 Dynamische Programmierung Formulierung als Funktion Sei G(i,j) = 1, wenn man die Zahl j als Summe einer Teilmenge der ersten i Zahlen aus M darstellen kann Sei G(i,j) = 0, sonst Sei G(0,0) = 1 (Man kann die Null als Summe über die leere Menge darstellen) Sei G(0,j) = 0 für j0 (Man kann keine Zahl ungleich 0 als Summe über die leere Menge darstellen)

67 LS 2 / Informatik 67 Dynamische Programmierung Formulierung als Funktion Sei G(i,j) = 1, wenn man die Zahl j als Summe einer Teilmenge der ersten i Zahlen aus M darstellen kann Sei G(i,j) = 0, sonst Sei G(0,0) = 1 (Man kann die Null als Summe über die leere Menge darstellen) Sei G(0,j) = 0 für j0 (Man kann keine Zahl ungleich 0 als Summe über die leere Menge darstellen) Rekursion G(i,j) = 1, wenn G(i-1,j) =1 oder (jM[i] und G(i-1,j-M[i]) = 1) G(i,j) = 0, sonst

68 LS 2 / Informatik 68 Dynamische Programmierung PartitionMemoInit(M) 1. W 0 2. for i 1 to length[M] do 3. W W+ M[i] 4. if W ist ungerade then return 0 5. Initialisiere Feld G[0..length[M]][0..W] 6. for i 0 to length[M] do 7. G[i,0] 1 8. for j 1 to W do 9. G[i,j] -1 10. for j 1 to W do 11. G[0,j] 0 12. if PartitionMemo(M,G, n, W/2)=1 then return 1 13. else return 0

69 LS 2 / Informatik 69 Dynamische Programmierung PartitionMemoInit(M) 1. W 0 Berechne W 2. for i 1 to length[M] do 3. W W+ M[i] 4. if W ist ungerade then return 0 5. Initialisiere Feld G[0..length[M]][0..W] 6. for i 0 to length[M] do 7. G[i,0] 1 8. for j 1 to W do 9. G[i,j] -1 10. for j 1 to W do 11. G[0,j] 0 12. if PartitionMemo(M,G, n, W/2)=1 then return 1 13. else return 0

70 LS 2 / Informatik 70 Dynamische Programmierung PartitionMemoInit(M) 1. W 0 Berechne W 2. for i 1 to length[M] do 3. W W+ M[i] 4. if W ist ungerade then return 0 Keine 2 gleich großen Teilmengen 5. Initialisiere Feld G[0..length[M]][0..W] 6. for i 0 to length[M] do 7. G[i,0] 1 8. for j 1 to W do 9. G[i,j] -1 10. for j 1 to W do 11. G[0,j] 0 12. if PartitionMemo(M,G, n, W/2)=1 then return 1 13. else return 0

71 LS 2 / Informatik 71 PartitionMemoInit(M) 1. W 0 Berechne W 2. for i 1 to length[M] do 3. W W+ M[i] 4. if W ist ungerade then return 0 Keine 2 gleich großen Teilmengen 5. Initialisiere Feld G[0..length[M]][0..W] Initialisiere Feld G 6. for i 0 to length[M] do Setze dabei G[i,0] auf 1 und 7. G[i,0] 1 Setze dabei G[0,j], j>0, auf 0 8. for j 1 to W do G[i,j] = -1 heißt, Funktionswert noch 9. G[i,j] -1 nicht bekannt 10. for j 1 to W do 11. G[0,j] 0 12. if PartitionMemo(M,G, n, W/2)=1 then return 1 13. else return 0 Dynamische Programmierung

72 LS 2 / Informatik 72 PartitionMemoInit(M) 1. W 0 Berechne W 2. for i 1 to length[M] do 3. W W+ M[i] 4. if W ist ungerade then return 0 Keine 2 gleich großen Teilmengen 5. Initialisiere Feld G[0..length[M]][0..W] Initialisiere Feld G 6. for i 0 to length[M] do Setze dabei G[i,0] auf 1 und 7. G[i,0] 1 Setze dabei G[0,j], j>0, auf 0 8. for j 1 to W do G[i,j] = -1 heißt, Funktionswert noch 9. G[i,j] -1 nicht bekannt 10. for j 1 to W do 11. G[0,j] 0 12. if PartitionMemo(M,G, n, W/2)=1 then return 1 13. else return 0 Dynamische Programmierung

73 LS 2 / Informatik 73 PartitionMemoInit(M) 1. W 0 Berechne W 2. for i 1 to length[M] do 3. W W+ M[i] 4. if W ist ungerade then return 0 Keine 2 gleich großen Teilmengen 5. Initialisiere Feld G[0..length[M]][0..W] Initialisiere Feld G 6. for i 0 to length[M] do Setze dabei G[i,0] auf 1 und 7. G[i,0] 1 Setze dabei G[0,j], j>0, auf 0 8. for j 1 to W do G[i,j] = -1 heißt, Funktionswert noch 9. G[i,j] -1 nicht bekannt 10. for j 1 to W do 11. G[0,j] 0 12. if PartitionMemo(M,G, n, W/2)=1 then return 1 13. else return 0 Dynamische Programmierung

74 LS 2 / Informatik 74 Dynamische Programmierung PartitionMemo(M,G, i, j) 1. if j<0 return 0 2. if G[i,j]-1 then return G[i,j] 3. if PartitionMemo(M,G,i-1,j)=1 or PartitionMemo(M,G,i-1,j-M[i]) then G[i,j]=1 4. else G[i,j]=0 5. return G[i,j]

75 LS 2 / Informatik 75 Dynamische Programmierung PartitionMemo(M,G, i, j) Gibt es Teilmenge S von M[1..i] mit x = j ? 1. if j<0 return 0 2. if G[i,j]-1 then return G[i,j] 3. if PartitionMemo(M,G,i-1,j)=1 or PartitionMemo(M,G,i-1,j-M[i]) then G[i,j]=1 4. else G[i,j]=0 5. return G[i,j] x L

76 LS 2 / Informatik 76 Dynamische Programmierung PartitionMemo(M,G, i, j) Gibt es Teilmenge S von M[1..i] mit x = j ? 1. if j<0 return 0 Wenn j ungültig gib false zurück 2. if G[i,j]-1 then return G[i,j] 3. if PartitionMemo(M,G,i-1,j)=1 or PartitionMemo(M,G,i-1,j-M[i]) then G[i,j]=1 4. else G[i,j]=0 5. return G[i,j] x L

77 LS 2 / Informatik 77 Dynamische Programmierung PartitionMemo(M,G, i, j) Gibt es Teilmenge S von M[1..i] mit x = j ? 1. if j<0 return 0 Wenn j ungültig gib false zurück 2. if G[i,j]-1 then return G[i,j] G[i,j] bereits berechnet? 3. if PartitionMemo(M,G,i-1,j)=1 or PartitionMemo(M,G,i-1,j-M[i]) then G[i,j]=1 4. else G[i,j]=0 5. return G[i,j] x L

78 LS 2 / Informatik 78 Dynamische Programmierung PartitionMemo(M,G, i, j) Gibt es Teilmenge S von M[1..i] mit x = j ? 1. if j<0 return 0 Wenn j ungültig gib false zurück 2. if G[i,j]-1 then return G[i,j] G[i,j] bereits berechnet? 3. if PartitionMemo(M,G,i-1,j)=1 Sonst, berechne G[i,j] nach or PartitionMemo(M,G,i-1,j-M[i]) then G[i,j]=1 Rekursion 4. else G[i,j]=0 5. return G[i,j] x L

79 LS 2 / Informatik 79 Dynamische Programmierung PartitionMemo(M,G, i, j) Gibt es Teilmenge S von M[1..i] mit x = j ? 1. if j<0 return 0 Wenn j ungültig gib false zurück 2. if G[i,j]-1 then return G[i,j] G[i,j] bereits berechnet? 3. if PartitionMemo(M,G,i-1,j)=1 Sonst, berechne G[i,j] nach or PartitionMemo(M,G,i-1,j-M[i]) then G[i,j]=1 Rekursion 4. else G[i,j]=0 5. return G[i,j] x L

80 LS 2 / Informatik 80 Dynamische Programmierung PartitionDynamicProg(M) 1. W 0 2. for i 1 to length[M] do 3. W W+ M[i] 4. if W ist ungerade then return 0 5. Initialisiere Feld G[0..length[M]][0..W] 6. for i 0 to length[M] do 7. for j 0 to W/2 do 8. if j=0 then G[i,j] 1 9. else if i=0 then G[i,j] 0 10. else if G[i-1,j] = 1 or (M[i]j und G[i-1,j-M[i]]) then G[i,j] 1 11. else G[i,j] 0 12. return G[length[M],W/2]

81 LS 2 / Informatik 81 Dynamische Programmierung PartitionDynamicProg(M) 1. W 0 Berechnen von W und 2. for i 1 to length[M] do Initialisierung von G 3. W W+ M[i] 4. if W ist ungerade then return 0 5. Initialisiere Feld G[0..length[M]][0..W] 6. for i 0 to length[M] do 7. for j 0 to W/2 do 8. if j=0 then G[i,j] 1 9. else if i=0 then G[i,j] 0 10. else if G[i-1,j] = 1 or (M[i]j und G[i-1,j-M[i]]) then G[i,j] 1 11. else G[i,j] 0 12. return G[length[M],W/2]

82 LS 2 / Informatik 82 PartitionDynamicProg(M) 1. W 0 Berechnen von W und 2. for i 1 to length[M] do Initialisierung von G 3. W W+ M[i] 4. if W ist ungerade then return 0 5. Initialisiere Feld G[0..length[M]][0..W] 6. for i 0 to length[M] do Berechnung 7. for j 0 to W/2 do von G 8. if j=0 then G[i,j] 1 9. else if i=0 then G[i,j] 0 10. else if G[i-1,j] = 1 or (M[i]j und G[i-1,j-M[i]]) then G[i,j] 1 11. else G[i,j] 0 12. return G[length[M],W/2] Dynamische Programmierung

83 LS 2 / Informatik 83 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 0 1 2 3 4 5

84 LS 2 / Informatik 84 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 01 1 2 3 4 5

85 LS 2 / Informatik 85 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 1 2 3 4 5

86 LS 2 / Informatik 86 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 11 2 3 4 5 M[1]=1

87 LS 2 / Informatik 87 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111 2 3 4 5 M[1]=1

88 LS 2 / Informatik 88 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 2 3 4 5 M[1]=1

89 LS 2 / Informatik 89 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 21 3 4 5 M[2]=4

90 LS 2 / Informatik 90 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211 3 4 5 M[2]=4

91 LS 2 / Informatik 91 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 21100 3 4 5 M[2]=4

92 LS 2 / Informatik 92 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001 3 4 5 M[2]=4

93 LS 2 / Informatik 93 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 2110011 3 4 5 M[2]=4

94 LS 2 / Informatik 94 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 3 4 5 M[2]=4

95 LS 2 / Informatik 95 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 31 4 5 M[3]=3

96 LS 2 / Informatik 96 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 311 4 5 M[3]=3

97 LS 2 / Informatik 97 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 3110 4 5 M[3]=3

98 LS 2 / Informatik 98 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 31101 4 5 M[3]=3

99 LS 2 / Informatik 99 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 3110111 4 5 M[3]=3

100 LS 2 / Informatik 100 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 31101110 4 5 M[3]=3

101 LS 2 / Informatik 101 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 3110111011 4 5 M[3]=3

102 LS 2 / Informatik 102 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 311011101100 4 5 M[3]=3

103 LS 2 / Informatik 103 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 311011101100 41 5 M[4]=5

104 LS 2 / Informatik 104 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 311011101100 411011111111 5 M[4]=5

105 LS 2 / Informatik 105 Dynamische Programmierung Beispiel: M = 1, 4, 3, 5, 7 j i 012345678910 010000000000 111000000000 211001100000 311011101100 411011111111 511011111111 M[5]=7

106 LS 2 / Informatik 106 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis PartitionDynamicProg berechnet zunächst die Summe W der Elemente aus M. Ist diese ungerade, so kann es keine Partition in zwei gleich große Teilmengen geben.

107 LS 2 / Informatik 107 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis PartitionDynamicProg berechnet zunächst die Summe W der Elemente aus M. Ist diese ungerade, so kann es keine Partition in zwei gleich große Teilmengen geben. Ansonsten berechnet der Algorithmus die Funktion G, mit G[i,0]= 1 für alle i G[0,j]= 0 für alle j>0 G[i,j] = 1, gdw. G[i-1,j]=1 oder (jM[i] und G[i-1,j-M[i]]=1)

108 LS 2 / Informatik 108 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis PartitionDynamicProg berechnet zunächst die Summe W der Elemente aus M. Ist diese ungerade, so kann es keine Partition in zwei gleich große Teilmengen geben. Ansonsten berechnet der Algorithmus die Funktion G, mit G[i,0]= 1 für alle i G[0,j]= 0 für alle j>0 G[i,j] = 1, gdw. G[i-1,j]=1 oder (jM[i] und G[i-1,j-M[i]]=1) Der Algorithmus gibt 1 zurück, gdw. G[length[M],W/2] = 1.

109 LS 2 / Informatik 109 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis PartitionDynamicProg berechnet zunächst die Summe W der Elemente aus M. Ist diese ungerade, so kann es keine Partition in zwei gleich große Teilmengen geben. Ansonsten berechnet der Algorithmus die Funktion G, mit G[i,0]= 1 für alle i G[0,j]= 0 für alle j>0 G[i,j] = 1, gdw. G[i-1,j]=1 oder (jM[i] und G[i-1,j-M[i]]=1) Der Algorithmus gibt 1 zurück, gdw. G[length[M],W/2] = 1.

110 LS 2 / Informatik 110 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis Wir zeigen per Induktion über i: G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann

111 LS 2 / Informatik 111 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis Wir zeigen per Induktion über i: G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann (I.A.) Für i=0, j=0 kann man j als Summe der leeren Teilmenge darstellen Für i=0, j>0, kann man j nicht als Summe einer Teilmenge der leeren Menge darstellen

112 LS 2 / Informatik 112 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis Wir zeigen per Induktion über i: G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann (I.A.) Für i=0, j=0 kann man j als Summe der leeren Teilmenge darstellen Für i=0, j>0, kann man j nicht als Summe einer Teilmenge der leeren Menge darstellen (I.V.) Für alle k<i und alle j wird G[k,j] korrekt berechnet

113 LS 2 / Informatik 113 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis Wir zeigen per Induktion über i: G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann (I.A.) Für i=0, j=0 kann man j als Summe der leeren Teilmenge darstellen Für i=0, j>0, kann man j nicht als Summe einer Teilmenge der leeren Menge darstellen (I.V.) Für alle k<i und alle j wird G[k,j] korrekt berechnet (I.S.) Z.z. G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann.

114 LS 2 / Informatik 114 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis (I.S.) Z.z. G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann.

115 LS 2 / Informatik 115 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis (I.S.) Z.z. G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann. <= Kann man j als Summe einer Teilmenge von M[1..i], so kann man j entweder als Teilmenge von M[1..i-1] darstellen oder als M[i] vereinigt mit einer Teilmenge von M[1..i-1

116 LS 2 / Informatik 116 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis (I.S.) Z.z. G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann. <= Kann man j als Summe einer Teilmenge von M[1..i], so kann man j entweder als Teilmenge von M[1..i-1] darstellen oder als M[i] vereinigt mit einer Teilmenge von M[1..i-1]. Im ersten Fall folgt aus (I.V.), dass G[i-1,j]=1 ist und somit auch G[i,j]=1.

117 LS 2 / Informatik 117 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis (I.S.) Z.z. G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann. <= Kann man j als Summe einer Teilmenge von M[1..i], so kann man j entweder als Teilmenge von M[1..i-1] darstellen oder als M[i] vereinigt mit einer Teilmenge von M[1..i-1]. Im ersten Fall folgt aus (I.V.), dass G[i-1,j]=1 ist und somit auch G[i,j]=1. Im zweiten Fall muss die Teilmenge von M[1..i-1] Summe j-M[i] haben.

118 LS 2 / Informatik 118 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis (I.S.) Z.z. G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann. <= Kann man j als Summe einer Teilmenge von M[1..i], so kann man j entweder als Teilmenge von M[1..i-1] darstellen oder als M[i] vereinigt mit einer Teilmenge von M[1..i-1]. Im ersten Fall folgt aus (I.V.), dass G[i-1,j]=1 ist und somit auch G[i,j]=1. Im zweiten Fall muss die Teilmenge von M[1..i-1] Summe j-M[i] haben. Nach (I.V.) ist dann aber G[i-1,j-M[i]]=1 und somit G[i,j] = 1.

119 LS 2 / Informatik 119 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis (I.S.) Z.z. G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann. <= Kann man j als Summe einer Teilmenge von M[1..i], so kann man j entweder als Teilmenge von M[1..i-1] darstellen oder als M[i] vereinigt mit einer Teilmenge von M[1..i-1]. Im ersten Fall folgt aus (I.V.), dass G[i-1,j]=1 ist und somit auch G[i,j]=1. Im zweiten Fall muss die Teilmenge von M[1..i-1] Summe j-M[i] haben. Nach (I.V.) ist dann aber G[i-1,j-M[i]]=1 und somit G[i,j] = 1. => Ist G[i,j]=1, so war entweder G[i-1,j]=1 oder G[i-1,j-M[i]]=1. Nach (I.V.) kann man entweder j oder j-M[i] als Teilmenge von M[1..i-1] darstellen. Somit kann man j als Teilmenge von M[1..i] darstellen.

120 LS 2 / Informatik 120 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis (I.S.) Z.z. G[i,j] = 1, gdw. man j als Summe einer Teilmenge von M[1..i] darstellen kann. <= Kann man j als Summe einer Teilmenge von M[1..i], so kann man j entweder als Teilmenge von M[1..i-1] darstellen oder als M[i] vereinigt mit einer Teilmenge von M[1..i-1]. Im ersten Fall folgt aus (I.V.), dass G[i-1,j]=1 ist und somit auch G[i,j]=1. Im zweiten Fall muss die Teilmenge von M[1..i-1] Summe j-M[i] haben. Nach (I.V.) ist dann aber G[i-1,j-M[i]]=1 und somit G[i,j] = 1. => Ist G[i,j]=1, so war entweder G[i-1,j]=1 oder G[i-1,j-M[i]]=1. Nach (I.V.) kann man entweder j oder j-M[i] als Teilmenge von M[1..i-1] darstellen. Somit kann man j als Teilmenge von M[1..i] darstellen.

121 LS 2 / Informatik 121 Dynamische Programmierung Lemma 22 Algorithmus PartitionDynamicProg ist korrekt. Beweis Somit gilt G[length[M],W/2] = 1 gdw. man j als Summe einer Teilmenge von M[1..length[M]] darstellen kann.

122 LS 2 / Informatik 122 Dynamische Programmierung Satz 23 Sei M eine Menge von n natürlichen Zahlen und R die Summe der Zahlen aus M. Algorithmus PartitionDynamicProg löst Partition in Zeit O(nW). Beweis Die Korrektheit des Algorithmus folgt aus Lemma 22. Die Laufzeit ist offensichtlich O(nW).

123 LS 2 / Informatik 123 Dynamische Programmierung Bemerkung Partition ist ein NP-vollständiges Problem Damit gibt es wahrscheinlich keinen polynomieller Algorithmus für Partition Warum ist unser Algorithmus nicht polynomiell? Die Laufzeit hängt von W ab Sind die Zahlen aus M exponentiell groß, so ist die Laufzeit ebenfalls exponentiell


Herunterladen ppt "LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)"

Ähnliche Präsentationen


Google-Anzeigen