Algorithmen und Datenstrukturen Prof. Martin Lercher Institut für Informatik Heinrich-Heine-Universität Düsseldorf Algorithmen und Datenstrukturen Teil 1 Komplexitätsmaße für Algorithmen 16. Oktober 2016 1 / 21 Empfohlene Literatur • Thomas Ottmann, Peter Widmayer: Algorithmen und Datenstrukturen, Spektrum Akademischer Verlag, 5. Auflage, 2012 • Richard Johnsonbaugh, Marcus Schäfer: Algorithms, Pearson Education, 2004 • Jon Kleinberg, Eva Tardos: Algorithm Design, Addison Wesley, 2006 2 / 21 Komplexitätsmaße für Algorithmen Die wichtigsten Komplexitätsmaße für die Bewertung von Algorithmen sind • Rechenzeit • Speicherplatz • Kommunikationsaufwand (bei parallelen Prozessen). • ... Welche Algorithmen sind gut? Welche Algorithmen sind schlecht? Probleme beim Vergleich von Algorithmen sind • unterschiedlich schnelle Hardware (Computer) • unterschiedlich gute Übersetzer (Compiler) • unterschiedliche Vernetzung • unterschiedliche Eingabedarstellungen • ... 3 / 21 Komplexitätsmaße für Algorithmen Informatiker abstrahieren! • Wir messen die Größe der Eingabe in der Anzahl der elementaren Objekte: • Anzahl der gegebenen Zahlen • Anzahl der gegebenen Objekte • Anzahl der Buchstaben in allen gegebenen Namen • Wir zählen die Anzahl der elementaren Schritte: • • • • arithmetische Operationen Vergleiche Lese- und Schreiboperationen Ein- und Ausgabeoperationen 4 / 21 Komplexitätsmaße für Algorithmen Die Rechenzeit ist die Anzahl der benötigten elementaren Schritte in Abhängigkeit von der Größe der Eingabe. Sei Wn die Menge aller Eingaben der Größe n. Sei AT (w ) die Anzahl der elementaren Schritte von Algorithmus A für Eingabe w . Sei Pn : In → [0, 1] eine Wahrscheinlichkeitsverteilung für die Eingaben der Größe n, d.h., X Pn (w ) = 1. w ∈In 5 / 21 Komplexitätsmaße für Algorithmen Definition Sei M eine Teilmenge von R. • sup(M) ist die kleinste Zahl c ∈ R, sodass für alle n ∈ M, n ≤ c. • max(M) ist die kleinste Zahl c ∈ M, sodass für alle n ∈ M, n ≤ c. Anmerkungen: sup(M) muss nicht aus M sein bzw. max(M) muss nicht immer existieren. Beispiel: M := 1 1− n∈R . 1 + n2 6 / 21 Komplexitätsmaße für Algorithmen Die Worst-Case Zeitkomplexität für Algorithmus A (die Zeitkomplexität im schlechtesten Fall) ist TA (n) := sup{AT (w ) | w ∈ Wn }. TA (n) ist eine obere Schranke für die maximale Anzahl der Schritte, die Algorithmus A benötigt, um Eingaben der Größe n zu bearbeiten. Die mittlere bzw. erwartete Zeitkomplexität für Algorithmus A ist Pn T A (n) = X Pn (w ) · AT (w ). w ∈Wn Pn T A (n) ist die mittlere Anzahl von Schritten, die Algorithmus A benötigt, um Eingaben der Größe n mit Verteilung Pn zu bearbeiten. Platz- und Kommunikationskomplexitäten sind analog definiert. 7 / 21 Das O-Kalkül Die asymptotische Betrachtung berücksichtigt keine konstante additive Terme und keine konstanten Faktoren. Grundsätzliches: • Bei der Aufwandsabschätzung betrachten wir grundsätzlich nur Funktionen der Art f : N0 → N0 , die für unendlich viele Werte n ∈ N0 Funktionswerte f (n) 6= 0 annehmen. (N0 := N ∪ {0}) 8 / 21 Das O-Kalkül • Der Standardbezeichner für die Eingabegröße ist (meistens) n. • Für Funktionen f , die nicht alle Argumente auf N0 abbilden, wie zum Beispiel √ f1 (n) = log(n), f2 (n) = n/10 − 1000, f3 (n) = n, verwenden wir bei der Aufwandsabschätzung immer die Funktionen f : N0 → N0 mit f (n) = max{0, df (n)e}, auch wenn wir f (n) schreiben. 9 / 21 Das O-Kalkül Definition Sei g : N0 → N0 eine Funktion. Dann ist O(g ) = ∃c ∈ N : ∃ n0 ∈ N : ∀ n ∈ N : f : N0 → N 0 . n ≥ n0 ⇒ f (n) ≤ c · g (n) O(g ) ist die Menge der Funktionen, die asymptotisch höchstens so stark wachsen wie g . 10 / 21 Das O-Kalkül Beispiel Sei g (n) = n, dann ist • 7n + 18 ∈ O(g ) • n/2 ∈ O(g ) √ • 4 n ∈ O(g ) • 2 log(n) ∈ O(g ) • 17 ∈ O(g ) • n2 ∈ / O(g ) • 2n ∈ / O(g ) • e 3n ∈ / O(g ) 11 / 21 Das O-Kalkül Sei g : N0 → N0 und f : N0 → N0 ∈ O(g ), dann gilt: a · f (n) + b ∈ O(g ), ∀ a, b ∈ R. Einige Rechenregeln: ∀g : N0 → N0 : ∀f ∈ O(g ) : ∀c ∈ R : • f (n) + c ∈ O(g ) • f (n) · c ∈ O(g ) ∀g1 , g2 : N0 → N0 : ∀f1 ∈ O(g1 ) : ∀f2 ∈ O(g2 ) : • f1 + f2 ∈ O(g1 + g2 ) • f1 · f2 ∈ O(g1 · g2 ) • O(g1 ) ⊂ O(g2 ) ⇒ O(g1 + g2 ) = O(g2 ) 12 / 21 Das O-Kalkül Wir schreiben: O(n) O(n2 ) O(log(n)) √ O( n) O(2n ) O(1) für für für für für für O(g ), O(g ), O(g ), O(g ), O(g ), O(g ), falls falls falls falls falls falls g (n) = n g (n) = n2 g (n) = √ log(n) g (n) = n g (n) = 2n g (n) = 1 Definition Ein Algorithmus A hat eine Worst-Case-Laufzeit aus O(g ), falls TA ∈ O(g ). 13 / 21 Das O-Kalkül Beispiel Algorithmus: Doppelter Eintrag Eingabe: a0 , . . . , an−1 ∈ N0 Ausgabe: Doppelt ∈ {true, false} Doppelt ⇔ ∃i, j ∈ {0, . . . , n − 1} : ai = aj ∧ i 6= j Eingabegröße: n 1: for (i := 0, i < n, i++) 2: for (j := i + 1, j < n, i++) 3: if (a[i] = a[j]) then 4: return(true); 5: return(false); 14 / 21 Das O-Kalkül Beispiel Im Worst-Case(!) sind alle Zahlen paarweise verschieden. In diesem Fall führt der Algorithmus für Eingabefolgen mit n Zahlen die Anweisungen 1,2,3,4,5 wie folgt aus: • 1 mal die Anweisungen 1, → O(1) • n mal die Anweisungen 2,→ O(n) • n − 1 + n − 2 + · · · + 2 + 1 mal die Anweisung 3, → O(n2 ) • höchstens 1 mal die Anweisung 4, → O(1) • höchstens 1 mal die Anweisung 5, → O(1) Der Algorithmus Doppelter Eintrag“ hat eine Worst-Case Laufzeit aus ” O(1 + n + n2 + 1 + 1) = O(n2 ). 15 / 21 Das O-Kalkül Die häufigsten Aufwandsklassen: O(1) O(log(n)) √ O( n) O(n) O(n log(n)) O(n2 ) O(n3 ) O(nc ) O(2n ) O(c n ) konstant logarithmisch Wurzel linear loglinear quadratisch kubisch polynomiell (c konstant) exponentiell exponentiell (c > 1 konstant) 16 / 21 Das O-Kalkül Definition Sei g : N0 → N0 eine Funktion. Dann ist “Omega von g ”: Ω(g ) := {f : N0 → N0 | g ∈ O(f )} bzw. Ω(g ) := ∃ c ∈ N : ∃ n0 ∈ N : ∀ n ∈ N : f : N0 → N0 . n ≥ n0 ⇒ c · f (n) ≥ g (n) Ω(g ) ist die Menge der Funktionen, die asymptotisch mindestens so stark wachsen wie g . 17 / 21 Das O-Kalkül Definition Sei g : N0 → N0 eine Funktion. Dann ist “Theta von g ”: Θ(g ) := {f : N0 → N0 | f ∈ O(g ) ∧ g ∈ O(f )} bzw. Θ(g ) := f : N0 → N0 ∃ c1 , c2 ∈ N : ∃ n0 ∈ N : ∀ n ∈ N : n ≥ n0 ⇒ c1 · f (n) ≥ g (n) ∧ c2 · g (n) ≥ f (n) bzw. Θ(g ) := O(g ) ∩ Ω(g ) Θ(g ) ist die Menge der Funktionen, die asymptotisch genauso stark wachsen wie g . 18 / 21 Das O-Kalkül Beispiel 6n3 + 2n2 + 7n − 10 n2 log(n) nk für k > 0 und c > 1 log(n)k für k > 0 ∈ O(n3 ) 6∈ O(n2 ) ∈ O(c n ) ∈ O(n) ∈ Ω(n3 ) ∈ Ω(n2 ) 6∈ Ω(c n ) 6∈ Ω(n) ∈ Θ(n3 ) 6∈ Θ(n2 ) 6∈ Θ(c n ) 6∈ Θ(n) Die häufigsten Aufwandsklassen und ihre Inklusionen: O(1) ( ( ( ( ( ( ( ( ( O(log(n)) O(log(n)2 ) √ √ 1 n = n2 O( n) O(n) O(n log(n)) O(n2 ) O(n3 ) O(2n ) O(3n ) 19 / 21 Das O-Kalkül Definition Sei g : N0 → N0 eine Funktion. Dann ist o(g ) := ∀c ∈ N : ∃ n0 ∈ N : ∀ n ∈ N : f : N0 → N0 n ≥ n0 ⇒ c · f (n) < g (n) bzw. o(g ) := O(g ) \ Ω(g ) ∀c ∈ N : ∃ n0 ∈ N : ∀ n ∈ N : f : N0 → N0 . bzw. n ≥ n0 ⇒ f (n) > c · g (n) ω(g ) := Ω(g ) \ O(g ) und ω(g ) := o(g ) ist die Menge der Funktionen, die asymptotisch echt schwächer wachsen als g . ω(g ) ist die Menge der Funktionen, die asymptotisch echt stärker wachsen als g . 20 / 21 Das O-Kalkül Die Symbole O, Θ, Ω, o, ω werden auch Landau-Symbole genannt. (Edmund Landau, 1924) Hin und wieder und insbesondere im nordamerikanischen Raum wird die Schreibweise f = O(g ) anstatt f ∈ O(g ) verwendet. Dies hat historische Grunde und kommt ursprünglich aus der analytischen Zahlentheorie. 21 / 21