Was bisher geschah I Definition Algorithmus I Eigenschaften von Algorithmen I Spezifikation von Berechnungsproblemen I Instanzen von Berechnungsproblemen I Spezifikation des Sortierproblemes I Korrektheit von Algorithmen Algorithmenentwurf: I 1. Spezifikation (Vor- und Nachbedingungen) 2. Entwurf 3. Verifikation 1 Ziele beim Entwurf von Algorithmen I I Korrektheit geriner Ressourcenverbrauch I I I Laufzeit Speicherplatz sinnvoll strukturierte einfache formale Beschreibung (z.B. kurzer, lesbarer Programmcode) “ . . . there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” Tony Hoare, 1980 ACM Turing Award Lecture 2 Beispiel – Summe der ersten n natürlichen Zahlen informale Aufgabenstellung: Addiere alle natürlichen Zahlen von 1 bis n. Spezifikation: Vorbedingung: Eingabe n ∈ NP Nachbedingung: Ausgabe s = n i=1 i Algorithmus : A1 Eingabe : n ∈ Ausgabe : s N s←0 für jedes i ← 1, . . . , n : s ←s+i Algorithmus : A2 Eingabe : n ∈ Ausgabe : s N s ← n(n + 1)/2 3 (Idealisiertes) Rechnermodell Random-Access-Maschine (RAM) I I unendlich viele Speicherzellen für je eine natürliche Zahl (Alternative: Real-RAM für reelle Zahlen) Befehle: I I I I Laden Speichern Operationen (logisch, arithmetisch, Vergleiche) Unterprogrammaufrufe I Ausführung jedes Befehles (elementare Anweisung, Schritt) dauert (kostet) genau eine Einheit I sequentielle Ausführung aller Befehle 4 Laufzeitanalyse Laufzeit eines Algorithmus auf der Eingabe x: Anzahl der zur Ausführung des Algorithmus bei Eingabe x benötigten Einheiten (Schritte) Laufzeit T eines Algorithmus ist eine Funktion der Größe der Eingabe Definition der Größe hängt vom Berechnungsproblem ab, z.B. Länge einer zu sortierenden Liste, Länge der Binärdarstellung zweier zu addierender Zahlen worst-case Maximum der Laufzeiten des Algorithmus über alle Eingaben obere Schranke für die Laufzeit best-case Minimum der Laufzeiten des Algorithmus über alle Eingaben untere Schranke für die Laufzeit average-case Durchschnitt der Laufzeiten des Algorithmus über alle Eingaben 5 Beispiel: Durchsuchen einer Folge Spezifikation des Suchproblemes: V: Eingaben x = (x1 , . . . , xn ), y N: Ausgabe: I Ja, falls ein i ∈ {1, . . . , n} mit xi = y existiert, I sonst Nein Algorithmus : Suche 1 Eingabe : (x1 , . . . , xn ), y Ausgabe : gefunden gefunden ← Nein für jedes i ← 1, . . . , n : wenn xi = y dann gefunden ← Ja Laufzeit (Tafel) 6 Mathematische Grundlagen: Wachstumsklassen präzise Laufzeitfunktion meist nicht relevant, nur die Größenordnung des Wachstums Ziel: Abschätzung der Größenordnung der Wachstumsfunktion durch Vergleich mit einfachen Funktionen Abschätzungen des asymptotischen Wachstums gelten nur für hinreichend große Werte 7 Wachstumsklassen Funktionenklassen zu einer gegebenen Funktion g : N → R≥0 N R N N R N N R N N R N∃c > 0∀n ≥ n0 : 0 ≤ cg(n) < f (n)} O(g) = {f : → ≥0 | ∃n0 ∈ ∃c > 0∀n ≥ n0 : f (n) ≤ cg(n)} f wächst höchstens so schnell wie g (asymptotische obere Wachstumsschranke) o(g) = {f : → ≥0 | ∃n0 ∈ ∃c > 0∀n ≥ n0 : f (n) < cg(n)} f wächst langsamer als g Ω(g) = {f : → ≥0 | ∃n0 ∈ ∃c > 0∀n ≥ n0 : 0 ≤ cg(n) ≤ f (n)} f wächst mindestens so schnell wie g (asymptotische untere Wachstumsschranke) ω(g) = {f : → ≥0 | ∃n0 ∈ f wächst schneller als g Θ(g) = O(g) ∩ Ω(g) (asymptotisch gleiches Wachstum) Gilt genau dann, wenn f ∈ O(g) und g ∈ O(f ) 8 Asymptotische obere Schranke O(g) = {f : N → R≥0 | ∃n0 ∈ N∃c > 0∀n ≥ n0 : f (n) ≤ cg(n)} Beispiele: I 3/2n2 + 3/2n + 2 ∈ O(n2 ) I n ∈ O(n3 ) I 2n 6∈ O(n3 ) geeignete Abschätzung für worst-case-Analyse 9 Vereinfachungen in O-Notation I O(cf ) = O(f ), konstante Faktoren irrelevant I O(f + g) = max(O(f ), O(g)), Summanden mit kleinerem Wachstum irrelevant, z.B. Polynome kleineren Grades I O(loga n) = O(logb n) 10 Berechnung durch Grenzwerte 1000n5 − 5463524n4 + 13n3 + n2 ∈ O(n5 ) wegen 1000n5 − 5463524n4 + 13n3 + n2 n→∞ n5 5 1000n = lim = 1000 < ∞ n→∞ n5 lim Beispiele: I O(n/2) = O(134n) = O(n − 5000) = O(n − 5000) = O(17n − 5000) = O(n/5000) = O(n) I O(log n) ⊆ O(n) ⊆ O(n2 ) ⊆ O(2n ) 11 Beispiele I n + 1000 ∈ O(n) I 1000n ∈ O(n) I I 1000n ∈ O(n2 ) √ 1000n 6∈ O( n) I 1000n5 + 3524n2 ∈ O(n5 ) I 1000n5 + 3524n2 ∈ O(n6 ) I n/1000 + 3524 ∈ O(n) I loga n ∈ O(logb n) 12 Wichtige Funktionenklassen I O(1) konstantes Wachstum I O(n) lineares Wachstum I O(n2 ) quadratisches Wachstum I O(n3 ) kubisches Wachstum I O(nk ) polynomielles Wachstum I O(log n) logarithmisches Wachstum I O(n log n) I O(log log n) doppelt logarithmisches Wachstum I O(2n ) exponentielles Wachstum 13 Laufzeitabschätzungen für Steuerstrukturen elementare Operationen A (Zuweisung, Berechnung eines arithmetischen Ausdruckes, Vergleich) T (A) = 1 ∈ O(1) sequentielle Verknüpfung (Nacheinanderausführung) Algorithmus A = A_1; A_2 Laufzeit T (A) = T (A1 ) + T (A2 ) Verzweigung (Alternative) Algorithmus A = if C then A_1 else A_2 Laufzeit T (A) = max(T (A1 ), T (A2 )) ∈ O(T (A1 ) + T (A2 )) Wiederholung (Schleife) Algorithmus A = for i = 1 to n A_i Laufzeit T (A) = T (A1 ) + T (A2 ) + . . . + T (An ) oft für jeden Durchlauf gleiche Laufzeit, dann T (A) = nT (A1 ) 14 Beispiel: Suche 2 Spezifikation des Suchproblemes: V: Eingaben x = (x1 , . . . , xn ), y N: Ausgabe: I Ja, falls ein i ∈ {1, . . . , n} mit xi = y existiert, I sonst Nein Algorithmus : Suche 2 Eingabe : (x1 , . . . , xn ), y Ausgabe : gefunden gefunden ← Nein i ←1 solange gefunden = Nein und i ≤ n : wenn xi = y dann gefunden ← Ja i ←i +1 15 Laufzeiten I Suche 1 best falls y = x1 : T (n) ∈ O(n) worst falls y nicht in x vorkommt: T (n) ∈ O(n) average T (n) ∈ O(n) I Suche 2 best falls y = x1 : T (n) ∈ O(1) worst falls y nicht in x vorkommt: T (n) ∈ O(n) average T (n) ∈ O(n) 16 Beispiel Minimum-Suche Spezifikation: I I Eingabe x = (x1 , . . . , xn ) Ausgabe y mit 1. y ∈ {x1 , . . . , xn } und 2. ∀z ∈ {x1 , . . . , xn } : y ≤ z Algorithmus : Minimum-Suche Eingabe : (x1 , . . . , xn ) Ausgabe : y y ← x1 für jedes i ← 2, . . . , n : wenn y > xi dann y ← xi Laufzeit: O(n) 17 Beispiele Für alle Algorithmen: Eingabe : n Ausgabe : s Algorithmus : A Algorithmus : B k ← 52; s ← 5 für jedes i ← 1, . . . , n : für jedes j ← 1, . . . , k : s ← n + ij k ← 52; s ← 5 für jedes i ← 1, . . . , n : für jedes j ← 1, . . . , n : s ← n + ij Algorithmus : C k ← 52; s ← 5 für jedes i ← 1, . . . , n : für jedes j ← 1, . . . , i : s ←i +j T (A) ∈ 0(n) T (B) ∈ 0(n2 ) T (C) ∈ 0(n2 ) 18