1 / 76

Grundlagen der Informatik 1 Thema 7: Komplexität von Algorithmen

Grundlagen der Informatik 1 Thema 7: Komplexität von Algorithmen. Prof. Dr. Max Mühlhäuser Dr. Guido Rößling. Auswahl von Algorithmen. Zeitkomplexität Wie lange dauert die Ausführung? Speicherbedarf Wie viel Speicher wird zur Ausführung benötigt? Benötigte Netzwerkbandbreite.

dian
Download Presentation

Grundlagen der Informatik 1 Thema 7: Komplexität von Algorithmen

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Grundlagen der Informatik 1Thema 7: Komplexität von Algorithmen Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

  2. Auswahl von Algorithmen • Zeitkomplexität • Wie lange dauert die Ausführung? • Speicherbedarf • Wie viel Speicher wird zur Ausführung benötigt? • Benötigte Netzwerkbandbreite Zwei Algorithmen berechnen die gleiche Funktion. Beispiel: merge-sort und insertion-sortWelcher Algorithmus ist der bessere? Betrachtung der nicht-funktionalen Eigenschaften von Algorithmen: Im Folgenden betrachten wir vor allem das Kriterium der Zeit, Speicher wird ähnlich behandelt

  3. Wie beurteilt man die Kosten der Berechnung? • Das Messen der Zeit, die ein Programm für bestimmte Argumente benötigt, kann helfen, um sein Verhalten in einer bestimmten Situation zu verstehen • Aber mit einer anderen Eingabe kann das Programm eine völlig andere Zeit beanspruchen … • Zeitmessungen von Programmen für bestimmte Eingaben entsprechen dem Testen von Programmen für bestimmte Eingaben: • So wie das Testen Fehler aufdecken kann, können Zeitmessungen Anomalien im Ausführungsverhalten für bestimmte Eingaben aufspüren • Allerdings lässt sich davon keine generelle Aussage über das Verhalten eines Programms ableiten • Diese Vorlesung gibt einen ersten Einblickin die Mittel zum Treffen allgemeiner Aussagen über die Ausführungskosten von Programmen • GdI 2 widmet sich diesem Thema genauer

  4. Überblick • Abstraktes Zeit- und Komplexitätsmaß • O-Notation und andere Wachstumsmaße • Techniken zur Bestimmung der Komplexität • Vektoren in Scheme

  5. Konkretes Zeitmaß, Abstraktes Zeitmaß • Die tatsächlicheAusführzeit ist von mehreren Faktoren abhängig • Prozessorgeschwindigkeit • Typ des Computers • Programmiersprache • Qualität des Compilers, … Um sinnvolle Vergleiche von Algorithmen zu ermöglichen, benötigen wir ein Maß der Zeitkomplexität, das von derartigen Faktoren unabhängig sind. Zeit Art des Computer 51.915 11.508 2.382 0.431 0.087 Home computer Desktop Computer Minicomputer Mainframe computer Supercomputer Tatsächliche Ausführungszeit (Millisekunden) für das Berechnen von f

  6. Komplexitätsmessung • Idee: Beschreibung des Zeitverbrauchs als mathematische Funktion  Kostenfunktion • Definitionsbereichder Kostenfunktion: Eingabegröße n • Abhängig vom untersuchten Problem • Für die Sortierung einer Liste: n = Anzahl der Elemente • Matrizenmultiplikation: n = Anzahl der Zeilen, m= Anzahl Spalten • Graphenalgorithmen: n = Anzahl der Knoten, e= Anzahl Kanten • Wertebereichder Kostenfunktion: benötigte Anzahl der Rechenschritte T(n) • Ansatz: Anzahl der Rekursionsschritte ist ein gutes Maß der Größe der Auswertungssequenz

  7. Veranschaulichung des abstrakten Zeitmaßes Untersuchen wir das Verhalten der Funktion length: • Sie erhält eine Liste mit beliebigem Dateninhalt und berechnet wie viele Elemente in der Liste enthalten sind (define (length a-list) (cond [(empty? a-list) 0] [else (+ (length (rest a-list)) 1)])) length (list 'a 'b 'c)) = (+ (length (list 'b 'c)) 1) = (+ (+ (length (list 'c)) 1) 1) = (+ (+ (+ (length empty) 1) 1) 1) = (+ (+ (+ 0 1) 1) 1) = 3 Rekursions-schritte

  8. Veranschaulichung des abstrakten Zeitmaßes Nur die Anzahl der Rekursionsschritte ist relevant für die Bestimmung der Komplexität. • Schritte zwischen den Rekursionen unterscheiden sich nur bzgl. der Substitution von a-list. (length (list 'a 'b 'c)) = (cond [(empty? (list 'a 'b 'c)) 0] [else (+ (length (rest (list 'a 'b 'c))) 1)]) = (cond [false 0] [else (+ (length (rest (list 'a 'b 'c))) 1)]) = (cond [else (+ (length (rest (list 'a 'b 'c))) 1)]) = (+ (length (rest (list 'a 'b 'c))) 1) = (+ (length (list 'b 'c)) 1)

  9. Veranschaulichung des abstrakten Zeitmaßes • Das Beispiel zeigt zweierlei: • Die Anzahl der Auswertungsschritte hängt von der Länge der Eingabeliste ab • Die Anzahl der Rekursionsschritte ist ein gutes Maß für die Länge einer Auswertungssequenz • Wir können die eigentliche Anzahl benötigter Schritte aus diesem Maß und der Funktionsdefinition wieder rekonstruieren. • Die abstrakte Laufzeiteines Programms ist das Verhältnis zwischen der Eingabegröße und der Anzahl der Rekursionsschritte in einer Auswertung • “abstrakt” heißt, die Messung ignoriert konstante Faktoren: • wie viele primitive Schritte pro Rekursion benötigt werden • wie viel Zeit primitive Schritte benötigen • wie viel tatsächliche Zeit die gesamte Berechnung verbraucht

  10. Veranschaulichung des abstrakten Zeitmaßes (define (contains-doll? alos) (cond [(empty? alos) false] [(symbol=? (first alos) 'doll) true] [else (contains-doll? (rest alos))])) • Die folgende Applikation von contains-doll? benötigt keinen Rekursionsschritt. • Die folgende Applikation benötigt so viele Rekursionsschritte, wie es Elemente in der Liste gibt. • Im besten Fall wird die Lösung unmittelbar gefunden • Im schlimmsten Fall wird die gesamte Liste durchsucht (contains-doll? (list'doll'robot 'ball 'game-boy)) (contains-doll? (list 'robot 'ball 'game-boy'doll))

  11. Abstraktes Zeitmaß und Eingabeform • Wir können nicht davon ausgehen, dass Eingaben immer in bestmöglicher Form bereitgestellt werden • Genauso wenig können wir hoffen, dass sie nie in schlechtmöglichster Form vorliegt. • Stattdessen können wir analysieren, wie viel Zeit die Funktion durchschnittlich benötigt. • Zum Beispiel würde contains-doll? im Durchschnitt 'doll irgendwo in der Mitte der Liste finden. • Deshalb können wir sagen, dass die abstrakte Laufzeit von contains-doll? (ungefähr oder durchschnittlich) n/2 beträgt, wenn die Eingabe n Elemente beinhaltet • Im Durchschnitt gibt es halb so viele Rekursionsschritte wie Elemente in der Eingabe.

  12. Komplexitätsklassen • Da das abstrakte Zeitmaß konstante Faktoren ignoriert, können wir die Division durch 2 ignorieren. • Genauer gesagt • Nehmen wir an, dass jeder Rekursionsschritt KZeiteinheiten benötigt • Wenn wir stattdessen K/2als Konstante wählen, haben wir: • Um zu zeigen, dass wir solche Konstanten vernachlässigen, sagen wir, contains-doll? benötige die „Größenordnung von n Schritten“, um'doll in einer Liste mit n Elementen zu finden.

  13. Komplexitätsklassen F ~ in der Größenordnung von n G ~ in der Größenordnungvon n2 G F T 0 n 1000

  14. Analyse: insertion-sort ;; insertion-sort: list-of-numbers  ->  list-of-numbers ;; creates a sortedlistofnumbersfromnumbers in alon (define (insertion-sort alon) (cond [(empty? alon) empty] [else (insert (first alon) (insertion-sort (rest alon)))])) (sort (list 3 1 2)) = (insert 3 (insertion-sort (list 1 2))) = (insert 3 (insert 1 (insertion-sort (list 2)))) = (insert 3 (insert 1 (insert 2 (insertion-sort empty)))) = (insert 3 (insert 1 (insert 2 empty))) = (insert 3 (insert 1 (list 2))) = (insert 3 (cons 1 (list 2))) = (insert 3 (list 1 2)) = (cons 1 insert 3 (list 2)) = (cons 1 (cons 2 (insert 3 empty))) = (list 1 2 3)

  15. Analyse: insertion-sort • Zwei Phasen der Auswertung: • Rekursive Anwendung von insertion-sortaktiviert so viele Applikationen von insert,wie sich Elemente in der Liste befinden • Jede Anwendung von insert durchläuft eine Liste von 1, 2,…,n - 1Elementen (nist die Anzahl der Elemente in der ursprünglichen Liste) – nach Gauß‘scher Formel ist das quadratisch. • insert verhält sich ähnlich dem Suchen eines Elements: • Anwendungen von insert auf einer Liste mit n Elementen benötigen im Schnitt ~ n Rekursionsschritte. • Bei n Anwendungen von insertgibt es eine Größenordnung von n2 Rekursionsschritte von insert • Zusammengefasst: wenn lstn Elemente hat… • benötigt die Auswertung von (insertion-sortlst)nRekursionsschritte von insertion-sortund • n2 Rekursionsschritte von insert. • Zusammen: n2+n , d.h. ~ n2

  16. Komplexitätsklassen • insertion-sortbenötigt ungefähr c1n2Schritte, um n Elemente zu sortieren (proportional zun2) • c1 ist eine Konstante unabhängig von n • Im Folgenden werden wir merge-sortanalysieren • Dies benötigt ungefähr c2n log2nSchritte, um n Elemente zu sortieren • c2 ist eine Konstante unabhängig von n • c2 > c1 • Egal, wie viel kleiner c1 als c2 ist, es wird immer einen Schnittpunkt in den Eingabedaten geben (n groß genug),ab dem merge-sort schneller ist • Wir können also die Konstanten ignorieren

  17. Komplexitätsklassen • Stellen Sie sich vor, wir verwenden einen schnellen Computer A für insertion-sortund einen langsamen Computer B für merge-sort • A ist 100 mal schneller als B betreffend der Rechenleistung • A führt eine Milliarde (109) Anweisungen pro Sekunde aus • B führt nur 10 Millionen Anweisungen (107) pro Sekunde • Zusätzlich nehmen wir an: • insertion-sortist von dem weltbesten Programmierer in der Maschinensprache für A implementiert • Der resultierende Code benötigt 2n2 (c1 = 2) Anweisungen, um n Zahlen zu sortieren • merge-sort ist von einem durchschnittlichen Programmierer in einer high-level Programmiersprache mit ineffizientem Compiler implementiert • Der resultierende Code benötigt 50 n log2n(c2 = 50) Anweisungen

  18. Komplexitätsklassen Wir sortieren eine Liste mit 1 Million Zahlen (n=106)… A (insert-sort) 2 x (106)2 instructions = 2000 sec 109 instructions/sec B (merge-sort) 50 x 106 x log2106instructions ≈ 100 sec 107 instructions/sec Da wir einen Algorithmus verwenden, dessen Laufzeit langsamerer wächst, läuft B20 mal schneller als A(trotz des langsameren Rechners und schlechten Compilers)! Im Allgemeinen wächst der relative Vorteil von merge-sort mit der Problemgröße.

  19. Zusammenfassung: abstrakte Zeit • Unsere abstrakte Beschreibung ist immer eine Aussage über das Verhältnis zweier Mengen: • (mathematische) Funktion, die ein abstraktes Größenmaß der Eingabe auf ein abstraktes Maß der Laufzeit abbildet (Anzahl natürlicher Rekursionen) • Die genaue Anzahl der ausgeführten Operationen ist weniger wichtig • Wichtiger ist die Komplexitätsklasse, zu der der Algorithmus gehört • z.B. linear, logarithmisch • Wenn wir „Größenordnungs“-Eigenschaften von Algorithmen vergleichen, wie z.B. n, n2, 2n…, vergleichen wir die entsprechenden Funktionen, die n Elemente konsumieren und obige Ergebnisse produzieren.

  20. Überblick • Abstraktes Zeit- und Komplexitätsmaß • O-Notation und andere Wachstumsmaße • Techniken zur Bestimmung der Komplexität • Vektoren in Scheme

  21. O-Notation • Funktionen für alle natürlichen ZahlenN zu vergleichen ist schwierig: • Die Domäne der natürlichen Zahlen ist unendlich • Wenn eine Funktion f größere Ausgaben produziert als eine Funktion g für alle n in N, dann ist f eindeutig größer als g • Aber was können wir aussagen, wenn dieser Vergleich für einige Eingaben fehlschlägt? Z.B. für 1000? • Um abschätzende Aussagen zu treffen, übernehmen wir eine mathematische Notation, die zum Vergleichen von Funktionen • bis zu einem Faktor und • bis auf eine endliche Anzahl von Ausnahmen verwendet wird G T F 0 n 1000

  22. O-Notation Größenordnung-von (Groß-O): Fallsgeine Funktion auf den natürlichen Zahlen ist, so ist O(g) (ausgesprochen: „groß-O von g“) eine Klasse von Funktionen auf den natürlichen Zahlen. Eine Funktion f ist in O(g), wenn es die Zahlen cund n0=großGenug gibt, so dass für alle n > n0gilt: f(n) <= cg(n) Die „O-Notation“ geht auf den Zahlentheoretiker Edmund Landau (1877-1938) zurück; das "O" bezeichnet man daher auch als „Landau Symbol“ Wir sagen: "f(n) wächst höchstens so schnell wie g(n)"(g ist eine obere Schranke für f)

  23. O-Notation f „ist höchstens so groß wie“ g (n) f(n)  O(g(n)), wenn zwei positive Konstanten c und n0 existieren, mit |f(n)| c |g(n)| für alle n  n0 Funktion g definiert die Komplexitäts-klasse cg(n) 3000 Funktion fverhält sichasymptotischwieg; ab n0gilt immerf(n) < cg(n) 2000 f(n) Asymptotisches Maß (n  ). Es abstrahiert von unwichtigen Details für die Bestimmung der Komplexitätsklasse. 1000 0 125 250 500 1000 2000 n0

  24. O-Notation: Beispiele • Für f(n) = 1000 n undg(n) = n2 können wir sagen, dass finO(g) ist, weil für alle n> 1000 gilt, • f(n) <= c.g(n) (n0 = 1000 und c = 1) • Die Groß-O Notation bietet eine Kurzform an, um Aussagen über die Laufzeit von Funktionen zu treffen: • Die Laufzeit von length ist O(n). • Im schlechtesten Fall ist die Laufzeit von insertion-sortO(n2) • Dabei sind n und n2 Standardabkürzungen für die (mathematischen) Funktionen f(n) = n und g(n) =n2

  25. Anzahl der Vergleiche Eingabegröße (n) Komplexitätsklassen O(n log n) O(n) • PolynomiellesWachstum(O(nx)) verkleinert die Größe sinnvoller Eingaben stark • Exponentielles Wachstum(O(an)) noch stärker O(n3) O(n2) O(log n)

  26. Eigenschaften der O-Notation • Vergleiche der „O“ Komplexität sind nursinnvollfür große Eingaben • Bei kleinen Eingaben kann ein ineffizienter Algorithmus manchmal schneller sein als ein effizienter • Beispiel: eine Funktion aus 2n2wächst schneller als eine in (184 log2n), sie ist aber besser für kleinere Eingaben (n < 20) • Insbesondere bei Algorithmen mit linearem oder schwächerem Wachstum können sich derartige Faktoren bemerkbar machen • Der Vergleich der Komplexitätsklasse ist in diesen Fällen u.U. nicht ausreichend.

  27. f(n) = an2 + bn +c mit a = 0.0001724, b = 0.0004 und c = 0.1 n2 - Ausdruck in %vom ganzen f(n) an2 n 10 125 250 500 1000 2000 0.121 2.8 11.0 43.4 172.9 690.5 0.017 2.7 10.8 43.1 172.4 689.6 14.2 94.7 98.2 99.3 99.7 99.9 Eigenschaften der O-Notation • Die O-Notation blendet proportionale Faktoren, kleine Eingaben und kleinere Termeaus Beispiele: 2n3+n2-20O(n3)log10 n O(log2 n) n + 10000 O(n) n O(n2) O(1)  O(log n)  O(n)  O(n2)  O(n3)  O(2n)  O(10n)

  28. O-Notation: andere Symbole • Es gibt noch mehr Symbole für verschiedene Zwecke: • Asymptotische untere Schranke [f(n) (g(n))]: • f(n) (g(n)), wenn positive Konstanten c und n0N existieren, so dass 0 cg(n)  f(n),  n n0 • Wir sagen: „f(n) wächst mindestens so schnell wie g(n)“ • Asymptotisch exakte Schranke [f(n) (g(n))]: • f(n) (g(n)), wenn die positiven Kostanten c1, c2, und n0 N existieren, so dassc1 g(n)f(n)c2 g(n),n n0 • f(n) (g(n)) genau dann, wenn • f(n)  O(g(n)) und f(n) (g(n)) • Wir sagen „f(n) wächst genauso schnell wie g(n)“

  29. O-Notation: andere Symbole • Schema für O,  und : n0 n0 n0 obere Schranke untere Schranke exakte Schranke

  30. Andere asymptotische Notationen • Eine Funktion f(n) ist in o(g(n)), wenn es positive Konstanten c und n0 gibt, so dass f(n) < c g(n)  n  n0 • Eine Funktion f(n) ist in (g(n)), wenn es positive Konstanten c und n0 gibt, so dassc g(n) < f(n)  n  n0 • Intuitiv: • () ist ähnlich > • () ist ähnlich  • () ist ähnlich = • o() ist ähnlich < • O() ist ähnlich 

  31. Übersicht • Abstraktes Zeit- und Komplexitätsmaß • O-Notation und andere Wachstumsmaße • Techniken zur Bestimmung der Komplexität • Vektoren in Scheme

  32. Beispiel: Exponentieren • Eingabe: Basis b und positiver ganzzahliger Exponent n • Ausgabe: bn • Idee: bn = b* b(n-1) , b0 = 1 • Angenommen die Multiplikation benötigt eine konstante Zeit c • Dann giltT(n) = cn = O(n) (define (expt b n)  (cond [(= n 0) 1]    [else (* b (expt b (- n 1)))]))

  33. Beispiel: Exponentieren • Idee: Weniger Schritte durch sukzessives Quadrieren • Statt b8als b*b*b*b*b*b*b*b zu berechnen, können wir es auch so machen:b2 = b*b, b4 = (b2)2, b8 = (b4)2 • Generell gilt die Regel • bn = (bn/2) 2 wenn n gerade istbn = b*bn-1 wenn n ungerade ist • Zu welcher Komplexitätsklasse gehört dieser Algorithmus? (define (fast-expt b n)  (cond [(= n 0) 1]        [(even? n) (sqr (fast-expt b (/ n 2))))        (else (* b (fast-expt b (- n 1))))))

  34. Analyse von Teile-und-Herrsche Algorithmen • Für rekursive Algorithmen kann die Laufzeit oft als Rekurrenzgleichung (Rekurrenz) beschrieben werden • Gesamtlaufzeit wird mittels der Laufzeit für kleinere Eingaben definiert • Beispiel: • Problem (n) wird in 2 Teilprobleme (n/2) zerlegt • Aufwand cn für Zerlegung und Kombination der Teillösungen • Eine Rekurrenz T(n)für die Laufzeit eines Teile-und-Herrsche Algorithmus der Größen basiert auf den drei Schritten des Paradigma…

  35. Analyse von Teile-und-herrsche Algorithmen • Fall 1: Die Problemgröße ist klein genug, sagen wir n <= c für eine Konstante c, so dass es trivial gelöst werden kann  Lösung benötigt konstante Zeit  (1) • Fall 2: Das Problem ist nicht-trivial: • Die Teilung des Problems ergibt a Teilprobleme, die alle 1/b der Größe des Originals haben • Beispiel: für merge-sort haben wir a = b = 2 • D(n): Aufwand für die Zerlegung in Teilprobleme • C(n): Aufwand für das Kombinieren der Teillösungen

  36. Die Türme von Hanoi ! Das „Türme von Hanoi“ Puzzle wurde 1883 vom französischen Mathematiker Édouard Lucas erfunden. Wir bekommen einen Turm von Scheiben, in größer werdender Reihenfolge auf einen der drei Stäbe gesteckt. Das Ziel ist, den ganzen Turm auf einen der anderen Stäbe zu bringen, wobei jeweils nur eine Scheibe bewegt und niemals eine größere auf eine kleinere Scheibegelegt werden darf.

  37. 1 3 2 Die Türme von Hanoi: Algorithmus B C A n • Um n Scheiben von Stange A zu Stange B zu bewegen: • Bewege n−1 Scheiben von A nach C. Damit bleibt Scheibe #n auf A • Bewege Scheibe #n von A nach B • Bewege n−1 Scheiben von C nach B, so dass sie auf Scheibe #n sitzen Rekursiver Algorithmus: Um Schritte 1 und 3 auszuführen, wende den gleichen Algorithmus wieder für n-1 an. Die gesamte Prozedur ist eine endliche Anzahl von Schritten, denn irgendwann wird der Algorithmus für n = 1 angewendet werden. Dieser Schritt, eine einzelne Scheibe zu verschieben, ist trivial.

  38. Die Türme von Hanoi (move 'A 'B 'C 4) (define (move T1 T2 T3 n) (cond [(= n 0) empty] [else (append (move T1 T3 T2 (- n 1)) (list (list T1 T2)) (move T3 T2 T1 (- n 1))) ] ) ) (list (list 'A 'C) (list 'A 'B) (list 'C 'B) (list 'A 'C) (list 'B 'A) (list 'B 'C) (list 'A 'C) (list 'A 'B) (list 'C 'B) (list 'C 'A) (list 'B 'A) (list 'C 'B) (list 'A 'C) (list 'A 'B) (list 'C 'B)) Ausgegeben wird die Liste der Scheibenbewegungen A C B Wie viele Scheibenbewegungen sind erforderlich, um einen Stapel der Höhe n zu bewegen?

  39. i-1 å 2k = 0 k = 2i×T(n-i) + , für i=n, n-i wird 0 Rekursive Komplexitätsfunktionfür die Türme von Hanoi • Wie viele Umlagerungen von Scheiben sind notwendig …? • für n < 2 ist die Antwort einfach: T(0)=0, T(1)=1 • für n > 1 ist die Antwort rekursiv definiert: T(n) = T(n-1)+1+T(n-1) = 2×T(n-1)+1 = 2×(2×T(n-2)+1)+1 = 2×(2×(2×T(n-3)+1)+1)+1 = 2n×T(0) + 2n-1 = 2n-1 => exponentielle Komplexität!

  40. Wenn das Universum sein Ende finden wird… Es gibt eine Legende über ein buddhistisches Kloster bei Hanoi, in dem sich ein riesiger Raum mit drei abgenutzten Pfosten befindet, die von 64 goldenen Scheiben umgeben waren. • Seit der Gründung des Klosters vor über tausend Jahren führen Mönche die Anordnung einer alten Prophezeiung aus: • Sie bewegen die Scheiben in Übereinstimmung mit den Regeln des Puzzles • Jeden Tag bewegen die Mönche eine Scheibe • Man sagt, sie glauben, wenn die letzte Bewegung ausgeführt würde, wird die Welt mit einem Donnerschlag untergehen.

  41. Wenn das Universum sein Ende finden wird… • Zum Glück sind sie nicht mal annäherungsweise fertig  • Angenommen, die Legende wäre wahr und die Mönche könnten eine Scheibe pro Sekunde bewegen, mit der kleinsten Anzahl an nötigen Bewegungen: • Dann bräuchten sie zur Lösung 264−1 Sekunden - das sind etwa 585 Milliarden Jahre • Unser Universum ist zur Zeit ungefähr 13,7 Milliarden Jahre alt

  42. Analyse von MergeSort • Vereinfachung: Größe des ursprünglichen Problems ist eine Potenz von 2 • Jeder Teilung liefert zwei Teilsequenzen von Länge n/2 • Es gibt Beweise, dass eine solche Annahme die Komplexitätsklasse der Lösung zur Rekurrenz nicht beeinflusst • Worstcase: n > 1 • Teile: Das Extrahieren der Elemente der beiden Teillisten benötigt jeweils Zeit der Ordnung n  D(n) = 2n ~(n) • Herrsche: Das rekursive Lösen der 2 Teilprobleme dauert 2T(n/2) • Kombiniere: Zusammenfügen der beiden Listen benötigt auch (n) worst-case Laufzeit für mergesort

  43. Lösen von Rekurrenzen • Frage: Wie löst man Rekurrenzen wie diese? • Antwort: Mathematische Methoden die uns dabei helfen: • Substitutionsmethode • Rekursionsbaum-Methode • Master-Methode basierend auf dem Master-Theorem • Eine „Kochbuch“-Methode, um Rekurrenzen der Form T(n) = aT(n/b)+f(n) zu lösen, a 1, b>1, f(n)asymptotisch positive Funktion • Kann benutzt werden, um zu zeigen, dass T(n) von mergesort in (n log n) ist • Dabei vernachlässigen wir technische Details: • Wir ignorieren Rundungen nach unten und oben (absorbiert durch O- oder Q-Notation) • Wir nehmen ganzzahlige Argumente für Funktionen an • Wir vernachlässigen Grenzbedingungen

  44. Das Master-Theorem • Betrachte • wobei a >= 1 und b >= 1 falls n < c falls n > 1 • Wenn für eine Konstante e > 0, • dann • Wenn , dann • Wenn für eine Konstante e > 0 und wenn a f(n/b) <= cf(n) für eine Konstante c < 1 und alle hinreichend großen n, dann T(n) =Q(f(n))

  45. Die Rekursionsbaum-Methode • In einem Rekursionsbaum repräsentiert jeder Knoten die Kosten eines Teilproblems in der Kette der rekursiven Funktionsapplikationen • Summiere Kosten auf jeder Ebene, um Kosten pro Ebene zu bekommen • Summiere alle Kosten pro Ebenen, um Gesamtkosten zu ermitteln • Besonders nützlich für Rekurrenzen, welche die Laufzeit von Teile-und-herrsche Algorithmen beschreiben • Oftmals verwendet, um eine gute Annäherung zu finden, die dann mit anderen Methoden verifiziert wird • Wenn sorgfältig entworfen, kann sie auch als direkter Beweis einer Lösung für eine Rekurrenz dienen

  46. Baum für die erste Applikation cn T(n/2) T(n/2) Baum für zwei Applikationsschritte cn cn/2 cn/2 T(n/4) T(n/4) T(n/4) T(n/4) Rekursionsbaum für Merge Sort Schreiben wir die Rekurrenz für merge-sort wie folgt:

  47. Rekursionsbaum für MergeSort Gesamt: cn (log n + 1) cn cn cn cn/2 cn/2 cn cn/4 cn/4 cn/4 cn/4 logn + 1 Ebene (Induktion) ... ... ... ... ... ... ... ... ... 2ic(n/2i) Ebene i  2i Knoten ... ... ... ... ... ... ... ... ... cn c c c c c c c c n

  48. Die Substitutionsmethode • Auch bekannt als die “making a goodguessmethod” („eine gute Annäherung finden“ - Methode) • Funktionsweise: • Rate die Form der Antwort, • Benutze Induktion, um die Konstanten zu finden und zeige, dass die Lösung funktioniert • Beispiele: • T(n) = 2T(n/2) + (n)  T(n) = (n log n) • T(n) = 2T(n/2) + n  ??? • T(n) = 2T(n/2 )+ 17) + n  ??? • T(n) = 2T(n/2) + nT(n) =(n log n) • T(n) = 2T(n/2+ 17) + n(n log n)

  49. Die Substitutionsmethode Rekurrenz: Geschätzte Lösung: Zu zeigen ist, dass für eine geeignete Konstante c > 0 Anfangsannahme: die Schranke gilt für also: Lösung: die Abschätzung ist für n>n0 zu zeigen

  50. Bester Fall: die Partitionierungerzeugt in jedemSchrittzweiTeilproblemederGröße n/2 Master Theorem Performanz von Quicksort: bester Fall Die Laufzeit von quicksorthängt von der Qualität der Partitionierung ab, d.h., von den Pivot-Elementen

More Related