Höhere Algorithmik Simon Putzke Wintersemester 09/10

FU-Berlin Prof.: G. Rote

Erstellt mit LYX.

"THE BEER-WARE LICENSE" (Revision 42): Simon Putzke wrote this file. As long as you retain this notice you can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a beer in return.

3

4

Inhaltsverzeichnis

I.

Einleitung

11

II. Sortieren I

15

1. Sortieralgorithmen A1: bogosort . . . . . . . . . . . . . . . . . . A2: Überprüfen durch Auswahl . . . . . . . . A3: Sortieren durch Verschmelzen (Mergesort) A4: Quicksort . . . . . . . . . . . . . . . . . A5: ohne Bezeichnung . . . . . . . . . . . . . Vergleich der Algorithmen . . . . . . . . . . . 1.0.1. Allgemeine Bemerkungen . . . .

17 17 18 19 21 24 25 25

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

III. Rechenmodelle

27

2. Arten von Rechnermodellen 2.1. Turingmaschine (Alan Turing, 1936) . . . . 2.2. Registermaschine . . . . . . . . . . . . . . . Logarithmisches Kostenmaß (LKM) 2.3. Word- RAM . . . . . . . . . . . . . . . . .

29 29 29 31 33

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

IV. Sortieren II

35

3. Median finden Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a) Pivotelement zufällig auswählen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . b) deterministisch mit Laufzeit O(n) im schlimmsten Fall . . . . . . . . . . . . . . . . . . .

37 37 38 41

4. Das Divide & Conquer Prinzip Verbesserte Multiplikation (Karatsuba- Multiplikation) . . . . . . . . . . . . . . . . . . . . .

45 46

5. Entscheidungsbäume und untere Schranken für das Sortieren

49

6. Suche in sortierten Listen 6.1. Binäre Suche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2. Interpolationssuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3. Quadratische Binärsuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

51 51 51 52

5

Inhaltsverzeichnis

V. Rekursionsgleichungen

55

7. Das 7.1. 7.2. 7.3.

57 57 59 59

Master-Theorem Hinleitung zum Master-Theorem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Anwendung des Master-Theorems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Beweis des Master-Theorems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

VI. Das Wörterbuchproblem 8. Datenstrukturen I 8.1. Streuspeicherung . . . . . . . . . . . . . . . . 8.2. Suchbäume . . . . . . . . . . . . . . . . . . . 8.2.1. Binärer Suchbaum . . . . . . . . . . . 8.2.2. AVL- Baum . . . . . . . . . . . . . . . 8.2.3. (a,b)- Baum . . . . . . . . . . . . . . . B- Baum . . . . . . . . . . . . . . . . Einfügen . . . . . . . . . . . . . . . . . Löschen aus einem (a,b)- Baum . . . . Verschmelzen von Listen verschiedener

63 . . . . . . . . .

65 65 66 66 66 67 67 67 68 70

9. Amortisierte Analyse 9.1. Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2. Methoden zur Bestimmung der amortisierten Laufzeit . . . . . . . . . . . . . . . . . .

75 75 75

10.Vereinige-Finde-Problem (Union-Find) 10.1. Operationen . . . . . . . . . . . . . . . . . . . 10.2. Anwendungen . . . . . . . . . . . . . . . . . . 10.3. Realisierung durch eine Datenstruktur . . . . 10.4. Höhenbalancierung . . . . . . . . . . . . . . . 10.5. Pfadkompression . . . . . . . . . . . . . . . . 10.6. Knotenrang . . . . . . . . . . . . . . . . . . . 10.6.1. Beobachtung . . . . . . . . . . . . . . 10.6.2. Einschub: Turmfunktion (Potenzturm) 10.7. Analyse einer FIND- Operation . . . . . . . . Ackermann- Funktion . . . . . . . . . Inverse Ackermann- Funktion . . . . .

79 79 79 79 80 81 81 82 82 82 83 84

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Länge ((2,3)-Bäume)

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

VII. Algorithmen-Entwurfsprinzipien

85

11.Dynamische Programmierung/Optimierung 11.1. Optimaler binärer Suchbaum . . . . . . . . . . . 11.1.1. Suchkosten . . . . . . . . . . . . . . . . . 11.1.2. Zusammenfassung . . . . . . . . . . . . . Rekursionsgleichung . . . . . . . . . . . . Laufzeit . . . . . . . . . . . . . . . . . . . 11.2. Kürzeste Triangulierung eins konvexen Polygons . 11.2.1. Dynamischer Ansatz . . . . . . . . . . . . 11.3. Rucksackproblem . . . . . . . . . . . . . . . . . . 11.4. Die optimale Stadt (Manhattan Problem) . . . .

87 87 87 91 91 91 92 92 93 94

6

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

Inhaltsverzeichnis 11.4.1. Dynamische Programmierung: erster Ansatz . . . . . . . . . 11.4.2. Rekursion . . . . . . . . . . . 11.4.3. Rekursionsgleichung . . . . . 11.5. Hamiltonkreise im Graphen . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

94 94 95 96 97

12.Der Greedy- Algorithmus 101 12.1. Rucksackproblem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 12.1.1. Verbesserter Greedy- Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . 101 12.2. Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 13.Branch-and-Bound 103 13.1. Rucksackproblem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 13.1.1. Verbesserung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 14.Laufzeiten 14.1. Unterschied von polynomiell, exponentiell und 14.1.1. polynomiell . . . . . . . . . . . . . . . 14.1.2. exponentiell . . . . . . . . . . . . . . . 14.1.3. Länge der Eingabe . . . . . . . . . . . 14.1.4. pseudopolynomiell . . . . . . . . . . . 14.1.5. Kostenmaß . . . . . . . . . . . . . . .

pseudopolymnomiell. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

VIII.Graphen 15.Allgemeines in Graphen 15.1. Inhalte . . . . . . . . . 15.2. Speicherung . . . . . . 15.2.1. Adjazenzliste . 15.2.2. Adjazenzmatrix

107 107 107 107 107 107 108

109 . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

111 111 111 111 111

16.Durchsuchen von Graphen 113 16.1. Tiefensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 16.2. Breitensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 17.Kürzeste Wege 17.1. Allgemeines . . . . . . . . . . . . . . . . 17.1.1. Probleme bei negativen Kosten . 17.2. Algorithmus von Bellman-Ford . . . . . 17.2.1. Berechnung . . . . . . . . . . . . 17.2.2. Anmerkungen,Beobachtungen . . 17.3. Algorithmus von Floyd-Warshall . . . . 17.3.1. Varianten und Verallgemeinerung Erreichbarkeit in Graphen . . . . Algorithmus von Kleene . . . . . Weg mit der größten Kapazität . 17.3.2. Allgemeine Wegprobleme . . . .

. . . . . . . . . . . . auf . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . andere Wegprobleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

115 115 115 115 116 117 117 119 119 120 120 120

18.Flüsse in Netzen 123 18.1. Formales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

7

Inhaltsverzeichnis 18.2. Problem des größten Flusses . . . . . . . . . . 18.2.1. Max-Fluss-Min-Schnitt-Satz . . . . . . 18.2.2. Ford-Fulkerson . . . . . . . . . . . . . 18.3. Paarungen (Matchings) in bipartiten Graphen

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

124 125 127 130

IX. Komplexitätstheorie

133

19.Die Klasse P 19.1. Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . 19.2. Probleme . . . . . . . . . . . . . . . . . . . . . . . . . . 19.2.1. Berechnungsprobleme . . . . . . . . . . . . . . . 19.2.2. Entscheidungsprobleme . . . . . . . . . . . . . . 19.3. Rechenmodell . . . . . . . . . . . . . . . . . . . . . . . . 19.4. Länge der Eingabe . . . . . . . . . . . . . . . . . . . . . 19.5. Polynomielle Reduktion . . . . . . . . . . . . . . . . . . 19.5.1. Drei Graphenprobleme . . . . . . . . . . . . . . . CLIQUE . . . . . . . . . . . . . . . . . . . . . . . Knotenüberdeckung (KÜ) / vertex cover (VC) . Unabhängige Menge (UM) / independent set (IS) 19.5.2. Beispielreduktionen . . . . . . . . . . . . . . . . . KÜ ≤p UM . . . . . . . . . . . . . . . . . . . . . UM ≤p CLIQUE . . . . . . . . . . . . . . . . . . CLIQUE ≤p KÜ . . . . . . . . . . . . . . . . . . 19.5.3. Weitere Graphenprobleme . . . . . . . . . . . . . HAM-PFAD (Hamilton- Pfad) . . . . . . . . . . KEW (kürzester einfacher Weg) . . . . . . . . . . 19.5.4. Weitere Beispielreduktion . . . . . . . . . . . . . HAM-PFAD ≤p KEW . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

135 135 135 135 135 135 136 136 137 137 137 138 138 138 138 139 139 139 139 140 140

. . . . . . . . . . . . . . . . . .

141 141 141 142 142 143 143 143 144 145 145 146 146 148 148 148 149 149 149

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

20.Die Klasse NP 20.1. Definitionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2. Probleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2.1. Das Erfüllbarkeitsproblem (SAT) . . . . . . . . . . . . . . 20.2.2. Exaktes Rundreiseproblem . . . . . . . . . . . . . . . . . . 20.2.3. Gewinnposition von Go (oder ähnlichen Positionsspielen) 20.2.4. Bipartite Paarung (BP) . . . . . . . . . . . . . . . . . . . 20.2.5. 3-SAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2.6. 3-Färbung . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2.7. 2-SAT ∈ P . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2.8. Hamiltonkreis in gerichteten Graphen . . . . . . . . . . . 20.2.9. Rundreiseproblem ist NP-vollständig . . . . . . . . . . . . 20.2.10.Teilmengensumme (subsetsum) . . . . . . . . . . . . . . . TMS in unärer Kodierung . . . . . . . . . . . . . . . . . . 20.2.11.Dreidimensionales Matching (3DM) . . . . . . . . . . . . . 20.3. Approximationsalgorithmen . . . . . . . . . . . . . . . . . . . . . 20.3.1. Ungerichtetes Rundreiseproblem mit Dreiecksungleichung 20.3.2. Rundreiseproblem in der Ebene . . . . . . . . . . . . . . . 20.4. Klasse CoNP . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

Inhaltsverzeichnis Glossar

155

9

Inhaltsverzeichnis

10

Teil I.

Einleitung

11

Voraussetzungen Es wird vorausgesetzt, dass zu folgenden Themen bereits Kentnisse vorhanden sind: • grundlegende Datenstrukturen – Felder (Arrays) – verkettete Listen – (balancierte) Suchbäume – Halde (Heap) – Prioritätswarteschlange • Graphenalgorithmen – Tiefensuche, Breitensuche – Kürzeste Wege mit dem Dijkstra- Algorithmus – Kürzeste Spannbäume • Laufzeit, O- Notation

• Umgang mit Wahrscheinlichkeit, Erwartungswert

Was wird passieren? Grundlagen / Theorie Rechenmodelle NP- Vollständigkeit (Komplexitätstheorie)

Techniken Analyse - Rekursionsgleichungen - amortisierte Analyse Entwurf - Teile und Herrsche - dynamische Programmierung - greedy Algorithmen

Algorithmen Fortgeschrittene Datenstrukturen - randomisierte Suchbäume - UNION-Find-Problem - Zeichenketten Graphen : Flüsse Arithmetik schnelle Fouriertransformation (Fast Fourier Transform FFT)

Ziele Sie entwerfen Algorithmen (mit Hilfe von allgemeinen Entwurfsprinzipien, z.B. Teile und Herrsche). Sie analysieren Laufzeiten und den Speicherbedarf von Algorithmen. Sie kennen grundlegende Algorithmen und können sie auf Aufgaben aus verschiedenen Gebieten anwenden. Sie verstehen die Bedeutung von NP - Vollständigkeit und können Probleme in Komplexitätsklassen einordnen.

13

14

Teil II.

Sortieren I

15

1. Sortieralgorithmen Es gibt n Datensätze mit Schlüsseln aus einer totalgeordneten Menge. Aufgabe: Diese Datensätze sollen in die richtige Reihenfolge gebracht werden. Es existieren dafür zwar Bibliotheken, wir machen dies aber zu Fuß, denn es ist wichtig zu wissen, wie diese funktionieren. Wir betrachten im Folgenden 5 Algorithmen:

A1: bogosort Algorithmus Algorithmus 1.1 bogosort Die Datensätze werden sooft umgeordnet, bis die sortierte Folge da ist. Betrachte alle n! Permutationen der Eingabedaten. Für jede Permutation gilt dann: Überprüfe, ob diese sortiert ist. Wenn ja: HALT. Dieser Algorithmus terminiert und funktioniert, da die sortierte Liste eine Permutation ist und die Anzahl aller Permutationen ist endlich.

Laufzeit Eine Liste mit n Elementen besitzt n! Permutationen, demnach n! Möglichkeiten O(n!). Diese muss überprüft werden, ob sie sortiert ist. Bei n Elementen ergibt dies O(n). Die Laufzeit beträgt demnach O(n! · n).

17

1. Sortieralgorithmen

A2: Überprüfen durch Auswahl Algorithmus Algorithmus 1.2 Überprüfen durch Auswahl Finde das kleinste Element und entferne es aus der Liste. Wiederhole diesen Schritt, bis die Liste leer ist.

Laufzeit Um das kleinste Element von n Elementen zu finden, werden (n-1) Vergleiche benötigt. Laufe von links nach rechts, merke das Kleinste und prüfe mit dem nächsten Element. Rekursionsgleichung:

T (n) = #Vergleiche insgesamt (n − 1) + T (n − 1) ! "# $ ! "# $ Vergleiche Listenelemente T (1) = 0

T (n) =

T (n) =

= = =

18

(n − 1)

+ T (n − 1) (n − 2)

(n − 1)

+

n · (n − 1) 2 % & Θ n2

(n − 2)

+

+...+

T (n − 2) (n − 3) + T (n − 3) .. . 1

+

T (1) ! "# $ =0

A3: Sortieren durch Verschmelzen (Mergesort)

A3: Sortieren durch Verschmelzen (Mergesort) Algorithmus

Algorithmus 1.3 Mergesort Der Algorithmus folgt dem Teile und Herrsche-Prinzip. Zerlege die Daten in zwei gleich große Teile und sortiere diese rekursiv. Verschmelze diese beiden sortierten Listen der Länge ≈ n2 zur sortierten Ergebnisliste der Länge n. (n kann ungerade sein, daher das ≈).

(verschmelzen = engl. merge)

Laufzeit Das Verschmelzen zweier Listen der Länge a und b benötigt höchstens (a+b-1) Vergleiche. 2 3

5 6

8 7

9

20

5 → 3 2

8 6

9 7

20

5 → 6 2

8 7 3

9

20

8 → 6 2

9 7 3

20 usw. 5

Vergleiche beide Listen, wähle das kleinere Element am Anfang und füge es in eine neue Liste, dann vergleiche das nächste Element.

T (n) = #Vergleiche für Mergesort bei n Datensätzen T (1) = T (0) = 0 '+ n ,* '( n )* +T + (n − 1) T (n) ≤ T 2 2 Um die Gleichung zu vereinfachen, werden die Rundungen & ' ( ) aus der Gleichung entfernt und wir nehmen an, dass n = 2k . % & Vereinfachte Rekursionsgleichung n = 2k : T (n) ≤ 2 · T

'n* 2

+n

Lösen durch sukzessives Einsetzen:

19

1. Sortieralgorithmen

T (n)



'n* n+2·T ! "#2 $ %n& 2

=n

(i = k)

≤ ≤

# $! ' n *" n+2· 2 % & i · n + 2i · T 2ni

'n* + 2·T !% "#&4 $ n

2·T .. .

+

4

=n

+

# $! ' n *" 4· 4

+ 2k

8·T

%n&

%n& 8

8

= ...

⇒ k = log2

% & ≤ k · n + 2k · T 2nk = n · k = n · log2 n ⇒ T (n) = O(n · log n) Beweis: T (n) ist monoton wachsend, dies kann mit vollständiger Induktion bewiesen werden. Wenn n keine Zweierpotenz ist, so nimm die nächstgrößere Zweierpotenz n! = 2"log2 n# mit n ≤ n! < 2 · n. max. 2·T (n) # $! " = O(n! · log n! ) T (n) ≤ T (n! )

= O(2n · log2 2n) ! "# $ log n+1

= O(2n · log n + 2n)

= O(n · log n)

!

20

A4: Quicksort

A4: Quicksort Algorithmus Algorithmus 1.4 Quicksort Der Quicksort- Algorithmus funktioniert nach dem Teile und Herrsche-Prinzip. 1. Wähle ein Element a, das sogenannte Pivot-Element, aus der Eingabe. 2. Zerlege die Eingabe in die Elemente < a und > a. Sortiere die beiden Teillfolgen rekursiv. 3. Füge die sortieren Teilfogen mit a zum Ergebnis zusammen.

Laufzeit Annahme: Alle Elemente sind verschieden, d.h. es existiert keine gleichen Elemente. Das Zerlegen in eine Teilfolge benötigt (n-1) Vergleiche. Nun wird die Eingabe in zwei Teile der Größe k und (n-1-k) mit 0 ≤ k ≤ n − 1 , falls das Pivotelement das (k+1)-kleinste Element ist. 1

2

3

a

5

6

7

8 k=123 und n-1-k=5678

T (0) = T (1) = 0 T (n) = (n − 1) + T (k) + T (n − 1 − k) Da k nicht bekannt ist, berechnen wir hier den schlimmsten Fall (worst case). Dieser tritt genau dann auf, wenn k = 0 oder k = n − 1 . Dies gilt, da bei Einsetzen: T (n) = (n − 1) + T (n − 1) = vgl. “Sortieren durch Auswahl” .

% & n · (n − 1) = O n2 2

Der Beweis, dass dies der worst case ist, kann durch vollständige Induktion erbracht werden: n · (n − 1) Dies hat ein Maximum bei k = 0 und k = n − 1 2 ⇒ Dies ist tatsächlich der schlimmste Fall. T (n) ≤

Wir wollen uns also gegen den worst-case absichern: Wähle das Pivotelement zufällig aus. k = 0, 1, . . . , n − 1 hat die jeweilige Wahrscheinlichkeit von

1 n

.

Die Laufzeit kann zwar nicht exakt bestimmt werden, jedoch kann der Erwartungswert berechnet werden.

21

1. Sortieralgorithmen

Erwartungswert der Anzahl der Vergleiche n−1 1S(n) = (n − 1) + (S (k) + S (n − 1 − k)) n S(n) =

k=0

Diese Gleichung soll vereinfacht werden. Wähle dazu nicht das “schlimmste k” aus, sondern wähle jedes k mit gleicher Wahrscheinlichkeit:

22

A4: Quicksort

S(n) = (n − 1) + 2 ·

n−1 1 · S(k) n

i) n · S(n) = n · (n − 1) + 2 ·

k=0 n−1 -

S(k)

k=0

Bilde darauffolgende Rekursionsgleichung ii)

ii) (n − 1) · S(n − 1) = (n − 1) · (n − 2) + 2 ·

n−2 -

S(k)

k=0

und bilde die Differenz n · S(n) − (n − 1) · S(n − 1) = (n − 1) · 2 + 2 · S(n − 1) | Stelle die Gleichung um 1 n · S(n) = (n + 1) · S(n − 1) + 2 · (n − 1) | ! "# $ n · (n + 1) ≤2n

S(n − 1) S(n) 2 ≤ + + 1$ n $ n+1 ! "# !n "# U (n)

U (n−1)

U (n) ≤ U (n − 1) +

2 n+1 =0

2 2 2 2 2 # $! " U (n) ≤ + + + . . . + + + U (1) n+1 n n−1 4 3  Hn+1  # $! " 4 5   1 1 1 1  = 2· 2· 1+  1 + 2 +3 + . . . + n + 1 − 2 ! "# $ ! "# $ nicht dabei daher wieder abgezogen Hn ≈ ln n (wächst gegen eine Konstante). Hn = O(log n)

U (n) ≤ 2 · Hn + 1 S(n) = U (n) · (n + 1)≤2 · (n + 1) · Hn+1 = O(n · log n)

23

1. Sortieralgorithmen

A5: ohne Bezeichnung Algorithmus Algorithmus 1.5 Sortieren, Ohne Bezeichnung Wiederhole k mal: Wähle zwei zufällige Indizes i, j ∈ {1, ..., n} Vergleiche ai und aj und vertausche sie, falls (i < j und ai > aj ) und (i > j und ai < aj ).

Frage dazu: Wie groß muss k gewählt werden? (Wird später beantwortet.)

Laufzeit Mit jeder Vertauschung wird ein “Fortschritt” gemacht, d.h. dass es nicht möglich ist, dass durch eine Vertauschung ein Rückschritt erfolgt. Also wird die Anzahl der Inversionen kleiner.

n · (n − 1) , ≥0 2 #Fehlstellen = 0 ⇒ Folge ist sortiert #Fehlstellen ≤

Wie viele Vorgänge sind notwendig, bis der Algorithmus eine Vertauschung macht? Sei V die Anzahl der Vergleiche (V = #Vergleiche), es handelt sich um ein Bernoulli- Experiment. P (erfolgreicher Versuch) =

#Fehlversuche · 2 2 ≥ 2 → nur noch eine Fehlstelle 2 n n

Es ist ≥, da auf die Reihenfolge geachtet werden muss und es wird angenommen, dass noch nicht sortiert ist. Nun wird der Erwartungwert für die Anzahl der Vergleiche berechnet: E(V ) =

1 n2 1 ≤ 2 = P (Erfolg) 2 n2

#Vertauschungen ≤

n · (n − 1) 2

E(#Vergleiche pro Vertauschung) ≤

n2 2

% & n2 n · (n − 1) n2 · n2 − n 1 · = = · n4 − n = O n4 2 2 4 4 Es ist%eine bessere & Analyse möglich, diese ist hier nicht gezeigt, diese ergibt jedoch, dass der Algorithmus in O n2 · log n Zeit läuft. E(#Schritte, bis die Folge sortiert ist) ≤

Es ist nicht möglich zu bestimmen, ob der Algorithmus tatsächlich terminiert.

Es wird k = 100 · n2 · log n gewählt, dies ist deutlich größer als der Erwartungswert. Die Wahrscheinlichkeit, dass die Folge nach diesen k Schritten sortiert ist, ist sehr groß.

24

Vergleich der Algorithmen

Vergleich der Algorithmen Algorithmus A1: bogosort A2: Sortieren durch Auswählen A3: Sortieren durch Verschmelzen A4: Quicksort A5: ohne Bezeichnung

Laufzeit worst-case Θ (n! % ·2 n) & Θ n Θ (n %· log& n) 2 %Θ2 n & O n · log n

Laufzeit im Mittel

Θ (n · log n) Θ (n · log n) keine Garantie für korrektes Ergebnis

1.0.1. Allgemeine Bemerkungen • Zufall kann für einen Algorithmus nützlich sein (z.B. Vermeiden des worst-case bei Quicksort) • Es gibt 2 Arten von randomisierten (probabilistischen) Algorithmen – Monte Carlo- Algorithmen ∗ Das korrekte Ergebnis ist garantiert (z.B. Quicksort). ∗ Die Laufzeit kann schwanken. – Las Vegas- Algorithmen ∗ Das Ergebnis ist mit hoher Wahrscheinlichkeit korrekt oder genähert korrekt

∗ A5 ist ein solcher Algorithmus

25

1. Sortieralgorithmen

26

Teil III.

Rechenmodelle

27

2. Arten von Rechnermodellen 2.1. Turingmaschine (Alan Turing, 1936) Eine Turingmaschine besteht aus einem beidseitig unendlichem Band, auf welchem Daten stehen. Dazu gehört eine Steuereinheit, welche die Daten auf dem Band liest und auf dieses schreibt. Es werden demnach die Daten interpretiert und verändert.

2.2. Registermaschine Allgemein Die Registermaschine (engl. Random-Access-Machine) wird u.a. folgendermaßen abgekürzt: RAM und besteht aus unendlich vielen Registern R0 , R1 , R2 , . . . . Jedes Register kann eine ganze Zahl z ∈ Z speichern.

Befehle In Klammern steht der entsprechende Assembler- Befehl. A A A A A

:= B + C (add) := B − C (sub) := B ∗ C (mul) := B/C (div) := B (sto)

A, B, C können sein: • Register, z.B. R50 • indirekt adressierte Register, z.B. (R3 ) (Wenn in R3 der Wert x steht, dann ist Rx gemeint) • Konstanten k ∈ Z (außer A)

Anweisungen • GOTO L (JMP) L ist die Sprungmarke der Anweisung • IF A > 0 GOTO L (BP) • HALT Beendet das Programm

29

2. Arten von Rechnermodellen 1 2 L: 3 4

A A A B .. .

:= A + B := B := 3 + A := A + B

Berechnung Ein Programm für die Registermaschine berechnet eine parallele Funktion f : U → Z∗ , U ⊆ Z∗

Z∗ ist eine endliche Folge von ganzen Zahlen. f (x1 , x2 , . . . , xn ) = (y1 , y2 , . . . , yn ) bedeutet: Die Registermaschine wird gestartet mit n in R0 und x1 , . . . , xn in R1 , . . . , Rn . Dann hält sie mit m in R0 und y1 , . . . , ym in R1 , . . . , Rm .

Programmierung Berechnung von n! mit einer Registermaschine: Die Berechnung von n! ist : n! = 1 · 2 · . . . · n

Wir wählen einen Algorithmus, der n herunterzählt: n! = n · (n − 1) · . . . · 1 S: IF

R2 R2 R1 R1 R1 HALT

:= := := >0 :=

2 R2 ∗ R1 R1 − 1 GOTO S R2

(wird auf eine Konstante gesetzt) (S: Schleifen-Marke)

(Ergebnis soll in R1 stehen)

Der Pseudocde für den obigen Algorithmus ist dieser: Algorithmus 2.1 Pseudocode RAM Eingabe n; f := 1; while n > 0 f := f · n; n := n − 1; print (f ); Der eine Code lässt sich direkt in den Anderen übersetzen.

Komplexität Die Komplexität (hier: Laufzeit und Speicherplatz) eines Programms für eine Registermaschine lässt sich auf verschiedene Arten bestimmen:

30

2.2. Registermaschine Einheitskostenmaß (EKM) Es wird angenommen, dass jede Operation ein Schritt in dem Programm ist, jeder Schritt kostet gleich viel. Bei dem obigen Programm zur Berechnung von n! wird O(n) Zeit benötigt, da es eine Schleife gibt, die n-mal läuft und dann noch konstant viele Schritte. Der Speicherplatz beim EKM ist gleich der Adresse der höchsten angesprochenen Speicherzelle. da diese eine obere Schranke bildet. Der Speicherplatz bei n! ist demnach O(1) .

Logarithmisches Kostenmaß (LKM) Eine Schwäche des EKM ist, dass nicht berücksichtigt wird, dass in einem Register unendlich lange Zahlen (die Zahlen werden durch Bits repräsentiert) stehen können. Bei dem LKM gilt: Der Zeitaufwand ist proportinonal zur Anzahl der beteiligten Bits. Der Zugriff auf eine Adresse oder ein Wert n ∈ Z zählt max {&log2 |n|' , 1} Zeiteinheiten. Beispiel: (in R1000 steht 5)

R10 : = (R1000 ) − 30

Kosten = &log2 10' + &log2 1000' + &log2 5' + &log2 30' = 4 + 10 + 3 + 5

Die Kosten betragen in diesem Beispiel 22 Einheiten. Der Speicherplatz ist die Gesamtanzahl aller Bits aller Werte und Adressen. Beispiel: In dem Beispiel werden die Rundungsklammern weggelassen!

31

2. Arten von Rechnermodellen

= + + .. .

log n + log (n · (n − 1)) + log (n · (n − 1) · (n − 2)) + . . . log n .

log n + log (n − 1) .

log n + log (n − 1) + log (n − 2) .. .

≤ n2 · log n

+

log n + log (n − 1) + log (n − 2) + . . . + log 2

=

n · log n + (n − 1) · log (n − 1) + . . . + 2 · log 2 ! "# $ n 2



'n 2

· log

% & n* n n2 n n2 · = · log2 = · (log2 (n − 1)) ≥ n2 log n · const. 2 2 4 2 4

% & ⇒ Θ n2 · log n

Der Speicherplatz ist log n! = Θ (n · log n). (Bemerkung: Es geht auch in (n · log2 n) Zeit, hier nicht gezeigt.) Beweis (log n! = Θ (n log n)) n! = n · (n − 1) · . . . · !"#$ 2 · !"#$ 1 ≤ nn ! "# $ ≤n

≤n

log2 n! ≤ log2 nn = n · log2 n

≤n

n ' n* 'n* 2 ≥ n! = n · (n − 1) · . . . · 2 · 1 ≥ !"#$ n · (n − 1) · . . . · n − "# $ ! 2 2 ! "# $ n ≥n 2

≥2

≥n 2

'n*n 2 = n · log n = n · (log (n − 1)) ⇒ Ω (log n) log n! ≥ log "# $ 2 2 2 2 ! Ω(log n)

!

Zusätzliches Insbesondere folgende Operationen sind in konstanter Zeit möglich: • Zugriff auf ein Feldelement a[i], ai . • Einen neuen Datensatz im Speicher ablegen und in eine verkettete Liste einfügen. Das Modell der Registermaschinen ist eine Abstraktion eines von heute gängigen realen Rechners, der in Assembler programmiert ist. Jedoch: Die Registermaschine hat im Gegensatz zu den realen Rechnern einen unbeschränkten Speicher, jedes Register kann eine beliebig (= unendlich) lange Zahl speichern.

32

2.3. Word- RAM

2.3. Word- RAM Diese Registermaschine besitzt Register fester Länge O(log n), wobei n die Eingabegröße ist. Ist es ein Widerspruch, dass die Register eine feste Länge haben, diese aber von der Eingabegröße abhängt? Nein. Eine Länge muss gegeben sein, z.B. die Addressierung benötigt dies. Historisch gesehen ist der Speicher immer weiter gewachsen, die Eingabegröße ist quasi fest, bis die Rechner sozusagen eine höhere Länge verkraften können und eine solche Zahl nötig wird. Jede Operation kostet eine Zeiteinheit. Im Weiteren wird zumeist die Analyse im EKM durchgeführt, mit dem Zusatzargument, dass die auftretenden Zahlen nicht zu groß sind. —— Beziehung zwischen Registermaschine mit LKM und Turingmaschine Ein Programm, das auf einer Registermaschine Eingaben der'Größe *n Bits im LKM in Zeit T (n) löst, kann auf einer Turingmaschine (mit einem Band!) in Zeit O T (n)3 simuliert werden.

Umgekehrt kann eine Turingmaschine mit Laufzeit T (n) auf einer Registermaschine mit Laufzeit O (T (n) · log (T (n))) im LKM simuliert werden.

(Das Band der Turingmaschine wird durch die Register simuliert. Das Band ist unendlich lang, die Anzahl der Register ist ebenfalls unendlich groß. Da die Turingmaschine sich keine Speicheradressen merkt, muss die spezielle Adressierung der Turingmaschine in der RAM implementiert werden, dies induziert den logarithmischen Faktor.) ——–

33

2. Arten von Rechnermodellen

34

Teil IV.

Sortieren II

35

3. Median finden Auswahl des k-kleinsten Wertes auf einer geordneten Menge von n Elementen. 12,

17,

3,

10,

2,

5, ↑

7

k=3

+n, n 3n ist der Median, ∼ und Spezialfall: k = sind die Quartile, dieses sind Anwendungen aus der 2 4 4 Statistik. Die primitive Variante, das gesuchte Element zu finden benötigt Θ (n · log n) Zeit. Es gibt jedoch auch einen Weg, der nur O(n) Zeit benötigt. QUICKSELECT → .

O(n) im Erwartungswert, randomisiert, einfach O(n) deterministisch (kompliziert, mit großem Laufzeitfaktor)

Algorithmus Algorithmus 3.1 Quickselect Select (L, n, k) mit (1 ≤ k ≤ n) // wähle das k kleinste Element aus einer Liste L mit n Elementen • Wähle ein Pivotelement a ∈ L 6 6 • Zerlege L = L< ˙ L= ˙ L> , je nachdem, ob x ∈ L die Bedingung x < a , x = 0 , x > a erfüllt. Fall 1 : Fall 2 : Fall 3 :

Select (L< , |L< | , k) print a Select(L> , |L> | , k − |L< | − |L= |) * ' n n Die Zerlegungen finden in linearer Zeit statt n + + + . . . ⇒ O(n) 2 4 Der worst-case ist genau dann, wenn k = 1 ist und das Pivotelement immer das größte Element ist. Dann führt die Rekursion von n auf n − 1. Das heißt, es gibt immer ein Select- Aufruf mit mindestens einem Element weniger. |L> | ≤ k |L< | < k ≤ |L< | + |L= | |L< | + |L= | ≥ k

⇒ T (n) =

O(n) +T (n − 1) ! "# $ Zerlegung % & = O n2 37

3. Median finden Um diesen worst-case zu umgehen, wird das Pivotelement für jede Zerlegung zufällig ausgesucht, vgl. mit Quicksort.

a) Pivotelement zufällig auswählen T (n) = Erwartungswert der Laufzeit bei einer Lister der Länge n (unabhängig von k) Annahme: Alle Elemente sind verschieden, also |L= | = 1 (Treten gleiche Elemente auf, so ist dies nur besser für den Algorithmus.) % & Das Pivotelement ist das i-kleinste Element 1 ≤ i ≤ n , jedes i hat die gleiche Wahrscheinlichkeit n1 . Sei dies eine Folge und das k-kleinste Element wird gesucht. Es wird zufällig ein i gewählt und anhand von Diesem wird entschieden, wie es weitergeht. Unten zu sehen: Es wird ein i < k, i = k und i > k gewählt (zufällig). Ist i = k, so ist k gefunden und der Algorithmus stoppt, ist i 1= k, so wird die Liste geteilt und die entsprechende Teilliste neu untersucht. i





– –

i

– – – – – – – i-1 – – – –   i = k fertig → HALT Fallunterscheidung = i > k rekursiver Aufruf mit kleinerer Menge, diese hat i − 1 Elemente   i < k rekursiver Aufruf mit größerer Menge, diese hat n − i Elemente –

– –

i ↑ k n-i –

  n 1 Zeit für den rekursiven Aufruf T (n) = O(n) + · "# $ ! n i=1 Mittelwert bilden

Nun spalten wir die Zeit für den rekursiven Aufruf auf, dieser variiert, welcher der beiden Fälle auftritt:

1 T (n) = O(n) + n





k−1  n  · T (n − i) + T (i − 1)    i=1  i=k+1 ! "# $ ! "# $ ik

Es soll nun gezeigt werden, dass [. . .] linear ist, also in O(n) liegt. Das Ziel ist demnach T (n) ≤ c · n zu beweisen, dies geht mit vollständiger Induktion. Zeit für rekursiven Aufruf ≤ T (max {i − 1, n − i}) n 1 T (max {i − 1, n − i}) T (n) ≤ c0 · n + · n i=1

38

a) Pivotelement zufällig auswählen

Nebenrechnung:

i−1 ≤ n−i

2·i−1 ≤ n

2·i ≤ n+1 n+1 i ≤ 2





  n+1  ( 2 ) n  1   T (n − $i) + T (i! − 1$) T (n) = c0 · n + ·   ! "# "# n   !! i=( n+1 +n i! i )   i=1 2 "# $ ! Grenzen vertauschen [. . .] =

n−1 -

i! =n−( n+1 2 )

% & T i! +

n−1 -

i!! =( n+1 2 )

% & T i!!

Induktionsannahme:

% & T i! ≤ c · i! % & T i!! ≤ c · i!!

(c wird später bestimmt)

1 T (n) ≤ c0 · n + n





    n−1 n−1   · c·i+ c · i    i=n− n+1 n+1 i= ( ) ( )   2 2 "# $ ! arithmetische Reihe

Fallunterscheidungen um Rundungsklammern zu entfernen.

Fall 1: n ungerade (unbedenklich, da immer n+1, bzw. n-1 gerechnet wird und dies per se gerade ist)

39

3. Median finden

T (n) ≤ c0 · n +



c  · n

n−1 -

i+

i=n−( n+1 2 )



n−1 -

i=( n+1 2 )

 i vgl. Glossar → Rechnen mit Summen

A % n−3 & % n−1 & % n+1 & % n−1 & B · · 2 n · (n − 1) n · (n − 1) c 2 − 2 + − 2 = c0 · n + · n 2 2 2 2   4 5  n−1  (n − 1) n − 3 n − 1 = n · (n − 1) + · +  = (n − 1) · n − 4 ! 2 "# 2 $ 4 =n−1 = 2n−2 2

= (n − 1) ·

4

3·n 4

5

=

3 · n2 − 3 · n + n − 1 3 · n2 − 2 · n − 1 = 4 4

Fall 2 : n gerade

2

obere Schranke $! " n−1 n−1  i+ i

= 3·n 4−2n ≤ 34 ·n2

T (n) ≤ c0 · n +

c · n

# 

i= n

i= n

! 2 "# 2 $ weiter bei (*) A %n& %n &B n · (n − 1) 2 · 2 −1 − 2· 2 2 C D 'n* 4n − 25 n 1 = n · (n − 1) − · =n· n−1− + 2 2 4 2 5 4 3·n 1 3 · n2 − 2 · n − = = n· 4 2 4

(∗)

Fortsetzung des Beweises:

T (n) ≤ c0 · n +

c 3 2 · ·n n 4

=

c0 · n +

! 3 ·c·n ≤c·n 4

⇔ c0 +

3 ·c≤c 4

⇔ c0 ≤

1 ·c 4

⇔ c ≥ 4 · c0 Setze c := 4 · c0 , dann geht der Induktionsbeweis durch.

40

b) deterministisch mit Laufzeit O(n) im schlimmsten Fall Satz: Die erwartete Laufzeit von Quickselect bei zufälliger Wahl des Pivotelementes ist O(n). Beweis: T (n) ≤ c0 · n + . . . nach n.

Wähle c = 4 · c0 und beweise T (n) ≤ c · n durch vollständige Induktion !

b) deterministisch mit Laufzeit O(n) im schlimmsten Fall • Zerlege die Liste L in Fünfergruppen.

• Berechne in jeder Fünfergruppe den Median. E F • Berechne den Median dieser n5 Mediane rekursiv.

• Dieser Median ist das Pivotelement.

Wenn n ≤ n0 , dann berechne den Median “direkt” (ohne rekursiven Aufruf), z.B. durch sortieren.



 Wieviele Elemente sind mindestens in Wieviele Elemente sind mindestens in

L< ∪ L= ? L> ∪ L= ?

|L< ∪ L= | ≥ |L< ∪ L= | ≥

—n!

5

/2 × 3 ≥

(n) ·3 10

(n) ·3 10

Die Größe der Liste schrumpft bei einem rekursiven Aufruf um mindestens 30%. Rekursion: T (n) ≤ c0 · n + T

'( n )* 5

' ( n )* +T n−3· 10

Zunächst: Als Vereinfachung ( ) weglassen (und für relle Zahlen zulassen) T (x) = maximale Laufzeit für Auswahl aus einer Liste der Länge ≤ x mit x ∈ R 4 5 'n* 7 ⇒ T (n) ≤ c0 · n + T +T ·n 5 10 ! "# $ schrumpfen auf 70% 41

3. Median finden Lemma: T (x)

erfülle die Bedingungen:

T : R>0 → R>0

T (x) ≤ c0 · x + T (α1 · x) + T (α2 · x) + . . . + T (αk · x) für x > n0

T (x) ≤ c1 für x ≤ n0 mit 0 ≤ αi und α1 + α2 + . . . + αk < 1

dann ist T (x) = O(x)

Beweis: α1 + α2 + . . . + αk = α

c := max

Behauptung:   x ≥ 1 für x ≤ n0   x > n0

G

c1 c0 , n0 1 − α

H

T (x) ≤ c · x T (x) ≤ c1 ≤ c1 · x T (x) ≤ c0 · x + c·α1 · x + c · α2 · x + . . . + c · αk · x = x · (c0 + c · (α1 + . . . + αk )) 4 5 stimmt nicht ! c0 1−α+α c0 ≤ x · c0 + · α = x · c0 · =x· ≤x·c 1−α 1−α 1−α

Zwar stimmt die Ungleichung nicht, jedoch kann die Rechnung im Folgenden angewendet werden:

T (x)



x · (c0 + c · α) ≤ c · x

⇔ c0 + c · a ≤ c

⇔ c0 ≤ c · (1 − α) ⇔ c ≥

c0 " 1−α

Die Induktion nach x ist nicht sauber. “Kleinstes Gegenbeispiel” Annahme: T (x) ≤ c · x gilt nicht für alle x. Setze x0 := inf {x |T (x) > c · x} ≥ n0 ∀ x < x0 gilt T (x) ≤ c · x

Behandeln des Abrundens: EnF 3 Wann ist n − 3 · 10 ≤ 4 ·n ? (n) 'n * ≤ n−3· −1 10 10 ! 3 7 +3 ≤ ·n = 10 4 n 3 ≤ 20 60 ≤ n

n−3·

(n) 3 ≤ ·n . 10 4 4 5 'n* 3 Für n ≥ 60 ist T (n) ≤ c0 · n + T +T ·n . 5 4 Für n > 60 ist n − 3 ·

42

b) deterministisch mit Laufzeit O(n) im schlimmsten Fall Für n ≤ 60 ist T (n) ≤ c1 .

Lemma: α1 + α2 =

1 5

+

3 4

=

19 20

a 5 m := r − l + 1 //Länge des Intervalls √ √ 6 Vergleiche a mit S [k − 1 · (( m) + 1)] , S [k − 2 · (( m) + 1)] √ bis S [k − i · (( m) + 1)] ≤ a √ 7 if S [k − l · (( m) + 1)] = a −→ fertig √ √ else QuadBinsuche (S, k − i · (( m) + 1) , k − (i − 1) · (( m) + 1) , a) 9 else analog suche nach rechts 10 else ’Nicht gefunden!! 1

Laufzeit √ T (n) = c + T ( n) + #Sprünge √ • wost case O ( n) • im Mittel:

Der Erwartungswert E ergibt die Anzahl der Vergleiche in Zeile 6. Pi ist die Wahrscheinlichkeit für mindestens i Vergleiche.

52







 

6.3. Quadratische Binärsuche Pi − Pi+1 ist die Wahrscheinlichkeit für genau i Vergleiche E=

∞ i=1

i · (Pi − Pi+1 ) = P1 − P2 + 2 · P2 − 2 · P3 + 3 · P3 − 3P4 + . . . =

∞ -

Pi

i=1

P P P P P P √ P P Falls der Algorithmus mindestens i Vergleiche macht: =⇒ P rg(a) −kP ≥ (i − 2) · m P ! "# $ P P P #S[j]≤a

Nun soll die Tschebyschew Ungleichung verwendet werden, dafür wird benötigt: • Zufallsvariabe X • Erwartungswert µ ' * • Varianz σ 2 = E (X − E(X))2 P (|X − µ| > t) ≤

σ2 t2

Xa = rg(a) a − S[l − 1] =P S[r + 1] − S[l − 1]

P (a[j] ≤ a) = a j = 1 . . . n für l ≤ j ≤ r P (S[j] ≤ a) = Die Wahrscheinlichkeit, dass genau q Elemente ≤ a :

µ = E(X) =

m q=0

σ

2

%m& q

· pq · (1 − p)m−q

4 5 m q· · pq · (1 − p)m−q = m · p q

= m · P · (1 − P )

⇒ Tschebyschew Ungleichung:

Pi ≤

σ2 t2

=

m · P · (1 − P ) √ 2 ((i − 2) · m) ≤ 41

=

# $! " m · P · (1 − P ) m · (i − 2)2 "# $ ! i≥3



1/4

(i − 2)2

für 1 ≥ 3

53

6. Suche in sortierten Listen

E=

∞ i=1

Pi ≤ P1 + P2 + ≤ 2+

∞ -

1/4

i=3

·

4

1 (i − 2)2

5

//j=i-2

∞ 1 π2 1 - 1 · = 2 + · ≈ 2, 41 4 j2 4 6 j=1

√ T (n) = T ( n) + d T (2) = b Behauptung: T (n) ≤ α · log log n, α : Konstante Induktionsafang: n = 4 , log log n = 1 α > T (4) Induktionsschritt:

T (n)



T

I.V. %√ & √ n + d ≤ α · log log n +d ! "# $ 1 ·log n 2

= =

α · (log log n − 1) + d

α· log log n für α ≥ d

für α ≥ max (b, T (4), d) gilt die Behauptung

⇒ Laufzeit im Mittel : O (log log n)

54

Teil V.

Rekursionsgleichungen

55

7. Das Master-Theorem

7.1. Hinleitung zum Master-Theorem

Im Weiteren werden Rekursionsgleichungen der folgenden Form betrachtet:

T (n) = a · T T (1) = θ(1)

'n* b

+ f (n)

a ≥ 1 b > 1 wäre b=1, würde T () keinen Fortschritt machen f (n) ≥ 0 Solch Rekursionsgleichungen treten häufig auf bei der Analyse von Divide & Conquer- Algorithmen. Beispiele: Mergesort :

T (n) = 2 · T

'n* 2

a=2b=2 Binäre Suche :

T (n) = 1 · T

Karatsuba :

T (n) = 3 · T

'n* 2

'n* 2

+n − 1$ ! "#

T (1) = T (0) = 0

+d

T (1) = c

+ O(n)

T (1) = c0

f (n)

Das Ziel ist es, ein “Kochrezept” für diese Rekursionsgleichungen zu erstellen. Dazu betrachten wir zunächst den Rekursionsbaum von T (n) = a · T

(einfacherhalber ist hier der Baum für a=3):

'n* b

+ f (n) mit T (1) = θ(1)

57

7. Das Master-Theorem

  





 









Wieviele Blätter hat dieser Baum? In jedem Schritt wird die Anzahl der Knoten mit a multipliziert, =⇒ alogb n Blätter Die Anzahl der Blätter im Rekursionsbaum ist daher nlogb a (zu zeigen mit Hilfe von den Logarithmusgesetzen, hier nicht gezeigt.) Gesamtkosten: Die Gesamtkosten sind die Kosten für die Blätter, sowei die Summe der Kosten der einzelnen Ebenen. Daraus folgt: b a)−1 'n* ' * (loglogb a aj · f j T (n) = θ n + b

j=0

Es lassen sich drei Aussagen über T (n), im Hinblick auf den Vergleich des Wachstums von machen. nlogb a 1.Fall: ∈ Ω (n" ) für ein " > 0 f (n) d.h. nlogb %a wächst & polynomiell stärker als f (n) log a b T (n) = θ n . 2.Fall:

f (n) = θ(1) nlogb a

% & f (n) ∈ θ logk n log a b n

3.Fall:

f (n) ∈ Ω (n" ) für ein " > 0 die Kosten der Wurzel dominieren. nlogb a

Hier muss noch eine Regularitätsbedingung gelten:

58

# Das Gewicht liegt in den Blättern ⇒

für ein k > 0

⇒ Kosten sind % gleichmäßig & auf den Ebenen verteilt. ⇒ T (n) = θ nlogb a · log n

f (n)/nlogb a

7.2. Anwendung des Master-Theorems

a·f

%n& b

≤ c · f (n) , 0 < c < 1 const.

⇒ T (n) = θ (f (n))

7.2. Anwendung des Master-Theorems Bestimme nlogb a und vergleiche mit f (n) und bestimme den Fall. 'n* Mergesort : T (n) = 2 · T + n−1 2 . → Fall 2 : T (n) = θ (n · log n) nlogb a = nlog2 2 = n1 7 Binäre Suche :

T (n)

=

1·T

'n* 2

nlogb a = nlog2 1 = n0 Karatsuba :

T (n)

nlogb a

T (n)

=

3·T

'n* 2

+

d .

=

17

+

O(n)

nlogb a = nlog2 3 ≈ n1,58 'n* + n3 = 4·T 2 . → Fall 3 = nlog2 4 ≈ 2 · n2 7

. 7



Fall 2 : T (n) = θ (log n)

& % & % → Fall 1 :θ nlog2 3 = O n1,58

Um zu Überprüfen, ob Fall 3 auch gilt, muss die Regularitätsbedingung überprüft werden: 'n* ' n *3 1 1 a·f =4· = · n3 = ·f (n) 0 0

d.h. f (n) ≤ d · nlogb a−" für eine Konstante d Also f

'n* bj

≤ d·

' n *logb a−" bj

Einsetzen in g(n) logb n−1

-

g(n) ≤

j

a ·

j=0

' n *logb a−" bj

logb n−1

= d·n

logb a−"

= d·n

logb a−"

-

·

j=0

aj ·

(b" )j aj

logb n−1

-

·

j=0

>1

(b" )logb n − 1 1 · " b" − 1 n

= d · nlogb a−" · = d · nlogb a ·

(b" )j !"#$

1 n" − 1 1 · " ≤d· " · nlogb a " b − 1 n b − 1 "# $ ! 1 ≤ b" − 1

% & 2. Fall f (n) = θ nlogb a obere Schranke also c1 · nlogb a ≤ f (n) < c2 · nlogb a .

Es gilt:

logb n−1

g(n) ≤ c2 ·

-

aj ·

j=0

' n *logb a b

logb n−1

-

aj ·

für ein " > 0 und a · f

'n*

= c2 · n

logb a

·

j=0

1 aj

' * = c2 · nlogb a · logb n ∈ O nlogb a · log n % & Untere Schranke g(n) ∈ Ω nlogb a · log n analog. % & 3. Fall f (n) = Ω nlogb a+"

b

≤ c · f (n)

mit 0 < c < 1

61

7. Das Master-Theorem aj · f

'n* bj

≤ cj · f

'n* bj

einsetzen in g(n):

logb n−1

g(n) =

j=0

cj · f (n) logb n−1

= f (n) ·

-

cj

j=0

≤ f (n) ·

∞ -

= f (n) ·

1 = O(f (n)) 1−c

cj

j=0

!

62

Teil VI.

Das Wörterbuchproblem

63

8. Datenstrukturen I Man möchte Datensätze speichern und über ihre Schlüssel auf sie zugreifen. Dazu werden Datenstrukturen benötigt, in welchen diese Datensätze verwaltet werden. Schlüssel

Daten

Grundoperationen: • Einfügen • Löschen • Suchen Die Schlüssel kommen aus einer geordneten Grundmenge U. Es soll noch weitere Operationen geben: • Finde den kleinsten vorhandenen Schlüssel ≤ a • Intervallabfragen (Finde alle Datensätze im Intervall [a, b] ) Datenstruktur

Einfügen/Löschen

Suchen

verkettete Liste sortiertes Feld (Array) Streuspeicherung (Hashtabelle) Suchbäume balancierte Suchbäume AVL-,Rot-Schwarz-,(a,b)-Bäume Balden (Treaps)

O(1) O(n) O(1) erwartet O(h) (h : Höhe) O(log n) O(log n) O(1)

O(n) O(log n) O(1) erwartet O(h) O(log n) O(log n) O(log n)

Anmerkungen → Binärsuche keine Intervallabfrage möglich

Suche im Erwartungswert

8.1. Streuspeicherung



 





Der Schlüssel s wird durch eine Hashfunktion h in einen Index i für den direkten Zugriff auf ein Feld der Länge N umgewandelt. h:U →Z

i = h(s) mod N

Es können Kollisionen auftreten, wenn einem Index zwei Datensätze (bzw. deren Schlüssel) zugeordnet werden. Eine Möglichkeit, um dieses zu vermeiden ist, dass die Datensätze in einer verketteten Liste gespeichert werden.

65

8. Datenstrukturen I 

 





Wenn die Hashfunktion die Schlüssel so umwandelt, dass die Indizes ungefähr gleichverteilt im n < c < 1 Intervall [0, N − 1] sind und wenn N ist, dann ist der Zugriff (Einfügen, Löschen, Suchen) in O(1) erwarteter Zeit möglich. Funktioniert auch in der Praxis. Der Belegungsfaktor α = 0,5 sein.

n N

sollte nicht höher als

8.2. Suchbäume 8.2.1. Binärer Suchbaum Suchbaum Eigenschaft: 

Für jeden Knoten v gilt: 

• alle Schlüssel im linken Teilbaum sind kleiner als v





• alle Schlüssel im rechten Teilbaum sind größer als v

Rotation Generelle Strategie: • Definiere eine strukturelle Eigenschaft, die garantiert, dass die Höhe O(log n) ist. 



• Beim Einfügen (Löschen) stelle durch Rotation sicher, dass die Eigenschaft wieder erfüllt ist.







 

8.2.2. AVL- Baum (nach Adelson-Velski und Landis) Eigenschaft: Für jeden Knoten gilt: Die Höhe des linken und rechten Teilbaumes unterscheiden sich höchstens um 1.

66







8.2. Suchbäume

8.2.3. (a,b)- Baum 





































• Jeder innere Knoten hat höchstens b und mindestens a Kinder. (Die Wurzel hat mindestens 2 Kinder) • Alle Blätter haben die gleiche Tiefe.

• Die Daten sind nur in den Blättern gespeichert.

• In den inneren Knoten sind nur die Schlüssel gespeichert, welche die Suche ermöglichen.

• Ein Knoten mit k Kindern hat k-1 Schlüssel. • Voraussetzung: a ≥ 2 und b ≥ 2 · a − 1

Die k-1 Schlüssel s1 , s2 , . . . , sk−1 zerlegen den Schlüsselbereich U in k Intervalle x < s1 , s1 ≤ x < s2 , . . . , sk−2 ≤ x < sk−1 x ≥ sk−1 die den k Kindern entsprechen.

Ein Beispiel am obigen Baum: Der kleinste Schlüssel im jeweiligen Teilbaum ist außen im linkesten Teilbaum. Ein (a,b)- Baum der Höhe h hat mindestens 2 · ah−1 und höchstens bh Knoten. Ein (a,b)- Baum mit n Blättern hat eine Höhe h ≤ 1 + log

n 2

= O (log n) (h ≥ logb n)

B- Baum (z.B. für externen Speicher) a = 1.000 n = 10.000.000 h ≤ 1 + log1.000 5 · 106 ⇒ h ≤ 3 ! "# $ =2

Das Suchen benötigt nur 3 innere Knoten und damit nur 2 Plattenzugriffe. Suchen in O(log n) Zeit. Einfügen Suche das Blatt, wo der neue Knoten hinkommen sollte und füge das Blatt dort ein. Der Elternknoten kann dadurch vorübergehend b+1 Kinder bekommen. In diesem Fall wird er in zwei Kinder zerlegt.

67

8. Datenstrukturen I Durch das Aufspalten des Knotens v kann dessen Elternknoten zu viele Kinder haben (b+1), dann muss dieser ebenfalls in 2 Knoten zerlegt werden, usw. immer eine Ebene hinauf, bis zur Wurzel. Wenn die Wurzel aufgespalten wird, wird eine neue Wurzel hinzugefügt. Die Schlüssel müssen ebenfalls angepasst werden. Die Laufzeit ist O(log n).























Löschen aus einem (a,b)- Baum 1. Das zu löschende Blatt suchen O (log n) . 2. Das Blatt entfernen. 3. Durch 2. kann der Elternknoten v vorübergehend zu wenige Kinder haben (a-1) 4. Fall 1: Elternknoten v hat einen Geschwisterknoten mit ≥ a + 1 Kindern

Eines dieser Kinder wandert zu v. Fertig. 5. Fall 2: v hat einen Geschwisterknoten mit a Kindern. Dann werden die beiden Knoten zu einem Knoten mit a + (a − 1) = 2 · a − 1 ≤ b Kindern zu einem Knoten vereinigt. Die Elternknoten v und v’ haben dadurch ein Kind verloren. Wenn v’ nicht die Wurzel ist und a − 1 Kinder hat, setze v := v ! und gehe zu 3. Wenn v ! die Wurzel ist und nur noch ein Kind hat, entferne die Wurzel. v wird die neue Wurzel.



 





68



























































8.2. Suchbäume Die Schlüssel der Knoten müssen nicht immer die kleinsten Werte der Teilbäume sein, es können auch gelöschte Schlüssel des Teilbaumes stehen bleiben. Beim Umbauen des Baumes auf korrekte Schlüssel achten! Fall 1 und Fall 2 sind nicht ausschließend. Es gibt viele Varianten. (a,b)- Bäume mit großen a, z.B. (a ≈ 100 − 1000) spielen bei Datenbanken eine große Rolle (vgl. B- Bäume). Intern können die k-1 Schlüssel auf irgendeine geeignete Weise gespeichert sein (sortierte Liste, AVLBaum, (2,3)- Baum). Satz: In einem (a,b)- Baum (2 ≤ a, b ≥ 2 · a − 1) kann man in O(log n) Zeit suchen, einfügen, entfernen. Idee: Die binäre Suche nach dem richtigen Kind direkt als Binärbaum darstellen → (2,4)- Bäume führen auf Rot- Schwarz- Bäume.

 

Jeder Knoten mit k = 3, 4 Kindern eines (2,4)- Baumes wird durch einen kleinen ausgeglichenen Binärbaum mit k Blättern und k-1 neuen inneren Knoten ersetzt. Die neuen Knoten heißen “rote”, die alten Knoten heißen “schwarze” Knoten.

Definitionen: Ein Rot-Schwarz- Baum is ein binärer Suchbaum mit zwei Arten von Knoten, rot und schwarz, der folgenden Bedingungen erfüllt: 1. Wurzel und alle Blätter sind schwarz. 2. Jeder Weg von der Wurzel zu einem Blatt enthält die gleiche Anzahl von schwarzen Knoten. 3. Jeder rote Knoten hat zwei schwarze Kinder. 4. Die Daten sind (üblicherweise gibt es aber Varianten) in den inneren Knoten und in den Blättern gespeichert. Beobachtung: Bis auf Punkt 4 entsprechen Rot-Schwarz- Bäume genau der Struktur von (2,4)- Bäumen.

69

8. Datenstrukturen I 





Der Umbau von Rot-Schwarz- Bäumen beim Einfügen und Entfernen wird durch Rotationen bewerkstelligt. Satz: Wenn man in einen zu Anfang leeren (2,3)- Baum n-mal ein Element einfügt, so benötigt das insgesamt O(n) Lauzeit + !Suchzeit "# $ ! "# $ O(n·log n) Umbau des Baumes Idee: Umbau ist nur dann erforderlich, wenn ein Knoten drei Kinder hat. → dann entstehen zwei neue Knoten mit je zwei Kindern. Wir veranschlagen eienen konstanten Aufwand pro Einfügeoperation. Wenn der tatsächliche Aufwand kleiner ist, dann kann die Ersparnis dazu verwendet werden, zukünftige Operationen, die mehr kosten, auszugleichen. → amortisierte Laufzeit Guthaben eines Baumes: Φ = #Grad 3 Knoten Annahme: Ein Knoten hat vorübergehend Grad 4 und es entstehen zwei neue Grad 2 Knoten. außerdem: • Ein Knoten steigt von Grad 2 auf Grad 3. Fertig. • Ein Knoten steigt von Grad 3 auf Grad 4 → wieder bei der Ausgangspositon. Bei jedem Schleifendurchlauf wird das Guthaben um 1 verringert, außer beim letzten Mal. veranschlagte Kosten für den Umbau: • eine Einheit für die Erhöhung von 2 auf 3 (einmal) • eine Einheit für das erstmalige Einfügen des Knotens Summe: 2 Einheiten Die übrigen Schleifendurchläufe sind bereits bezahlt, (als Guthaben des Baumes vorhanden). Danach ist das Guthaben um den entsprechenden Betrag reduziert. Verschmelzen von Listen verschiedener Länge ((2,3)-Bäume) Gegeben seien zwei sortierte Listen der Länge m und n (m < n) • O (m + n) Zeit

70

8.2. Suchbäume Es sei angenommen, dass die Listen bereits als Suchbäume vorliegen. Der Extremfall ist, wenn m = 1, n , dann O (log n) Zeit S O (m · log n) Elemente der kürzeren Liste in den Suchbaum der längeren Liste einfügen 2 Varianten: O (m + n) Ohne Suchbäume % & Es geht auch in O m · logm+1 n Zeit!   O (m · log2 n) m=1         Extremfälle:      O !"#$ m · logn+1 n = O(n) m = n    ! "# $  =n ≈logn n

Idee:

Die m sortierten Elemente nicht einzeln, sondern gemeinsam einfügen. Die Suche nach der neuen Einfügestelle beginnt nicht von Neuem bei der Wurzel, sondern beim Blatt der vorgehenden Einfügestelle, geht von dort nach onen in Richtung Wurzel, bis die neue Stelle gefunden ist, wo der neue Weg abzweigt. Erhofftes Ergebnis: Wenn m genügend groß ist, überlappen sich die Suchwege und die gemeinsamen Teile müssen nicht jedes Mal neu durchlaufen werden. Implementierung: Man merkt sich den Weg von der Wurzel zum aktuellen Knoten auf einem Stapel, sowie zu jedem Knoten das Intervall, für das der Teilbaum zuständig ist. Auf diese Weise kann man die nächste Abzweigungsstelle für den nächsten Weg finden. Gesamtzeit: Die Gesamtzeit für das Suchen von m sortierten Elementen im (2,3)- Baum mit n Elementen = O (# Kosten in der Vereinigung aller Wege von Wurzel zuden m Einfügestellen). h := höchste Ebene mit ≤ m Knoten





# Knoten in der Vereinigung ≤ # Knoten der Ebene 1 . . . h + m · (Weglänge von h bis zu den Blättern) "# $ ! n ≤log2 m/3



Die Suchzeit ist 4

n O m + m · log2 m/3

5





4 4 55 1   = O m + m · (log2 n − log2 m) + m · log2 3 = O m · 1 + log ! "# $ m

Einfügezeit (amortisiert) ... O(m)

O(m)

' n* insgesamt O m · log m

71

8. Datenstrukturen I Extremfälle: S ' ' m = 1 O (1 + log n) n ** O m · 1 + log → m m = n O (m · 1)

Zusammenfassung:

Das Vereinigen von 2 (2,3)- Bäumen mit m,n Elementen Wirf den kleineren (2,3)- Baum weg und füge seine Elemente in sortierter Reihenfolge in den Größeren ein. ' ' n ** amortisiert m ≤ n Laufzeit: O m · 1 + log m Die Laufzeit soll umgeschrieben werden, da bekannt sein muss, welcher Baum größer ist. Die Formel ist nicht symmetrisch. 4 5 % % && % % && (m + n)! = O log = O log m+n = O log m+n n m n! · m! log

(m + n)! n! · m!

(m + n) · (m + n − 1) · . . . · (n + 1) m · (m − 1) · . . . · 2 · 1

=

m-mal # $! " n · n · ... · n ≥ log · . . . · m$ !m · m "#

m-mal ' n *m n = log = m · log m m        n≥2·m        







   % 1 + log2 n  = O m · log2 O m ·     ! "# m$ ≥log2 2=1

n m

&

% % && = O log m+n n

            % %m+n&&   m · 1 + log2 n  = O(m) (∗)  m < n ≤ 2 · m O = O log n       m$   ! "#  ≤1

Nebenrechnung (*) 4 5 4 5 4 5 (m + n)! m+n n m+n m log (m + n)(m+n) en em log ≈ · n · m = log · ≥ log 2m = m m! · n! em+n n m n m "# $ ! ≥2

Dies ist die kleinste obere Schranke bei vergleichsbasierten Algorithmen.

Wenn man mit dieser Methode eine sortierte Liste der Länge n durch rekursives Verschmelzen von Teillisten beliebiger Größe und beliebiger Reihenfolge erzeugt, so geht das in O (log n!) = O (n · log n) Zeit. Beweis durch Induktion: Annahme: Endliste entsteht durch Verschmelzen von n1 und n2 Elementen mit n1 + n2 = n . Gesamtzeit:

72

8.2. Suchbäume 4

n! O log n1 ! + log n2 ! + log n1 ! · n2 !

5

= O (n!)

73

8. Datenstrukturen I

74

9. Amortisierte Analyse 9.1. Allgemeines Beispiel: Felder variabler Länge (in Java: Vector ) • Direkter Zugriff auf Elemente [i] in O(1) Zeit

• Feld lässt sich am Ende um ein Element verlängern Realisierung: “Vector” wird in einem Feld fester Länge gespeichert, z.B. mit einer Zweierpotenz. Wenn dieses Feld überläuft, dann wird ein neues Feld mit doppelter Länge angelegt und das alte Feld hinüberkopiert und der Speicherplatz freigegeben. n sei die aktuelle Länge und n! sei die tatsächliche Länge n! = 2"log n#

n ≤ n! < 2 · n

Zugriff: O(1) Zeit

S n < n! Verlängern um ein Element, n := n + 1 in n = n!

O(1) Zeit O(n) Zeit (⇒ n := n + 1 , n! := 2 · n! )

Hier wird nun eine Potentialfunktion eingeführt, diese hängt von der Datenstruktur ab, sie dient zur Analyse. Φ = 2 · n − n!

Φvor : Potential vorher, Φnach : Potential nachher

Es gilt: amortisierte Laufzeit einer Operation = tatsächliche Laufzeit - Φvor + Φnach

Verlängern um ein Element:  Φnach Φvor   # $! " %# $! "  % &  n < n! Tam = O(1) + 2 · (n + 1) − n! − 2 · n − n! & = O(1) + 2 = O(1)  n = n! Tam = O(n) + (2 · (n + 1) − 2 · n) − (2 · n − n) = O(n) −n = O(1)  ! "#+ 2$  ! "# $ ! "# $   Φ Φvor bezahlt O(n) nach

9.2. Methoden zur Bestimmung der amortisierten Laufzeit

Nehmen wir an, wir haben nur eine Art von Operationen P auf einer Datenstruktur. Wenn T (n) die Zeit für n aufeinanderfolgende Operationen ist, beginnend mit der leeren Datenstruktur, dann ist die amortisierte Zeit T (n) n pro Operation. Methode 1 zur amortisierten Analyse: Berechne die gesamte Laufzeit T (n). Methode 2:

75

9. Amortisierte Analyse Verwendung einer Potentialfunktion Φ, die von der der aktuellen Gestalt der Datenstruktur abhängt. TP = die tatsächliche Laufzeit der Operation P TP∗ = amortisierte Laufzeit TP − Φvor + Φnach Lemma: Wenn das Potential nie unter das Anfangspotential Φ0 sinkt, dann ist die amortisierte Laufzeit durch TP∗ beschränkt. Formeln: Φ0

−→ P1

Φ1

−→ P2

Φ2

−→ P3

Φ3 ...

−→ Pn

Φn

TP1 + TP2 + . . . + Tn

TP∗i = TPi − Φi−1 + Φi TP

TP1 + TP2 + . . . + Tn

= TP∗i + Φi−1 + Φi & % & % & % = TP∗1 + Φ0 − Φ1 + TP∗2 + Φ1 − Φ2 + · · · + TP∗n + Φn−1 − Φn % & = TP∗1 + TP∗2 + · · · + TP∗n + ΦP − Φn ! "# $ ≤0



TP∗1

+

TP∗2

+ ··· +

TP∗n

≤ n · TP

Die Einheiten von Φ sind “Laufzeit”, es präsentiert die angesparte Laufzeit. Eine Einheit von Φ reicht aus, um eine Operation mit konstanter Laufzeit zu bezahlen. Φ = (2 · n − n! ) · const  ! !  const − const · (2 · n − n ) + const · (2 · (n + 1) − n ) = 3 · const Tn→n+1 = const − const · (2 · n − n) + const · (2 · (n + 1) − n) = 2 · const  ! "# $ ! "# $  n

2

Einfügen in (2,3)-Baum

Φ = #Knoten vom Grad 3 Methode 3: Φ wird in der Datenstruktur “gespeichert” (andere Betrachtungsweise von Methode 2). Jeder Knoten vom Grad 3 hat einen Taler gespeichert. Einfügen in einen (2,3)- Baum kostet konstante Zeit + 1 Taler für den Elternknoten.









Der Temporärknoten vom Grad 4 hat 2 Taler gespeichert. Er bezahlt einen Taler, um den Knoten aufzuspalten und ein Taler wird an den Elternknoten weitergereicht.

76

9.2. Methoden zur Bestimmung der amortisierten Laufzeit Beispiel: Fibonacci- Halden haben eine amortisierte Laufzeit O(1) für die Einfügeoperation und O (log n), um das Minimum zu entfernen.



Das bedeutet, dass eine Folge von a einfüge- Operationen und b min-entfernenOperationen höchstens a · O(1) + b · O (log n) = O (a + b · log n) dauert. tatsächliche Zeit: Manchmal kann amortisierte Laufzeit in eine Laufzeitschranke für den schlechtesten Fall umgewandelt werden. Zum Beispiel durch Vorausarbeiten: 1. n =

n! 2

+1 

2.



Es wird auf beide “Bänder” parallel geschrieben. Der Aufwand verdoppelt sich über konstante Zeit. Dies ist wichtig für Echtzeit- Anwendung, z.B. ein Atomkraftwerk. Methode 4: Bei dieser Methode werden die globalen Beziehungen zwischen den Operationen ausgenutzt. #Schleifendurchläufe ≤ #Pop-Operationen = n

Die Laufzeit für alle Schleifendurchläufe = O(n)

77

9. Amortisierte Analyse

78

10. Vereinige-Finde-Problem (Union-Find) Gegeben sei eine endliche Menge S, diese bleibt unverändert. Dazu gilt o.B.d.A. : S = {1, . . . , n}

Partition von S S wird in disjunkte Teilmengen S1 , . . . , Sn zerlegt: ! ! ! 6 6 6 S = S1 S2 . . . Sn

  





 

10.1. Operationen





• Union (Si , Sj ) : Vereinige die Partitionen Si und Sj • Find (k) : k ∈ S, gib Si zurück mit k ∈ Si

10.2. Anwendungen 1. Zusammenhangskomponenten (z.B. maximale Anzahl disjunkter Teilmengen bestimmen) Algorithmus 10.1 Union-Find, max. Anzahl disjunkte Teilmengen finden Init Si = {i} für alle i ∈ V Für jede Kante e = (u, v) Si = Find (u) Sj = Union (v) Union (Si , Sj ) 2. minimale Spannbäume

3. Bildverarbeitung (Segmentierung eines Bildes) 4. Equivalence (x,y)

10.3. Realisierung durch eine Datenstruktur

79

10. Vereinige-Finde-Problem (Union-Find) Für jede Menge Si wird ein Baum mit Kind-Vater- Verweisen aufgebaut, dies ergibt insgesamt einen Wald. Die Wurzel des Baumes ist der “Repräsentant” der Menge.











Find(a): Folge den Verweisen, bis die Wurzel gefunden ist, gib die Wurzel zurück. Laufzeit: O(Höhe des Baumes) (zwischen O(1) und O(n) ) Union(i,j): (i,j : Wurzeln zweier Bäume)





Hänge i und seinen Baum an j an (Zeiger einfügen) Laufzeit: O(1) Beachte: Hänge den kleineren an den größeren Baum.





10.4. Höhenbalancierung • In den Bäumen wird die Höhe gespeichert und ggf. aktualisiert.

• Es wird immer der kleinere an den größeren Baum gehängt. Satz: Mit Höhenbalancierung gilt: 1. Laufzeit von Union ist O(1) 2. Laufzeit von Find ist O (log n) (wobei zu Beginn Si = {i} i = 1 . . . n)

Beweis:

1. Union: Speichern der Höhe und Aktualisierung: O(1) % & 2. Jeder Baum mit k Kindern hat die Höhe k ≤ log2 k k ≥ 2h

Induktion über k I.A.: I.V.: I.S.:

k = 1 → Höhe 0 → 1 ≥ 20

Baum mit k! ≤ k − 1 Knoten hat Höhe h! ≤ log2 k! ! 6 Baum mit k Knoten T = T1 T2 mit k1 , k2 Knoten haben Höhe h1 , h2 vor der Vereinigung gehabt. o.B.d.A.: h1 ≥ h2 , k = k1 + k2 , k1 ≥ 1 , k2 ≥ 1 h ≤ max (h1 , h2 + 1) I.V. (i) h = h1 k = k1 + k2 ≥ 2h1 = 2h I.V. (ii) h = h2 (k1 = k2 ) k = k1 + k2 ≥ 2h1 + 2h2 = 2 · 2h2 = 2h !

80

10.5. Pfadkompression

10.5. Pfadkompression Beim Einfügen von v werden alle traversierten Knoten direkt an die Wurzel angehängt. Funktion F, G : N → N



G(n) = min {k|F(k) ≥ n}



# F wächst sehr schnell, G wächst sehr langsam. F(i) 1 2 4 16 65536

n 1 2 3,4 5..16 4..65536





F(0) = 1 , F(i) = 2F (i−1) ∀ i ≥ 1

i 0 1 2 3 4













G(n) ∈ lg (n) 0 1 2 3 4



Jede Menge ist ein Baum und wird als solcher dargestellt. Die Wurzel ist der sogenannte Repräsentant der Menge. Die beiden Bäume werden vereinigt, in dem der kleinere Baum an den größeren Baum gehängt wird. Es wird ein Zeiger gesetzt. Dadurch wird der kleinere Baum zu einem Teilbaum des Größeren. Bei der Pfadkompression werden die Kinder an die Wurzel gehängt.

10.6. Knotenrang Zwar hängen die Kinder an der Wurzel, ab der nächsten UNION- Operation aber nicht mehr! Rang eines Knotens ist die Höhe des Knotens, wenn man keine Pfadkompression anwenden würde. Dieser ist im Knoten gespeichert. Am Anfang hat jeder Knoten den Rang 0. Bei der Vereinigung werden beide Wurzelknoten betrachtet, diese haben jeweils den Rang r1 r2 .   r1 > r2 hänge r2 als Kind an r1 (Baum mit Wurzel r2 ) Vereinigen : r1 < r2 hänge r1 als Kind an r2 (Baum mit Wurzel r1 )   r1 = r2 hänge r2 als Kind an r1 und r1 := r1 + 1

Der Rang kann so lange steigen, solange ein Knoten eine Wurzel ist, danach bleibt der Rang konstant. Der Rang des Elternknotens von v ist größer als der Rang von v. Diese Eigenschaft bleibt bei der Pfadkompression erhalten. Rang (Eltern von v) > Rang (v)

81

10. Vereinige-Finde-Problem (Union-Find)

10.6.1. Beobachtung • Ein Baum mit Wurzel vom Rang r hat mindestens 2r Knoten. Des lässt sich aus der Vereinigungsregel durch Induktion beweisen. (Der Rang steigt nur, wenn zwei Wurzeln bei Vereinigung den gleichen Rang haben.) • Es gibt höchstens

n 2r

Kinder vom Rang r.

• Der höchste Rang, der auftritt, ist ≤ log2 n

10.6.2. Einschub: Turmfunktion (Potenzturm) 22

F (i) = 22

T

i

rekursiv definiert als 2F (i−1)

F (0) = 1 F (1) = 2

Umkehrfunktion:

G(n) = min {i|n ≤ F (i)}

= log∗ n     = min i| log2 log2 . . . log2 n ≤ 1 "# $  !  i

F (0) = 1 F (1) = 2 F (2) = 4 F (3) = 16 F (4) = 65536 F (5) = 265536 65536

F (6) = 22

Daraus lässt sich erkennen, dass die Turmfunktion ziemlich schnell wächst, Die Umkehrfunktion heißt log∗ , diese Funktion wächst unvorstellbar langsam. Satz: Eine Folge von m UNION-FIND- Operationen auf einer Grundmenge von n Elementen dauert mit Vereinigung nach Rang und Pfadkompression O ((m + n) · log∗ n) Zeit. Im Folgenden wird die Menge wird in Ranggruppen unterteilt: Gruppe g = {r ∈ N|G(r) = g} = {F (g − 1) + 1, . . . , F (g)} 0

1

0

2 1

3

4

2

5

6

7

...

16

17

3

10.7. Analyse einer FIND- Operation

82

65536

... 4

... 5

... ...

10.7. Analyse einer FIND- Operation  

          

Die Knoten, die besucht werden, werden in zwei Klassen geteilt: Typ 1:

Knoten v mit G(Elterm(v)) > G(Rang(v)) außerdem Wurzel und vorletzter Knoten (Diese knoten werden mit der FIND- Operation gebucht)

Typ 2:

alle übrigen Knoten (Diese Besuche werden aud dem Knoten v gebucht.)







# Typ 1- Knoten einer FIND- Operation ≤ höchstens Ranggruppe + 2 ≤ G (log2 n) + 2 = G(n) − 1 + 2 = O (G(n)) insgesamt Typ 1- Operationen: O(m · G(n))

Typ 1:

Betrachte feste Knoten v. Was passiert mit dem Rang des Elternknotens bei den Typ 2- Besuchen? Dieser steigt mindestens um 1. Bei einem Typ 2- Besuche erhöht sich der Rang des Elternknotens um ≥ 1 (Der Rang des Elternknotens eines Knoten v mit Rang r muss in derselben Ranggruppe liegen.) Die Anzahl der Typ 2- Besuche ist ≤ der Anzahl der Ränge in der Ranggruppe g = F (g) − F (g − 1) ≤ F (g) # Typ 2- Besuche eines Knotens in Ranggruppe g ≤ F (g)

F (g)

Gesamtzahl aller Knoten in Ranggruppe g ≤ ≤ da 2r = 2F (g−1)+1

-

r=F (g−1)+1 ∞ -

r=F (g−1)+1

n 2r n 2r

Summe auflösen = n·

1 2F (g−1)+1

4

5 1 1 · 1 + + + ... 2 4 ! "# $ =2

=

n 2F (g−1)

=

n F (g)

Die Gesamtzahl aller Typ 2- besucher aller Kinder in der Ranggruppe ist ≤

n ·F(g)=n F (g)

Die Gesamtzahl aller Typ 2- Besuche ist ≤ n · (#Ranggruppen) ≤ n · [G (log n) + 1] = n · G(n) Summe: Typ 1- Besuche + Typ 2- Besuche : O (m · G(n) + n · G(n)) = O ((m + n) · G(n))

Ackermann- Funktion (Dies zeigt nur eine mögliche Variante der Ackermann- Funktion.)

83

10. Vereinige-Finde-Problem (Union-Find) A(i,j) i=0 i=1 i=2 i=3 i=4

j=0 0 1 1 1 1

j=1 2 2 2 2 2

j=2 4 4 4 4 4

j=3 6 8 16 65536 F(65536)

j=4 8 16 65536 F(65536) ...

j=5 16 32 265536 ... ...

=2·j = 2j = F (j) (wie oft wird F() angewendet) ... ...

a:N×N→N

Die Funktion ist induktiv definiert:

A(0, j) = 2 · j

A(i, 0) = 1 (i ≥ 1)

A(i, j) = A (i − 1, A(i, j − 1))

A(1, j) = 2j

A(2, j) = F (j) A(3, j) = F (F (F (F (F (1))))) "# $ ! j-mal

Die Ackermann- Funktion ist ein Beispiel einer nichtprimtivrekursiven Funktion. Inverse Ackermann- Funktion Die Umkehrfunktion der Ackermann- Funktion ist folgendermaßen definiert: α (n) := min {i|A (i, 3) ≥ n}

Es gilt außerdem die Schranke O ((m + n) · α(n)) für UNION-FIND mit Pfadkompression und in einem gewissen Bereich (falls m = O(n) ist) ist diese Schranke scharf. Randbemerkung: Die inverse Ackermann- Funktion tritt auch in anderen kombinatorischen Fragestellungen auf. Insbesondere in der Geometrie.

84

Teil VII.

Algorithmen-Entwurfsprinzipien

85

11. Dynamische Programmierung/Optimierung Bei dem dynamischen Programmieren geht es um das systematische Lösen von Teilproblemen. Das Prinzip der dynamischen Programmierung wird im Folgenden am Beispiel von optimalen Suchbäumen demonstriert.

11.1. Optimaler binärer Suchbaum Gegeben: n Schlüssel a1 < a2 < · · · < an

Zugriffshäufigkeit p1 , p2 , . . . , pn auf a1 , . . . , an q0 , q1 , . . . , qn für die Intervalle (−∞, a1 ) , (−a1 , a2 ) , . . . , (an , +∞) Gesucht: Ein binärer Suchbaum, der die erwartete Suchzeit minimiert. Bsp.: n = 3 p1 = 0, 1 p2 = 0, 2 p3 = 0, 3 q0 = q1 = q2 = q3 = q4 = 0, 1 











Daraus lassen sich viele binäre Suchbäume erschaffen, ein Beispiel wäre dieser:

11.1.1. Suchkosten Die Suchkosten sind die Weglängen im Suchbaum. (Es werden die Anzahl der Kanten gezählt, eigentlich müsste man die Knoten auf dem Weg zählen, aber die Addition von 1 ändert die Zielfunktion z nur um eine Konstante.)

87

11. Dynamische Programmierung/Optimierung Die Kosten vom obigen Baum sind wie folgt: 2 · 0, 1 + 1 · 0, 1 + 2 · 0, 1 + 0 · 0, 2 + 0, 2 + 0, 1 + 0, 2 + 0 + 0, 2 + 0, 3 + 0, 2 = 1, 2 Nun wird ein weiterer möglicher Baum betrachtet und dessen Kosten bestimmt: 

   





Kosten = 0, 1 + 0, 1 + 0, 4 + 0, 2 + 0, 3 + 0, 3 = 1, 4 Zielfunktion: erwartete geichtete Weglänge n i=1

pi · Tiefe (bi ) +

n i=0

qi · Tiefe (bi )

b1 , b2 : Blätter, die den Intervallen zwischen den gespeicherten Werten entsprechen. Teilproblem Tij (1 ≤ i ≤ j ≤ n) Das Teilproblem mit j − 1 + 1 Elementen ai , ai+1 , . . . , aj und Häufigkeiten p1 , . . . , pj und Intervallen qi−1 , . . . , qj T2,3 :





 

Bemerkung:



U

pi +

U

qi nicht unbedingt = 1

Optimalitätsprinzip (Bellmann, 1957) “Die Teillösungen einer optimalen Lösung müssen optimale Lösungen für Teilprobleme sein.” Satz: Bij sei ein optimaler Suchbaum für Tij , am ∈ {ai , . . . , aj } sei die Wurzel, dann ist der linke/rechte Teilbaum optimal für Ti,m−1 , bzw. Tm+1,j . Beweis: z ist die Zielfunktion, s.o. und B l und B r sind die Teilbäume.

88

11.1. Optimaler binärer Suchbaum

z (Bij ) = pm · 0 m−1 -

+

k=i

pk · Tiefe (ak ) +

j -

+

k=m+1 m−1 -

=

k=i

m−1 -

k=i−1

pk · Tiefe (ak ) +

qk · Tiefe (bk )

j -

k=m

qk · Tiefe (bk )

m−1 * - V W l r pk TiefeB (ak ) + 1 + TiefeB (bk + 1)

'

k=i−1

+ ... j j m−1 = pk + pk + qk k=i

k=m+1

m−1 -

+

k=1

pk · Tiefe

j -

+

Bl

k=m+1

k=m−1

(ak ) +

m−1 -

k=i−1

pk · Tiefe

Br

(ak ) +

l

ak · TiefeB (bk )

j -

k=m

r

qk · TiefeB (bk )

' * = const (abhängig von n) + z · B l + z · (B r ) Algorithmus: Berechnet in systematischer Reihenfolge die Optimallösungen zij für die Teilprobleme Tij , 1 ≤ i ≤ n + 1 , i − 1 ≤ j ≤ n mit Kosten zi+1,j = 0

Berechnung von Tij mit i ≤ j :

Wurzel = am i ≤ m ≤ j (alle Werte durchprobieren)

für jedes m = i , i + 1 , j

berechne

m−1 -

pk +

k=i

!

j -

pk +

k=i

"#

(pk − pm )

qk + zi,m−1 + zm+1,j

k=i−1

k=m+1

j -

j -

$

rij = dasjenige m, das das Minimum ergibt zij = der Wert des Minimums s Pij

=

j k=1

pk +

j -

qk

k=1

min (zi,m−1 + zm+1,j − pm ) + Pij

i≤m≤j

89

11. Dynamische Programmierung/Optimierung q0 0, 1

p1 0, 1

q1 0, 1

p2 0, 2

q2

p3 0, 3

0, 1

q3 0, 1

Ti,j

j=0

i=1

0

j=1 r=1 0, 2

i=2

0

i=3

j=2 r=2 0, 6 r=2 0, 2 0

i=4

j=3 r=2 1, 2 r=3 0, 3 r=3 0, 2 0

Berechnungen: T1,1 :

m = 1 P1,1 = 0, 3 z = 0, 3 − 0, 1 = 0, 2

T1,2 :

m = 1 P1,2 = 0, 6 z = T1,0 + T2,2 − 0, 1 + 0, 6 = 0 + 0, 2 − 0, 1 + 0, 6 m = 2 z = T1,1 + T3,2 − 0, 2 +0, 6 = 0, 2 + 0 − 0, 2 + 0, 6 !"#$ p2

T2,3 :

m = 2 P2,3 = 0, 8 z = T2,1 + T3,3 − 0, 2 + Pij = 0 + 0, 2 − 0, 2 + P m = 3 z = T2,2 + T4,3 − 0, 3 + Pij = 0, 2 + 0 − 0, 3 + P

...

...

Aus der Tabelle lässt sich nun der optimale Baum erstellen:

Die systematische Reihenfolge ist nicht eindeutig vorgegeben. Es sollen die “kleineren” Teilprobleme vor den “größeren” Teilproblemen gelöst werden, die auf den Kleineren aufbauen. z.B. • diagonalerweise (nach wachsendem j − i) • zeilenweise von unten nach oben

90

11.1. Optimaler binärer Suchbaum Algorithmus 11.1 Dynamische Optimierung, optimaler Suchbaum Vorverarbeitung: Berechne Pj =

j -

pk +

k=1

Dies geht in O(n) Zeit.

j -

qk

k=0

for i = n + 1 , n , n − 1 , . . . , 0 : zi,j−1 := 0 for j := i, i + 1 , . . . , n : min (zi,m−1 + zm+1,j − pm ) + Pj − Pi−1 + qi−1

i≤m≤j

rij := das m, bei dem das Minimum angenommen wurde zij := der Wert des Minimums

% & Hier gibt es 3 geschachtelte Schleifen, daher beträgt die Laufzeit: O n3 .

Der optimale Baum kann durch Zurückverfolgen der Werte rij bestimmt werden.

11.1.2. Zusammenfassung Teilprobleme Tij optimaler Baum für ai , ai+1 , . . . , aj mit einer entsprechenden Häufigkeiten. Rekursionsgleichung min (zi,m−1 + zm+1,j − Pi ) · Pij

zij

=

zi+1,i

=

0

zi,m−1 und zm+1,j

:

Lösung der kleineren Probleme

Pi und Pij

:

bekannt

i≤m≤j

zi,n → Lösung des Gesamtproblems Laufzeit % & n Möglichkeiten für i, j, m → O n3 Verbesserung der Laufzeit

rij = der Wert von m, bei dem das Minimum angenommen wird.

91

11. Dynamische Programmierung/Optimierung Es gilt rij ≤ ri,j+1 ≤ ri+1,j+1 (ohne Beweis) r2/6 ≤ r2/7 ≤ r3/7 • Der Wert von rij muss nur im Intervall von [ri,j−1 , ri+1,j ] gesucht werden.

% & • Die Gesamtlänge der Intervalle zum Suchen von r1 , k, r2 , k+1, r3 , k+2 ist nicht nur n·n = O n2 , sondern nur noch O(n) ≤ (2 · n)

Gesamtlaufzeit % & % & O n2 statt O n3 .

Anmerkung:

Warum wird nicht der Huffman-Algorithmus mit der Laufzeit O (n · log n) verwendet? Weil bei diesem Algorithmus die Blätterreihenfolge nicht gegeben ist. Falls qi = 0 ist, gibt es nich einen Algorithmus, der in O (n · log n) funktioniert.

11.2. Kürzeste Triangulierung eins konvexen Polygons Gegeben: Eine Menge von nichtkreuzenden Diagonalen. Definition Triangulierung: Zerlegung in Dreiecke durch n−3 nichtkreuzende Diagonalen (Strecken zwischen zwei Ecken durch das Innere des Polygons). Gesucht: Triangulierung mit kürzester Gesamtlänge. Tij : kürzeste Triangulierung des Polygons Pi , Pi+1 , . . . , Pj

11.2.1. Dynamischer Ansatz Tij ist die kürzeste Triangulierung des Polygons Pi , Pi+1 , . . . , Pj Diese Triangulierung besteht aus einem Dreieck Pi , Pj , Pm plus optimale Triangulierungen von Ti,m und Tm,j . zij = Länge der optimalen Triangulierung zij = min zi,m + zm,j + 9Pi − Pm 9 + 9Pm − Pj 9 i≤m≤j

zi,i+1 := − 9Pi − Pi+1 9 (Dadurch wird ausgeglichen, dass die Seite Pi , Pi+1 nicht gerechnet werden soll.) zi,i+1 +zi+1,m + 9Pi − Pi+1 9 + 9Pi+1,m 9 ! "# $ ! "# $ =0

=0

zi,n = Gesamtlösung. % & Laufzeit = O n3 , da drei Schleifen über i, j, m. 92

(1 ≤ i, i + 2 ≤ j ≤ n)

11.3. Rucksackproblem

11.3. Rucksackproblem Gegeben: n Gegenstände mit g1 , . . . , gn Gewichten und Wert w1 , . . . , wn und einem zulässigen maximalen Gesamtgewicht G. Gesucht: Eine Teilmenge X ≤ {1, . . . , n} mit

-

i∈X

gi ≤ G

mit maximalen Gesamtwert -

i∈X

wi → M AX!

Beispiel: i

1

2

3

4

g w

2 6

3 8

4 7

7 G=10 13

Teilprobleme: Tkg = maximaler Wert mit X ∈ {1, . . . , k} und Gesamtlaufzeit < g (nicht G) k := 0, 1, . . . , n g := 0, 1, . . . , G         zkg = max , zk−1,g−gk + wk zk−1,g  ! "# $ ! "# $     genommen nicht genommen z0,g (g > 0) := 0

zk,g (g < 0) := 0 z1,g = max {z0,g , z0,g−2 + 6} z2,g = max {z1,g , z1,g−3 + 8}

Zustandsgraph Dieser sogenannte Zustandsgraph der Rekursion hat einen Knoten für jedes Teilproblem. Kanten von T nach T ! mit Gewicht cT,T , wenn sich aus der Lösung T eine mögliche Lösung T ! ergibt, wenn man Kosten cT,T ! dazuaddiert.

93

11. Dynamische Programmierung/Optimierung Jede “Lösung” entspricht dann einem Weg von einem “Startknoten” zu einem “Zielknoten” im Graphen.



Kosten = ˆ Gesamtgewicht des Weges.



In unserem Beispiel ist die erste Spalte der Start und Tn,G das Ziel. Werte in Knoten sind der längste Weg vom Startknoten zu diesem Knoten.









 

 









Der Graph ist azyklisch. Laufzeit: O (n · G) Speicherbedarf: O (n · G) Zwar kann man auch immer nur zwei aufeinanderfolgende Spalten speichern, damit kann aber nur der optimale Wert bestimmt werden und nicht die Lösung.

11.4. Die optimale Stadt (Manhattan Problem) Gegeben: n∈N Gesucht: Teilmenge S ⊆ {1, 2, 3, . . . }2 |S| = n In jeder Zeile i ∈ N > 0 sind die ersten ri Punkte (i, 1) , (i, 2) , . . . , (i, ri ) belegt, mit ri ≥ 0 r1 ≥ r2 ≥ r3 ≥ . . . U ri = n

Ziel:

1 · 2

- %P P P P& Pi − i! P + Pj − j ! P → min

(i,j)∈S (i! ,j ! )∈S

= Gesamtsumme der Abstände zwischen allen Paaren von Punkten in der Manhattan-Matrix.

11.4.1. Dynamische Programmierung: Die optimale Stadt wird zeilenweise von unten aufgebaut.

erster Ansatz Optimale Stadt mit k Zeilen, m Blöcken und vk = r → Tm,k,r,u , wobei die Summe aller Abstände der m − k · r Punkte rechts von Spalte r vom Punkt (r, k) gleich v ist.

94

11.4. Die optimale Stadt (Manhattan Problem) 



zm,k,r,u = optimale Kosten einer Teilstadt

11.4.2. Rekursion Baue eine Stadt mit k + 1 Zeilen aus einer Stadt mit k Zeilen. X T zm,k+1,r,u! = min! zm−r! ,k,r,uneu (uneu : Zusatzkosten der neuen Zeile) r≥r

Zusatzkosten: k1 + k2

k1 = Abstand innerhalb der neuen Zeile r! r! |i − j| = 1/2 · i=1 j=1

   r! r! i  |i − j| = 1/2 ·  |i − j| + i=1

=

j=1

j=1

r ! · (r ! − 1) · (r ! + 1) 6

k2 = Abstände zwischen der neuesten oberen Zeile und den ersten k Zeilen u − uneu = Abstände aller Punkte rechts von der Spalte r ! vom Punkt (r ! , k + 1) minus der Abständer aller Punkte von Spalte r von Punkt (r, k). = (m − r ! − k · r) · Distanz von (r ! , k + 1) zu (r, k) (Distanzänderung der alten Punkte) + Summe der Distanzen der (r − r ! ) · k neuen Punkte zu (r ! , k + 1) ← Formel. Formel: U U x- Abstände + y- Abstände -

x-Abstände =

! r−r -

i=1

y-Abstände = u − uneu =

i·k =

(r − r ! ) · (r − r ! + 1) ·k 2

& k · (k + 1) % · r − r! 2

%

& % & (r − r ! ) · k % & m − r! − k · r · r − r! + 1 + · r − r! + k + 2 2 95

11. Dynamische Programmierung/Optimierung

 

k2 = Abstände zwischen oberster Zeile und den m − (k + 1) Punkten rechts (← k2,1 ) + Abstände zwischen obersten Zeilen und dem r ! × k- Rechteck darunter (← k2,2 ) k2,1 = Abstand von p zu p! = 9p − p! 91 − 9p − (r ! , k + 1)9 − 9(r ! , k + 1) − p9 !

k2,1 =

r %

& & % r ! − i × m − (k + 1) · r ! + u · r !

!i=1 "# $ r ! · (r ! − 1) 2

k2,2 =

U

x- Abstände +

U

y- Abstände !

k2,2 =

!

r r i=1 j=1

|i − j| · k + r 2 ·

k j=1

!

(k + 1 − j)

"# $ k · (k + 1) 2

11.4.3. Rekursionsgleichung zm,k+1,r,u = minr≥r! {zm−r! ,k,r,u−(m−r! −k·r)(r−r! +1)−(r−r! )·k·(r−r! +k+2)·1/2 r ! (r ! − 1) · (r ! + 1) r ! · (r ! + 1) + + 6 2 4 5 ! (r ! − 1) · (r ! + 1) % & r ! ! · n− n+1·r +u·r + 3 H % ! &2 k · (k + 1) ! r ≤r≤n ·k + r · 2

zm,k,r,u = ∞ (’undefiniert’) für m < 0 oder m > n, für k > n, für r > n, für u < 0, u > 2 · n2 Ausgangswert: z0,0,n,0 = 0 Y Z Endlösung: min zn,k,r,u : 0 ≤ k ≤ n, 0 ≤ r ≤ n, 0 ≤ u ≤ 2 · n2 Laufzeit:

0 0 0 0

96

≤ m ≤ n ≤ k ≤ n ≤ r ≤ n ≤ u ≤ 2 · n2

      

% & O n5 Werte

11.5. Hamiltonkreise im Graphen

r ! ≤ r ≤ n O(n) Zeit für jeden Wert % & ⇒ O n6

Speicher:

% & O n5

11.5. Hamiltonkreise im Graphen Gegeben: k × n- Gitter

Knoten V = {1, 2, . . . , n} × (1, 2, . . . , k)

Die Knoten (i, j) und (i! , j ! ) sind benachbart, wenn gilt: |i − i! | + |j − j ! | = 1

Ein Hamiltonkreis ist ein Kreis (ein geschlossener Kantenzug), der jeden Knoten genau einmal besucht.

 

5 × 6 - Gitter

Gesucht:

Die Anzahl der Hamiltonkreise auf dem 4 × n- Graph (n ∈ N)

 

Teilprobleme: Die Teilprobleme sind die “Teilkreise” auf den ersten j Spalten. Teillösungen: Betrachtung eines Hamiltonkreises, der auf den ersten Spalten eingeschränkt ist. Die Teillösung besteht aus mehreren Wegen, die Enden der Wege müssen in Spalte j sein.

Jede Teillösung wird in ein “Muster” (“Zustand”) klassifiziert, je nachdem, welche Knoten in Spalte j Endknoten von Wegen sind und wie diese durch die Wege mindestens verbunden sind.

97

11. Dynamische Programmierung/Optimierung

Das Muster

ist ausgeschlossen, die Wege würden sich kreuzen!

Teilprobleme bei der dynamischen Programmierung: zj,a = # Systeme von disjunkten Wegen, die im 4 × j- Gitter alle Knoten überdecken und dem Muster a entsprechen. Rekursion aufstellen: zj+1,’Muster a’ = Formel, in der zj,’Muster a’ vorkommen Matrix M  

                                                                       

ma,b = # Möglichkeiten, wie aus einer Lösung mit Muster a im 4 × j- Gitter eine Lösung mit Muster b im 4 × (j + 1)- Gitter durch Hinzufügen von Kanten entstehen kann.

98

11.5. Hamiltonkreise im Graphen





allgemeine Gestalt:

Rechenvorschrift der Matrix M :

zj+1,b =

a

zj,a · ma,b

&zj+1 = &zj · M

99

11. Dynamische Programmierung/Optimierung



Bei festen k ist die Laufzeit linear. Der Vektor mird mit der Matrix multipliziert. (Das Problem kann auch in logarithmischer Zeit gelöst werden.)

100

12. Der Greedy- Algorithmus Der Greedy- Algorithmus fällt eine Entscheidung auf Grund von lokalen Kriterien, ohne Rücksicht auf spätere Auswirkungen zu nehmen.

12.1. Rucksackproblem wi = 2, 1, 5, 3 0, 1 Variablen

gi = 8, 2, 5, 5 G = 11 S 0, Gegenstand iwird nicht gewählt xi = 1, sonst

Maximiere W

=

unter

n i=1 n i=1

xi · wi xi · gi ≤ G

xi ∈ {0, 1} Die “greedy”- Methode wäre z.B. die Folgende:

x1 = 1 x2 = 1 " Gewicht = 10 x3 = 0 (Gewicht wäre sonst 15> G) x4 = 0 W

= 3

Hier lernen wir die “erste Lektion”: Der Greedy- Algorithmus ist nicht immer optimal (in Bezug auf Optimallösung, nicht Laufzeit). Die Fälle, in denen er die Optimallösung liefert, sind Ausnahmen!

12.1.1. Verbesserter Greedy- Algorithmus Betrachte die Gegenstände in absteigender Reihenfolge nach zuerst. wi 2 1 5 3 8 2 5 5 gi wi/gi 1/2 1/2 1 3/5

wi gi

, also die “lukrativen” Gegenstände

101

12. Der Greedy- Algorithmus

x3 = 1 x4 = 1 x2 = 0 (Sonst Gewicht = 12) x1 = 0 W

= 8

In diesem Beispiel ist das Ergebnis optimal.

12.2. Anwendung Der Greedy- Algorithmus liefert Optimallösungen für • kürzeste Spannbäume (Kruskal)

• Geldwechsel mit Euro( / Cent)- Münzen

Nützlich:

• als Heuristik

• als Näherungslösung

102

13. Branch-and-Bound

13.1. Rucksackproblem

n -

i=1 n -

unter

i=1

xi · wi → MAX! xi · gi ≤ G

xi ∈ {0, 1}

Beispiel: n=4 4

gi wi

5

=

4

5 3

5 4 5 4 5 4 5 5 9 2 , , , 4 7 1

G=11 Dies liefert 2n potentielle Lösungen. Der Reihe nach werden die Werte x1 , x2 , x3 , x4 auf jeweils zwei Arten festgelegt → Lösungsbaum. Jeder Knoten des Baumes speichert Knoten

%g& w

%g& w

= bisheriges Gesamtgewicht / Gesamtwert.

auf der Ebene i hat zwei Kinder:

Für xi+1 = 1 und für xi+1 = 0 mit Werten nicht betrachtet.)

4

g + gi+1 w + wi+1

5

bzw.

4

g w

5

. (Die Knoten g > G werden

103

13. Branch-and-Bound









     









 





Optimallösung: x1 = x2 = 0 x3 = x4 = 1 W =8

Laufzeit: O (2n ) Speicher: O (n) Es ist eine Ersparnis möglich, da manche Zweige des Baumes abgeschnitten werden. Man kann sich zu jedem Knoten eine obere Schranke für den Gesamtwert berechnen, der von diesem Knoten erreicht werden kann. (Im Baum oben lila). Laufzeitverbesserung: % & Betrachte Knoten wg auf Ebene i:

Das verbleibende Gewicht G − g kann mit Gegenständen x1 , . . . , xn aufgefüllt werden. H G wn wi+1 ,..., . Die Werte sind ganzzahlig, die Schranke Diesen liefert die Schranke w +(G − g)·max gi+1 gn muss abgerundet werden. Der zusätzliche Wert, der damit erreicht werden kann ist: =M

# 4

$! H5" wn wi+1 xi+1 · wi+1 + · · · + xn · wn ≤ (G − g) · ,..., max gi+1 gn ! "# $ spezifischer Wert, Wert pro Gewicht

Beweis:

104

G

13.1. Rucksackproblem

xi+1 · gi+1 + · · · + xn · gn ≤ G − g

xi+1 · wi+1 + · · · + xn · wn = xi+1 · gi+1 ·

wi+1 wn + · · · + xn · gn · gi+1 gn !"#$ ! "# $ ≤M

≤M

≤ (xi+1 · gi+1 + · · · + xn · gn ) · M ≤ (G − g) · M ! Wenn die abgerundete Schranke nicht größer ist als die beste bisherige Lösung, so wird der Zweig abgeschnitten, das heißt, dass das der Zweig nicht mehr durchlaufen werden muss).

13.1.1. Verbesserung Ordne die Gegenstände absteigend nach 4 5 4 5 4 5 4 5 5 9 5 2 4 7 3 1 0,8 0,77 0,6 0,5

wi gi















Laufzeit: O (2n ) In der Praxis kann es um Größenänderungen besser sein.

105

13. Branch-and-Bound

106

14. Laufzeiten 14.1. Unterschied von polynomiell, exponentiell und pseudopolymnomiell. 14.1.1. polynomiell % & O Lk für eine Konstante k, wobei L die Länge der Eingabe ist.

2 Polynomiell kommt daher, dass zumeist Polynome % 2von & z.B. der Gestalt p(x) = 20 · x − 12 · x + 3, 5 betrachtet werden. In diesem Fall gilt: p(x) = O x . % & % & Außerdem gilt O x7,5 = O x8

14.1.2. exponentiell O (cn ) für eine Konstante c, die Laufzeit steigt exponentiell. Das Rucksackproblem z.B. ist exponentiell mit O (2n ). Dynamisches Programmieren mit O (n · G) oder O (n · W ).

14.1.3. Länge der Eingabe Länge der Eingabe = Zahl x ∈ Z benötigt log2 (1 + |x|) + 2 bis zur Darstellung. Rucksackproblem: U U L = θ (n + log (1 + |wi |)) + log (1 + |gi |) + log G 1 ≤ wi ≤ Wmax , 1 ≤ g ≤ G

Ein polynomieller Algorithmus muss polynomiell in n, log Wmax , log G sein. (er muss polynomiell vom Logarithmus der auftretenden Zahl abhängen.) % & O (n · G) = O n · 2log G ist exponentiell in der Länge.

14.1.4. pseudopolynomiell Ein Algorithmus, der polynomiell von der Größe (|x| nicht Bitlänge) der auftretenden Eingabezahlen abhängt, heißt pseudopolynomiell.

107

14. Laufzeiten

14.1.5. Kostenmaß

Strenggenommen muss das logarithmische Kostenmaß verwendet werden, wenn von einem polynomiellen Algorithmu gesprochen wird. Einheitskostenmaß (EKM) : O (2n ) 



  Logarithmisches Kostenmaß (LKM) : O 2n · (log G + log Wmax + log n)  ! "# $ ≥log der auftretenden Zahlen Dynamisches Programmieren: EKM: O (n · G)

LKM: O (n · G · (log G + log Wmax + log n))

108

Teil VIII.

Graphen

109

15. Allgemeines in Graphen 15.1. Inhalte • Speicherung

• Tiefensuche / Breitensuche • Dijkstra- Algorithmus • kürzeste Wege mit

– Floyd- Warshall – Bellman- Ford • Flüsse Bereits bekannt ist : • kürzester Spannbaum (Greedy- Algorithmus, Algorithmus von Kruskal)

15.2. Speicherung 15.2.1. Adjazenzliste Jeder Knoten speichert eine Liste seiner ausgehenden Kanten. Grundoperation: Gib alle Knoten v ∈ V aus, mit (u, v) ∈ E, die von u ausgehen. Graph G = (V, E)

V : Knotenmenge E ⊆ V × V : gerichtete Kanten

ungerichtete Graphen werden gespeichert, in dem man für jede ungerichtete Kante zwei gerichtete Kanten in jede Richtung speichert.

15.2.2. Adjazenzmatrix (aij ) mit n × m (n = |V | , m = |E|) S 1 wenn (i, j) ∈ E aij = 0 sonst

111

15. Allgemeines in Graphen

112

16. Durchsuchen von Graphen 16.1. Tiefensuche (depth-first-search, dfs) Alle Knoten sind zu Beginn unmarkiert Algorithmus 16.1 Tiefensuche dfs (u) markiere u für alle Kanten (u, v) if (v unmarkiert) then dfs (u) vorg [v] = u Wenn der Algorithmus dfs aufgerufen wird, dann besucht der Algorithmus alle Knoten, die von u aus erreichbar sind. Die Vorgänger vorg[u] bilden den Tiefensuchenbaum.

16.2. Breitensuche (breadth-first-search, bfs) Die besuchten Knoten werden in eine Schlange Q eingefügt. Jeder Knoten ist entweder besucht, gesehen oder neu. Initialisierung: Alle Knoten sind neu. Algorithmus 16.2 Breitensuche u1 sei der Startknoten Q = u1 u1 ist gesehen d [u1 ] := 0 Breitensuche : while Q 1= ∅ entferne den ersten Knoten aus Q setze u auf besucht für alle (u, v) ∈ E if (v ist neu) then füge v in Q ein d [v] = d [u] + 1 v wird auf gesehen gesetzt

113

16. Durchsuchen von Graphen Der Algorithmus besucht alle Knoten, die vom Startknoten u1 erreichbar sind. Die Vorgängerzeiger bilden den Breitensuchenbaum. d [v] ist die Länge des kürzesten Weges von u nach v.

114

17. Kürzeste Wege 17.1. Allgemeines Gegeben ist ein gerichteter Graph mit Kantengewichten cij ∈ R für die Kanten (i, j). cij ≤ 0 ist erlaubt.

1

Gesucht ist der kürzeste Weg vom Startknoten u1 zu allen anderen Knoten.

17.1.1. Probleme bei negativen Kosten Wenn der Graph negative Kreise enthält, dann ist der kürzeste Weg nicht unbedingt definiert. 2 Gibt es keine negativen Kreise, so gibt es immer einen kürzesten Weg: ein sogenannter einfacher Weg (ohne Wiederholung von Knoten).

    



Da es keinen negativen Kreis gibt, so ist der Weg über den Kreis immer ≥ 0, bei der Betrachtung des kürzesten Weges hilft dies nicht. Variante: kürzester einfacher Weg: NP- schwer



17.2. Algorithmus von Bellman-Ford Der Algorithmus von Bellman-Ford funktioniert mit dynamischer Programmierung. Teilprobleme: (k)

dj

= Länge des kürzesten Weges von u1 zu ui mit höchstens k Kanten.

(n−1)

di

1 2

= kürzeste Wege, sofern der Graph G keinen negativen Kreis hat.

Gewichtete Kanten können Kosten sein; negative Kosten sind Gewinne Nicht unbedingt: Falls der Kreis nicht von u1 erreichbar ist, ist es egal

115

17. Kürzeste Wege Rekursion:

(k)

dj

=

min

i:(i,j)∈E

X

(k−1)

dj

*T ' (k−1) , di + cij

j∈V k≥1 min

i=1,2,,...,n

* ' (k−1) di + cij

wir setzen cij falls (i, j) ∈ /V (0) dj

S ∞ für j = 1 u1 = 0 für j = u1

17.2.1. Berechnung Als Adjazenzliste: (k)

di i=1 .. . .. . i=n

k=0 0

1

...





n−1

∞ .. . ∞ 

(k)

d1  .. Berechnung von  .

(k)

dn

d&(k)

2



(k)

d1  .. = .

(k)

dn

  

   aus 

(k−1)

d1

.. .

(k−1)

dn

' * d&(k) = F d&(k−1)



 . ' * ' * d&(0) , d&(1) = F d&(0) , d&(2) = F d&(1)

1. Möglichkeit: wie in der Definition: benötigt die Adjazenzliste für die hereinkommenden Kanten für jeden Knoten j.

116

17.3. Algorithmus von Floyd-Warshall 2. Möglichkeit: Vorwärtsiteration: (k)

(k−1)

Initialisiere alle di auf di für alle (i, j) X ∈ E' *T (k) (k) (k−1) dj = min dj , di + cij Algorithmus 17.1 Straffen einer Kante Straffe * ' (i, j) (k) (k−1) if dj > di + cij (k)

(k−1)

then dj := di vorg[j] = 1

+ cij

Beide Varianten liefern dasselbe Ergebnis und laufen in O(m + n) Zeit, für d&(k−1) → d&(k) . Es sind insgesamt n Iterationen, die Laufzeit ist O (n · (m + n)).

Die generelle Annahme ist : m ≥ n − 1 (Graph zusammenhängend ⇒ O (m · n))

Wenn der Graph keine negativen Kanten enthält, dann bestimmen die Vorgängerzeiger den kürzesten-Wege-Baum mit Wurzel u1 .

17.2.2. Anmerkungen,Beobachtungen • Sobald d&(k) = d&(k−1) (d.h. in einer Iteration hat sich nichts geändert) kann man aufhören, es wird sich auch in'weiteren Schritten * ' *nichts ändern. d&(k+1) = F d&(k) = F d&(k−1) = d&(k) ⇒ d&(k) = d&(k+1) = d&(k+2) = . . .

• Wenn der Graph einen negativen Kreis enthält, der von u1 erreichbar ist, dann gibt es einen (k) Knoten j, für den die Folge dj , k = 1, 2, 3, . . . nach unten beschränkt ist. Dann kann der Fall d&(k) = d&(k−1) nicht eintreten. • Wenn irgendwann d&(k) = d&(k−1) für ein k ≤ n eintritt, dann gibt es keinen negativen Kreis, d&(k) enthält die kürzesten Abstände. • Wenn d&(n) = d&(n−1) ist, dann enthält G einen negativen Kreis.

17.3. Algorithmus von Floyd-Warshall Der Algorithmus funktioniert mit dynamischer Programmierung. Teilprobleme: Kürzeste Wege von i nach j.





Wir definieren eij := kürzeste Wege von i nach j, der als Zwischenknoten nur die Knoten 1, 2, . . . , k verwendet. Rekursionsgleichung: (0)

(1)

(k−1)

eij , eij , . . . , eij

seien bereits berechnet.

117

17. Kürzeste Wege (k)

Gesucht ist nun eij . X T (k) (k−1) (k−1) (k−1) eij = min eij , eik + ekj

für i, j = 1, 2, . . . , n für k = 1, 2, . . . , n

Initialisierung:   eij alle Wege ohne Zwischenknoten, wenn also (i, j) ∈ E (0) eij = ∞ wenn (i, j) ∈ / E und i1=j   0 wenn i = j

Endergebnis: (n)

ei j Algorithmus 17.2 Floyd-Warshall (0)

Initialisiere eij for k = 1, 2, . . . , n for i = 1, 2, . . . , n for j = 1, 2, . .X. , n T (k) (k−1) (k−1) (k−1) eij = min eij , eik + ekj

(*)

% & Laufzeit: O n3

% & Speicher naiv: O n3

% & Bei der Berechnung von k benötigt man allerding nur die Werte mit k − 1 Speicher, daher O n2 .

Der im Weiteren betrachtete Graph ist wie folgt:

 





  



 



Berechnung mit Hilfe einer Adjazenzmatrix:    4 ∞ ∞ ∞ 0 0 4 ∞ ∞ ∞  ∞ 0 1 ∞ ∞   ∞ 0 1 ∞ ∞    (0) (1)  eij =  eij =   ∞ ∞ 0 −2 ∞   ∞ ∞ 0 −2 ∞  −1 ∞ ∞ 0 ∞   −1 3 ∞ 0 −1 ∞ ∞ ∞ 2 0 0 ∞ ∞ ∞ 2

     

T X T X (1) (0) (0) (0) (1) (0) (0) (0) e4,2 = min e4,2 , e4,1 + e1,2 = min {∞, (−1) + 4} = 3 | e1,j = min e1,j , ei,1 + e1,j 118

17.3. Algorithmus von Floyd-Warshall

(2)

eij



 3 5  ∞ 0 1 ∞ ∞     ← Rest unverändert = ∞ 4     3 ∞

Der Algorithmus kann feststellen, dass der Graph negative Kreise enthält: (k)

Wenn irgendein eii negativ wird, dann hat der Graph einen negativen Kreis. Der Algorithmus sollte dieses prüfen und beim Erkennen eines solchen Auftretens terminieren. Zum Finden der kürzesten Wege muss man die Rekursion erweitern: Algorithmus 17.3 Floyd-Warshall, Finden der kürzesten Wege (0)

Initialisiere eij for k = 1, 2, . . . , n for i = 1, 2, . . . , n for j = 1, 2, . . . , n (k−1) (k−1) (k−1) + ekj < eij if eik (k)

(k−1)

then eij := eik zij := k (k) (k−1) else eij := eij

(k−1)

+ ekj

zij := der Zwischenknoten mit der höchsten Nummer, auf dem kürzesten Weg von i nach j, der bisher gefunden wurde. Initialisierung: zij = 0 (n)

Ausgabe eines kürzesten Weges von i nach j, falls eij 1= ∞ ist. Algorithmus 17.4 Floyd-Warshall, Ausgabe eines kürzesten Weges Ausgabe (i, j) (durch den kürzesten Weg von i nach j aus ausschließlich i, einschließlich j) if zij = 0 then print j else Ausgabe (i, zij ) Ausgabe (zij , j)

Die Laufzeit ist O (#Knoten dieses Weges)

17.3.1. Varianten und Verallgemeinerung auf andere Wegprobleme Erreichbarkeit in Graphen Gegeben: Adjazenzmatrix aij :=

S

1 falls (i, j) ∈ E 0 sonst

119

17. Kürzeste Wege Gesucht: Für alle Paare i, j : Gibt es einen Weg von i nach j? Lösung: (k)

(k−1)

Ersetzt (*) durch eij := eij

or

' * (k−1) (k−1) eij and ekj

aus “+” wird “∧”, aus “min” wird “∨” Algorithmus von Kleene

Der Algorithmus dient zum Umwandeln eines endlichen Automaten in einen regulären Ausdruck umwandeln. (*) wird ersetzt durch: ' * (k) (k−1) (k−1) (k−1) ∗ (k−1) eij := eij ∪ eik ekk ekj (k)

eij = {die Wörter, die ein endlicher Automat akzeptiert, wenn er im Zustand i beginnt und im Zustand j aufhört und nur die Zustände 1, . . . , k besuchen darf.} Weg mit der größten Kapazität

Gegeben: cij = “Kapazität” einer Kante, z.B. maximale Breite, maximales Gewicht eines Fahrzeuges. Kapazität eines Weges = Minimum der Kapazitäten des Weges







Gesucht: Der Weg mit der größten Kapazität. Lösung: X ' *T (k) (k−1) (k−1) (k−1) (*) wird ersetzt durch eij = max eij , min eik , ekj

Aus “min” wird “max”, aus “+” wird “min”. Initialisierung:   cij (0) eij = 0 oder − ∞   +∞

Der Weg mit der größten Kapazität lässt sich auch mit einer Verallgemeinerung des Bellman-FordAlgorithmus und auch mit dem Algorithmus von Dijkstra lösen.

17.3.2. Allgemeine Wegprobleme Gegeben: Grundmenge S von “Gewichten”

120

17.3. Algorithmus von Floyd-Warshall Operation ⊗ Gewicht eines Weges (i1 , i2 , . . . , il ) = ci1 ,i2 ⊗ ci2 ,i3 ⊗ · · · ⊗ cil−1 ,il Operation ⊕ Aggregieren der Weggewichte Gesucht: [

Gewicht des Weges Wege von i nach j

0) 1) 2) 3)

kürzester Weg S = R ⊗ = + ⊕ = min

Erreichbarkeit S = {0, 1} ⊗ = ∧ ⊕ = ∨ U reguläre Sprache S = P ( ∗ ) ⊗ = min ⊕ = max

größte Kapazität S = R ∪ {∞, −∞} ⊗ = min ⊕ = max

In allen Fällen gilt das Distributivgesetz (a ⊕ b) ⊗ c = (a ⊗ c) ⊕ (b ⊗ c) a ⊗ (b ⊕ c) = (a ⊗ b) ⊕ (a ⊗ c)

121

17. Kürzeste Wege

122

18. Flüsse in Netzen  





  





 

 



  

Flusserhaltungssatz: In jeden Knoten (außer s und t) fließt genauso viel hinein wie hinaus; alles was ein einen Knoten fließt, fließt heraus, sonst bildet sich ein Stau.

18.1. Formales Ein Netzwerk ist folgendermaßen definiert: • Es gibt einen gerichteten Graphen G mit G = (V, E) • Es gibt zwei ausgezeichnete Kanten s, t ∈ V und s 1= t, s: Quelle (source), t: Senke (sink) • Die Kapazität ist eine Funktion auf den Kanten mit c : E → R

cij ist eine obere Schranke für den Fluss auf der Kante (i, j).

Ein Fluss ist eine Funktion x : E → R, die zwei Bedingungen erfüllen muss: 1. Kapazitätsrestriktion (es darf nicht mehr auf einer Kante “fließen”, als sie Kapazität hat) ∀ (i, j) ∈ E : 0 ≤ xij ≤ cij 2. Flusserhaltung (In jeden Knoten (außer s und t) fließt genauso viel hinein wie hinaus; alles was ein einen Knoten fließt, fließt heraus, sonst bildet sich ein Stau.) ∀i 1= s, t :

U

(k,i)∈E xki =

-

xij

(i,j)∈E

Wert des Flusses:

123

18. Flüsse in Netzen Flusswert =

H Gesamtfluss aus der Quelle → MAX! Gesamtfluss in die Senke hinein w(x) = xsj − xij (s,j)∈E

(k,s)∈E

Variante an der Darstellungsweise: Man setzt xji = −xij

Bei der Annahme, dass der Graph keine zwei entgegengesetzten Kanten enthält, gilt für die Flusserhaltung im Knoten i: -

xij = 0

j

18.2. Problem des größten Flusses Gegeben: Ein Netzwerk. Gesucht: Der Fluss mit dem größten Wert. Definition: & % Ein Schnitt S, S ist eine Zerlegung von V in zwei Mengen mit





S ∩S = ∅ , S ∪S = V , s∈ S, t ∈ S 

Kapazität des Schnittes:



%

&

c S, S =

-

cij

i∈S j∈S (i, j) ∈ E

Flusswert eines Schnittes: & % x S, S =

Wert w(x) = ({s} , V − {s}) Lemma: Jeder Schnitt hat den gleichen Wert. Beweis:

124

-

i∈S j∈S (i, j) ∈ E

xij −

-

i∈S j∈S (i, j) ∈ E

xij

18.2. Problem des größten Flusses Addiere die Definitionen von w(x) und die Flusserhaltungsgleichungen der Kanten in S\ {s}

w (x) =

-

j:(s,j)∈E

0 =

-

j:(s,j)∈E

%

w (x) = w S, S

− −

&

-

k:(k,s)∈E

-

k:(k,i)∈E

für i ∈ S\ {s}

Alle Kanten kürzen sich weg, außer die Kanten des Schnittes. Insbesondere w (x) = w (V − {t} , {t}) =

-

(k, t) ∈E

xkt −

-

xtj

(t,j)

Lemma: % & Die Kapazität C S, S eines Schnittes ist eine obere Schranke für den Flusswert. Beweis:

% & w (x) = x S, S =



i∈S j∈S (i, j) ∈ E i∈S j∈S (i, j) ∈ E

xij − !"#$ ≤cij

-

i∈S j∈S (i, j) ∈ E

xij !"#$ ≥0

cij − 0

% & = c S, S

18.2.1. Max-Fluss-Min-Schnitt-Satz Der größte Wert eines Flusses ist gleich der kleinsten Kapazität eines Schnittes. (Ford/Fulkerson) ” ≤ ” folgt aus dem Lemma. Annahme: Das Netz enthält keine entgegengesetzten Kanten, ggf. die Kante unterteilen und Zusatzkanten einfügen.

125

18. Flüsse in Netzen











Definition: Der Restgraph, das Restnetzwerk Gx eines Netzes G bzgl. eines Flusses x ist folgendermaßen definiert: Für alle (i, j) ∈ E Restkapazität cij = cij − xij Restkapazität cij = xij

Vorwärtskante (i, j) Rückwärtskante (j, i)

Der Restgraph besteht aus allen Vorwärts- und Rückwärtskanten mit positiven Restkapazitäten.   

 





    



 

Satz (Charakterisierung des größten Flusses): x sei ein Fluss in einem Netz. Die folgenden drei Aussagen sind äquivalent: (i)

x hat den größten Wert.

(ii)

Im Restgraphen gibt es keinen Weg von s nach t % & % & Es gibt einen Schnitt S, S mit c S, S = w (x)

(iii) Beweis:

• (i) ⇒ (ii) , bzw. [¬ (ii) ⇒ ¬ (i)]

Wenn es im Restgraphen einen Weg von s zu t gibt, dann kann mann den Flusswert entlang dieses Weges vergrößern.

• (iii) ⇒ (i) % & c S, S ≥ w (x! ) für jeden Fluss x ! "# $ w(x)

126

18.2. Problem des größten Flusses • (ii) ⇒ (iii)

S = {Knoten, die von sim Restgraph erreichbar sind}

s ∈ S, t = S = V −S

Gx hat keine Kante von S nach S ⇒ Restkapazitäten sind 0 

(i, j) ∈ E , i ∈ S, j ∈ S

cij = cij − xij = 0



xij = cij

% & w (x) = x S, S xij xij − = !"#$ !"#$ i ∈ S =cij i ∈ S =0 j∈S j∈S = cij i∈S j∈S & % = c S, S

Aus der Charakterisierung folgt der Max-Fluss-Min-Schnitt-Satz, wenn wir voraussetzen, dass es immer einen Fluss x∗ mit größtem Wert gibt. Beweis: * ' * ' ∗ ∗ (i) ⇒ (iii) Es gibt S ∗ , S mit w (x∗ ) = c S ∗ , S % & & % Für jeden Schnitt S, S gilt w (x∗ ) ≤ c S, S ! "# $ ∗ =c(S ∗ ,S )

Die Existenz folgt z.B. daraus, dass die Menge der Flüsse x eine nichtleere, abgeschlossene, beschränkte Teilmenge des RE ist. Daher nimmt jede stetige Funktion, insbesondere w (x) dort ihr Maximum an. (konstruktiver Beweis später.) Wenn der Restgraph einen Weg von s nach t enthält, dann kann man den Fluss entlang dieses Weges vergrößern. ∀ Vorwärtskanten (i, j) auf dem Weg xij := xij + ∆ ∀ Rückwärtskanten (i, j) auf dem Weg xij := xij − ∆

ist die Flusserhaltung erfüllt.

w (x)steigt um ∆. Wähle ∆ klein genug, so dass die Restrikitionen 0 ≤ xij ≤ cij erfüllt bleiben.

∆ := min {cij | (i, j) eine Kante auf dem Weg} > 0

18.2.2. Ford-Fulkerson Gegeben:

127

18. Flüsse in Netzen Ein Netzwerk. Gesucht: Ein Fluss mit größtem Wert. Algorithmus 18.1 Ford-Fulkerson Start: xij := 0 ∀ (i, j) ∈ E Schleife: 1. Konstruiere den Restgraphen 2. Suche einen Weg von s nach t in Gx 3. Wenn ein Weg gefunden ist, dann bestimmte ∆ und vergrößere den Fluss um ∆i . Dann gehe zu 1.) Wenn es keinen Weg gibt, dann ist der Fluss optimal.

Die Menge der von s erreichbaren Kanten bilden einen Schnitt, dessen Kapazität gleich dem Flusswert ist. Beispiel:  



 

 





















Es gibt Beispiele, bei denn der Algorithmus nicht terminiert und sogar gegen einen Fluss konvergiert, der nicht optimal ist. Wenn alle Kapazitäten cij ganzzahlig sind, also cij ∈ Z, dann arbeitet der Algorithmus nur mit mit Werten ∈ Z. Insbesondere ist auch ∆ ∈ Z.

⇒∆≥1

w∗ Wert des optimalen Flusses ⇒ ≤ w∗ Iterationen Satz: Wenn alle cij ∈ Z, dann existiert immer ein optimaler Fluss, der auch ganzzahlig ist.

Wenn der größte Flusswert w∗ ist, dann terminiert der Algorithmus höchstens nach w∗ Iterationen. Jede Iteration kann in linearer Zeit durchgeführt werden. Laufzeit:

128

18.2. Problem des größten Flusses Die Gesamtlaufzeit beträgt O (w∗ · (m + n)) Eine Schranke für

w∗

is jeder beliebige Schnitt, z.B.



U

w∗ ≤

(s, j) ∈ E





csj

 

 









 











Dieser Algorithmus ist pseudopolynomiell. U Laufzeit ⊆ O ((m + n) · cij ) nicht pseudoploynomiell (in log cij , n, m)

Die Möglichkeiten einen Fluss auszuwählen sind: 1. kleinste Kantenzahl (Breitensuche) → Edmunds/Karp

2. größte Restkapazität

Es wird immer ein kürzester Weg s → t in Gx gewählt. Lemma: d(s, x) : kürzester Abstand von s nach x im Restgraphen (kann auch ∞ sein) d(s, t) : kürzester Abstand von s nach t im Restgraphen (kann auch ∞ sein) d (s, x) und d (s, t) kann im Laufe des Algorithmus nicht abnehmen.

Beweis: Die Kanten im Restgraphen, die nun entstehen, sind die Umkehrkanten der Kanten des Weges. d = d (s, x) Lemma: Jede Vorwärts-, bzw. Rückwärtskante wird höchstens n-mal aus dem Restgraphen gelöscht. Damit die Kante (i, j) nach dem Verschwinden wieder auftaucht, muss sich der Flusswert xij , bzw. xji ändern. Dazu muss die Kante (j, i) Bestandteil eines kürzesten Weges im Restgraphen sein. Lemma #$!" Die Länge dieses Weges ≥ d (s, j) + 1 + d (i, t) ≥ d (s, j) + 1 + d (i, t) = d (s, t) + 2 ! "# $ ! "# $ im neuen Graphen im alten Graphen

Der Abstand d (s, t) muss mindestens um 2 größer geworden sein. Das kann höchstens n/2- mal passieren. In jedem Schritt wird mindestens eine Vorwärts- oder Rückwärtskante aus Gx gelöscht. Das kann höchstens (2 · m) · (n) - mal passieren. !"#$ ! "# $ #Kanten Lemma 129

18. Flüsse in Netzen Satz: Wenn man im Restgraphen den Weg mit der kleinsten Kantenanzahl auswählt, benötigt % der &Algorithmus höchstens O (m · n) Schritte, die Laufzeit beträgt daher O (m · n · (m + n)) = O m2 · n . % & Es geht aber auch in O n3 .

18.3. Paarungen (Matchings) in bipartiten Graphen Definition: Eine Paarung ist ein Graph, dessen Kanten paarweise keine gemeinsamen Kanten haben. Bei einer perfekten Paarung (vollständigen Paarung) ist jeder Knoten zu einer Paarung inzident. Gegeben: Ein Graph G = (V, E). Mögliche Fragen: • Hat der Graph eine perfekte Paarung M = (V, E ! ) mit E ! ⊆ E ? • Finde die größte Paarung |E ! | → MAX! Beispiel: 





Gesucht ist die größte Paarung in dem bipartiten Graphen: ˙ V = A∪B A∩B =∅ E ⊆A×B Lösung: Reduktion auf ein max-Fluss-Problem (Füge s mit Kapazität 1 auf den Kanten ein, so auch t). Erstelle ein Netwerk mit zwei Knoten s (Quelle) und t (Senke) und zusätzliche Kanten • (s, a) für a ∈ A mit csa = 1 • (b, t) für b ∈ B mit cbt = 1 Die ursprünglichen Kanten werden von A nach B gerichtet, mit Kapazität cab = ∞ (oder cab = 1)

130

18.3. Paarungen (Matchings) in bipartiten Graphen

 













 

 

Beobachtung: Jeder ganzzahlige Fluss entspricht einer Paarung M = (V, E ! ) mit E ! = {a, b ∈ A, B | xab = 1} und umgekehrt. Der Wert des Flusses entspricht der Größe der Paarung. Algorithmus 18.2 Matchings in bipartiten Graphen Gegeben sei der Graph G = (V, E). ˙ Gesucht ist das größte Matching in dem bipartiten Graphen mit V = A∪B A∩B =∅ E ⊆A×B Füge Quelle s und Senke t ein. Richte den Graphen von . Vergebe die Kantengewichte ∞ und die speziellen Kantengewichte • (s, a) für a ∈ A mit csa = 1 • (b, t) für b ∈ B mit cbt = 1 Löse das entsprechende Flussproblem.

Laufzeit: 



Ford-Fulkerson: O (m + n) · !"#$ w∗  = O (m · n)

(Es geht auch in O (m ·



≤n

n) Zeit → Hopcraft/Karp)

Anwendung: Heiratssatz (M. Hall) Definition: G = (A ∪ B, E)

für A! ⊆ A ist N (A! ) = {b ∈ B | ∃a ∈ A! : (a, b) ∈ E} die Nachbarschaft von A’. Satz: Ein bipartiter Graph G = (A ∪ B, E) mit |A| = |B| hat genau dann eine vollständige Paarung, wenn ∀A! ⊆ A : |N (A! )| ≥ |A! | Beweis: max-Fluss-min-Schnitt-Satz. Es sei n = |A| = |B|

∃vollständige Paarung ⇔ Jeder Schnitt im Netzwerk hat Kapazität ≥ n

131

18. Flüsse in Netzen











A0 = A ∩ S S = A\S

B0 = B ∩ S B = B ∩ S

S ∞ wenn es eine Kante von A nach B gibt c S, S = P P PAP + |B0 | sonst %

&

Es gibt eine perfekte Paarung ⇔ ∀A0 ⊆ A : ∀B0 ⊆ B : wenn es keine Kante von A0 zu B − B0 gibt, dann ist |A − A0 | + |B0 | ≥ n. |A| − |A0 | + |B0 | ≥ n !"#$ n

|B0 | ≥ |A0 |

umformuliert: ∀A0 ⊆ A : ∀B0 ⊆ B

wenn B0 ⊇ N (A0 ), dann ist |B0 | ≥ |A0 |

Laufzeit: Die größten Paarungen in bipartiten Graphen lassen sich ebenfalls in polynomieller Zeit berechnen: √ O (m · n) Zeit.

132

Teil IX.

Komplexitätstheorie

133

19. Die Klasse P 19.1. Allgemeines Die Klasse P ist die Klasse der in polynomieller Zeit lösbarer Probleme und Reduzierbarkeit zwischen Problemen. Definition: Die Klasse P besteht aus Problemen, die in polynomieller Zeit gelöst werden können: Es gibt einen Algorithmus zur Lösung von P und ∃a, k : für alle Eingaben I ist die Laufzeit durch a · |I|k beschränkt.

“|I|” ist die Länge der Eingabe I.

19.2. Probleme 19.2.1. Berechnungsprobleme Das Problem wird durch eine Berechnung gelöst und das Ergebnis dieser Berechnung ist die Rückgabe; in der Regel kein boolescher Wert. Beispiel: EINGABE: GESUCHT:

Ein bipartiter Graph. die Größe der gesuchten Paarung. oder: eine größte Paarung.

19.2.2. Entscheidungsprobleme Das Problem wird gelöst und es wird eine Frage beantwortet; das Ergebnis ist ein boolescher Wert. Beispiele: EINGABE: FRAGE:

Ein bipartiter Graph. Hat der Graph eine vollständige Paarung?

EINGABE: FRAGE:

Ein bipartiter Graph, eine Schranke k ∈ N . Gibt es eine Paarung mit k Kanten?

19.3. Rechenmodell Welches Rechenmodell soll für die Lösung der Probleme hinzugezogen werden? • Turingmaschine

135

19. Die Klasse P • Registermaschine mit logarithmischem Kostenmaß • Registermaschine mit Einheitskostenmaß

Das Rechenmodell spielt keine Rolle (mit vernünftigen Einschränkungen). Eine Registermaschine kann auf einer Turingmaschine simuliert werden und umgekehrt QUERVERWEIS

19.4. Länge der Eingabe Die Eingabe muss über einem endlichen Alphabet kodiert werden, z.B. {0, 1}. Standardannahme:

Zahlen in der Eingabe werden binär kodiert : 9 = ˆ 1001 Zahl x benötigt O (log |x| + 2) Bits

Variante:

Zahlen werden unär kodiert : 9 = ˆ 1111111110 Zahl x benötigt O (|x| + 1) Bits

Algorithmen, die bei der Annahme von unärer Eingabekodierung polynomiell sind, heißen pseudopolynomielle Algor QUERVERWEIS

19.5. Polynomielle Reduktion Definition: Polynomielle Reduktion zwischen Entscheidungsproblemen: P1 ≺p P2 : P1 ist polynomiell reduzierbar auf P2 (P1 leichter als P2 ), wenn es eine Funktion f gibt, mit Eigenschaften: 1. f bildet die Eingaben von P1 auf die Eingaben von P2 ab. 2. f ist polynomiell berechenbar. 3. Für jede Eingabe I von P1 gilt: I ist JA- Eingabe von P1 ⇔ f (I) ist JA- Eingabe von P2

Reduktion: Ein Problem wird auf ein anderes zurückgeführt. Satz:

Seien L1 und L2 Entscheidungsprobleme, L1 ist polynomiell reduzierbar auf L2 und L2 ∈ P, dann gilt: L1 ∈ P. Beweis: Nach Voraussetzung haben wir eine polynomiell berechenbare Funktion f mit (i)

x ist JA- Eingabe für L1 ⇔ f (x) ist JA-Eingabe für L2

und es gibt einen Polynomialzeitalgorithmus g mit (ii)

g(y) = JA ⇔ y ist JA- Eingabe für L2 .

zu Zeigen: Es gibt einen Polynomialzeitalgorithmus h mit h(x) = JA ⇔ x ist JA- Eingabe für h

136

19.5. Polynomielle Reduktion

 

 

 

 

 

 

Berechne folgenden Algorithmus: 1. Berechne aus Eingabe x für L1 zunächst f (x) 2. Nimm das Ergebnis y = f (x) als Eingabe g 3. . . . berechne g (f (x)) Dieser Algorithmus berechnet also aus einer Eingabe x für L1 das JA- / NEIN- Ergebnis g (f (x)). (ii) (i) Es gilt: g (f (x)) = JA ↔ f (x) ist JA-Eingabe für L2 ⇔ x ist JA-Eingabe für L1 . noch zu zeigen: Der Algorithmus ist in polynomieller Zeit berechenbar. Sei af · |x|kf eine Laufzeitschranke für 1.

Sei ag · |x|kg eine Laufzeitschranke für 2.

Für Schritt 1: Laufzeit höchstens af · |x|kf .

Insbesondere gilt: |f (x)| ≤ af · |x|kf

k

Für Schritt 2 ist die Laufzeit beschränkt durch ag · |x|kg ≤ ag · af g · |x|kf ·kg k

Dieser Algorithmus hat also höchstens die Laufzeit af ·|x|kf +ag ·af g ·|x|kf ·kg , leistet also das Gewünschte. !

19.5.1. Drei Graphenprobleme CLIQUE Gegeben: ungerichteter Graph G = (V, E), natürliche Zahl k Frage: Gibt es eine Teilmenge U ⊆ V der Knoten mit |U | ≥ k Elementen, die eine Clique ist?

Das heißt für je zwei beliebige Elemente u, v ∈ U gilt (u, v) ∈ E. Knotenüberdeckung (KÜ) / vertex cover (VC) Gegeben: ungerichteter Graph G = (V, E), natürliche Zahl k Frage:

Gibt es eine Teilmenge U ⊆ V der Knoten mit |U | ≤ k Elementen, die alle Kanten überdeckt?

Das heißt für jede Kante (u, v) ∈ E gilt: u oder v (oder beide) ∈ U .

137

19. Die Klasse P Unabhängige Menge (UM) / independent set (IS) Gegeben: ungerichteter Graph G = (V, E), natürliche Zahl k Frage: Gibt es eine Teilmenge U ⊆ V der Knoten mit |U | > k Elementen, die unabhängig ist?

Das heißt für je zwei beliebige Elemente u, v ∈ U gilt (u, v) ∈ /E.

(Oder anders: für jede Kante (u, v) ∈ E liegt u oder v nicht in U ).

19.5.2. Beispielreduktionen KÜ ≤p UM Beweis: Reduktionsfunktion : f ((V, E) , k) = ((V, E) , |V | − k) ! "# $ ! "# $ Eingabe UM Eingabe KÜ 1. siehe Funktionseingaben 2. polynomiell " 3. x ist JA- Eingabe für KÜ ⇔ es gibt eine Knotenüberdeckung U ⊆ V mit |U | ≤ k (∗)

⇔ es gibt eine unabhängige Menge U ! mit |U ! | ≥ |V | − k ⇔ ((V, E) , |V | − k) = f ((V, E) , k) ist JA- Eingabe für UM

zu (∗): “⇒” Wähle U ! = V − U U ist Knotenüberdeckung ⇒ für jede Kante (u, v) ∈ E gilt: u ∈ U oder v ∈ U ⇒ für jede Kante (u, v) ∈ U gilt: u ∈ / V − U oder v ∈ / V −U ⇒ V − U ist unabhängige Menge “⇐” Wähle U = V − U ! U ist unabhängige Menge ⇒ für jede Kante (u, v) ∈ E gilt: u ∈ / U ! oder v ∈ / U! ! ⇒ für jede Kante (u, v) ∈ E gilt: u ∈ V − U oder v ∈ V − U ⇒ V − U ! ist KÜ UM ≤p CLIQUE Beweis:

%% & & V, E , k Reduktionsfunktion : f ((V, E) , k) = /E , wobei (u, v) ∈ E ⇔ (u, v) ∈ ! "# $ ! "# $ Eingabe UM Eingabe CLIQUE 1. siehe Funktionseingaben

2. polynomiell " a) Für alle u ∈ V Für alle v ∈ V falls (u, v) ∈ Adjazenzliste von u lösche (u, v) sonst fügeEin (u, v)

138

19.5. Polynomielle Reduktion 3. ((V, E) , k) ist JA- Eingabe für UM ⇔ es gibt eine unabhängige Menge U ⊆ V mit |U | ≥ k in (V, E) (∗)

⇔ es %% gibt&eine & Clique U ⊆ V mit |U | ≥ k in (V, E) ⇔ V, E , k ist JA- Eingabe für CLIQUE (∗) U ist unabhängige Menge in (V, E) ⇔ für zwei Elemente /E % u, &v ∈ U gilt: (u, v) ∈ ⇔ U ist Clique in V, E

CLIQUE ≤p KÜ Beweis: Reduktionsfunktion : f

1. siehe Funktion

& & %% ((V, E) , k) = V, E , |V | − k ! "# $ ! "# $ Eingabe CLIQUE Eingabe KÜ

2. polynomiell " 3. ((V, E) , k) ist JA- Eingabe für CLIQUE ⇔ es gibt eine Clique U ⊆ V mit |U | ≥ k in (V, E) & % ⇔es gibt eine unabhängige Menge U ⊆ V mit |U | ≥ k in V, E % & ! ⊆ V mit |U ! | ≤ |V | − k in V, E ⇔es gibt eine Knotenüberdeckung U & %P P && %% ⇔ V, E , PV P − k = f ((V, E) , k) ist JA- Eingabe für Knotenüberdeckung

19.5.3. Weitere Graphenprobleme HAM-PFAD (Hamilton- Pfad) Gegeben: ungerichteter Graph G = (V, E) Frage: Gibt es einen einfachen Weg in G, der jeden Knoten genau einmal besucht?

KEW (kürzester einfacher Weg) Gegeben: ungerichteter Graph G = (V, E), Kantengewichte uij ∈ R, Zahl k Frage: Gibt es einen einfachen Weg in G mit Länge ≤ k? (einfacher Weg: Jeder Knoten kommt höchstens einmal auf dem Weg vor.)

139

19. Die Klasse P

19.5.4. Weitere Beispielreduktion HAM-PFAD ≤p KEW Beweis:   /E ∞ (i, j) ∈ Reduktionsfunktion : f ((V, E)) = ((V, E) , wij , − |V | + 1) , wobei wij = 0 i=j ! "# $  "# $ !  −1 (i, j) ∈ E Eingabe HAM-P. Eingabe KEW 1. siehe Funktion 2. polynomiell " 3. (V, E) ist JA- Eingabe für HAM-PFAD ⇔ es gibt einen einfachen Weg (v1 . . . , vn ) in (V, E), der jeden Knoten genau einmal besucht ⇔es gibt einen einfachen Weg (v1 . . . , vn ) in (V, E) mit Gewicht ≤ − |V + 1 = −n + 1| ⇔((V, E) , wij , − |V | + 1) ist JA-Eingabe für KEW

P (polynomiell lösbar) wird üblicherweise mit “effizient lösbar” assoziiert. Mit einem Entscheidungsproblem lässt sich eine Sprache assoziieren. L = Menge der Eingaben, bei denen die Antwort “JA” ist. L ∈ P ≡ “Das Problem ist in P ”

Beispiel: Hamilton- Kreis- Problem L = {G = (V, E) |G hat einen Hamilton-Kreis} ⊆ Σ∗

Σ∗ ist ein geeignetes Eingabealphabet zur Kodierung von Graphen.

140

20. Die Klasse NP Definition: Die Klasse N P (“nichtdeterministisch Polynomialzeit”) enthält diejenigen Sprachen L, für die Folgendes gilt: Es gibt zwei Polynome Q1 , Q2 und einen Polynomialzeitalgorithmus A (x, y) mit zwei Eingabeparametern x und y. 1. ∀x : x ∈ L ⇔ ∃y : |y| ≤ Q1 (|x|) und A akzeptiert die Eingabe (x, y)

2. Die Laufzeit von A ist durch das Polynom Q2 beschränkt.

20.1. Definitionen Ein Problem A ist NP-vollständig, wenn gilt: (i) (ii)

A gehört zu NP, A ∈ N P

∀B ∈ N P : B 0 gibt es einen polynomiellen Algorithmus, der eine Rundreise R mit d (R) ≤ (1 + ") · d (R∗ ) berechnet. “PTAS” (Polynomial-time approximation scheme) ' * % & 2 Die Laufzeit ist in diesem Fall O 2exp(1/!) oder O n1/!

20.4. Klasse CoNP Die Definition von NP ist nicht symmetrisch bezüglich der Verneinung. JA-Eingaben sind die Eingaben, die ein polynomiell überprüfbares Zertifikat haben.

149

20. Die Klasse NP CoNP ist das Komplement der Probleme in NP (JA und NEIN vertauschen) Beispiel: Eingabe: Gewichteter Graph G, Schranke s Frage: Ist die Länge der kürzesten Rundreise ≥ s?

Dieses Problem ist in CoNP, es ist CoNP-vollständig. Vermutetes Bild der Komplexitätsklassen —Graphik Abhängigkeit NP-vollständiger Probleme —Graphik Ein offenes Problem, welches noch nicht bestimmt wurde, ist das des Graphisomorphismus’

150

Index A Algorithmus, Bogosort, 17, 25 Algorithmus, Las Vegas, 25 Algorithmus, Mergesort, 19, 25 Algorithmus, Monte Carlo, 25 Algorithmus, Quickselect, 37 Algorithmus, Quicksort, 21, 25 Algorithmus, Zufalls-, 25 Analyse, amortisierte Laufzeit, Methoden, 75 B Baum, Entscheidungs-, 49 Begriff, Median, 37 Begriff, Quartil, 37 D Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur, Datenstruktur,

Array, 65 Hashtabelle, 65 Hashtabelle, Hashfunktion, 65 Hashtabelle, Kollision, 65 Intervallabfrage, 65 Schlüssel, 65 Suchbaum, 65, 66 Suchbaum, (a,b) -, 67 Suchbaum, (a,b) -, Einfügen, 67 Suchbaum, (a,b) -, Löschen, 68 Suchbaum, AVL -, 66 Suchbaum, B -, 67 Suchbaum, binärer -, 66 Suchbaum, Eigenschaften, 66 Suchbaum, Rotation, 66 Suchbaum, Rot-Schwarz -, 69 Suchbaum, Verschmelzen, 70 Treap, 65 verkettete Liste, 65

K Komplexität, Einheitskostenmaß, 31 Komplexität, logarithmisches Kostenmaß, 31, 33 Komplexität, stark NP-vollständig, 148 L Laufzeit, amortisiert, 75, 77

Laufzeit, amortisiert, Methoden, 75 Laufzeit, angespannt, 76 Laufzeit, Potentialfunktion, 75, 76 Laufzeit, Schranke, 77 Liste, verschmelzen, 19 P Potentialfunktion, 75, 76 R Rechenmodell, RAM, 29 Rechenmodell, RAM, Anweisungen, 29 Rechenmodell, RAM, Fakultät, 30 Rechenmodell, Register, 29 Rechenmodell, Registermaschine, 29, 33 Rechenmodell, Turingmaschine, 29, 33 Rechenmodell, Word-RAM, 33 Rekursion, Lösungsbaum betrachten, 46 Rekursion, Master-Theorem, Anwendung, 59 Rekursion, Master-Theorem, Aussagen, 58 Rekursion, Master-Theorem, Beweis, 59 Rekursion, Master-Theorem, Fälle, 58 Rekursion, Master-Theorem, Hinleitung, 57 Rekursion, Master-Theorem, Regularitätsbedingung, 58 Rekursion, Wiederholtes Einsetzen, 45 S Sortieren, Divide and Conquer, 19, 21 Sortieren, Divide&Conquer, 45 Sortieren, Erwartungswert, 21 Sortieren, Median, 37 Sortieren, Pivotelement, 21 Sortieren, Teile und Herrsche, 19, 21, 45 Sortieren, untere Schranke, 49 Suche, Interpolations-, 51 Suche, quadratische Binär-, 52 U Ungleichung, Tschebyschew, 53 Union-Find, 79 Union-Find, Anwendungen, 79 Union-Find, Find, 79

151

Index Union-Find, Union-Find, Union-Find, Union-Find, Union-Find, Union-Find,

152

Find, Laufzeit, 80 Operationen, 79 Partition, 79 Realisierung, 79 Union, 79 Union, Laufzeit, 80

Algorithmenverzeichnis 1.1. 1.2. 1.3. 1.4. 1.5.

bogosort . . . . . . . . . . . . Überprüfen durch Auswahl . Mergesort . . . . . . . . . . . Quicksort . . . . . . . . . . . Sortieren, Ohne Bezeichnung

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

17 18 19 21 24

2.1. Pseudocode RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

3.1. Quickselect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37

6.1. Binäre Suche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2. Quadratische Binärsuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

51 52

10.1. Union-Find, max. Anzahl disjunkte Teilmengen finden . . . . . . . . . . . . . . . . . .

79

11.1. Dynamische Optimierung, optimaler Suchbaum . . . . . . . . . . . . . . . . . . . . . .

91

16.1. Tiefensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16.2. Breitensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

113 113

17.1. Straffen einer Kante . . . . . . . . . . . . . . . 17.2. Floyd-Warshall . . . . . . . . . . . . . . . . . . 17.3. Floyd-Warshall, Finden der kürzesten Wege . . 17.4. Floyd-Warshall, Ausgabe eines kürzesten Weges

. . . .

117 118 119 119

18.1. Ford-Fulkerson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18.2. Matchings in bipartiten Graphen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

128 131

20.1. NP, Rundreiseproblem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2. Approximationsalgorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

142 149

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

153

Algorithmenverzeichnis

154

Glossar Inversion Eine Fehlstellung (Inversion) ist ein Paar (i, j) mit 1 ≤ i < j < n und ai > aj . Beispiel die folgende Folge, es gibt 5 Fehlstellungen. 10

2

↑_ ↑_ ↑_

___ ___ _↑

7 ↑_ ___ _↑

14 ↑_ __ __

6 _↑ _↑ _↑

Rechnen mit Summen a -

i=

b−1 -

=

a · (a − 1) 2

i=1

a i=b

=

a i=1



i=1

a · (a − 1) (b − 1) · b − 2 2

Übergang zur nächsthöheren Zweierpotenz n → n! , n! = 2k k = &log2 n' mit n ≤ n! ≤ 2 · n ≤ T (n! ) ↑ implizite Annahme: Laufzeit wächst monoton mit der Größe T (n)

Möglichkeiten von Algorithmusentwurfsprinzipien Teile und Herrsche dynamische Programmierung greedy- Algortihmus branch & bound plane-sweep

(Divide & Conquer) (Systematisches Lösen von Teilproblemen) (Entscheidung nur anhand von lokalen Kriterien treffen) (systematisches Durchsuchen von Lösungsbäumen) (Überstreichen der Ebene für geometrische Probleme)

155