490 likes | 584 Views
Datenstrukturen, Algorithmen und Programmierung 2 (DAP2). Organisatorisches. Praktikum Falls Sie einen eigenen Laptop mit einem C-Compiler besitzen, können Sie diesen gerne zum Praktikum mitbringen. Organisatorisches. Lernräume Montag: 14.30-17.30 Uhr (OH14, Raum 340)
E N D
Organisatorisches Praktikum • Falls Sie einen eigenen Laptop mit einem C-Compiler besitzen, können Sie diesen gerne zum Praktikum mitbringen
Organisatorisches Lernräume • Montag: 14.30-17.30 Uhr (OH14, Raum 340) • Dienstag: 15-18 Uhr (OH14, Raum 340) • Mittwoch: 13-16 Uhr (OH14, Raum 340) • Donnerstag: 9-12 Uhr (GB V, Raum 105)
1. Teil der Vorlesung – Grundlagen der Algorithmenanalyse Inhalt • Wie beschreibt man einen Algorithmus? • Wie beweist man die Korrektheit eines Algorithmus? • Rechenmodell • Laufzeitanalyse
Laufzeitanalyse InsertionSort(Array A) Eingabegröße n • for j 2 to length[A] do length[A] = n • key A[j] • i j-1 verschiebe alle Elemente aus • while i>0 and A[i]>key do A[1…j-1], die größer als key • A[i+1] A[i] sind eine Stelle nach rechts • i i-1 • A[i+1] key Speichere key in Lücke Fragestellung Wie kann man die Laufzeit eines Algorithmus vorhersagen?
Laufzeitanalyse Laufzeit hängt ab von • Größe der Eingabe (Parameter n) • Art der Eingabe(Insertionsort ist schneller auf sortierten Eingaben) Analyse • Parametrisiere Laufzeit als Funktion der Eingabegröße • Finde obere Schranken (Garantien) an die Laufzeit
Laufzeitanalyse Worst-Case Analyse • Für jedes n definiere Laufzeit T(n) = Maximum über alle Eingaben der Größe n • Garantie für jede Eingabe • Standard Average-Case Analyse • Für jedes n definiere Laufzeit T(n) = Durchschnitt über alle Eingaben der Größe n • Hängt von Definition des Durchschnitts ab (wie sind die Eingaben verteilt)
Laufzeitanalyse Laufzeit hängt auch ab von • Hardware (Prozessor, Cache, Pipelining) • Software(Betriebssystem, Programmiersprache, Compiler) Aber • Analyse soll unabhängig von Hard- und Software gelten
Laufzeitanalyse Maschinenmodell • Eine Pseudocode-Instruktion braucht einen Zeitschritt • Wird eine Instruktion r-mal aufgerufen, werden r Zeitschritte benötigt • Formales Modell: Random Access Machines (RAM Modell) Idee • Ignoriere rechnerabhängige Konstanten • Betrachte Wachstum von T(n) für n „Asymptotische Analyse“
Laufzeitanalyse InsertionSort(Array A) Zeit: • for j 2 to length[A] do n • key A[j] • i j-1 • while i>0 and A[i]>key do • A[i+1] A[i] • i i-1 • A[i+1] key
Laufzeitanalyse InsertionSort(Array A) Zeit: • for j 2 to length[A] do n • key A[j] n-1 • i j-1 • while i>0 and A[i]>key do • A[i+1] A[i] • i i-1 • A[i+1] key
Laufzeitanalyse InsertionSort(Array A) Zeit: • for j 2 to length[A] do n • key A[j] n-1 • i j-1 n-1 • while i>0 and A[i]>key do • A[i+1] A[i] • i i-1 • A[i+1] key
Laufzeitanalyse InsertionSort(Array A) Zeit: • for j 2 to length[A] do n • key A[j] n-1 • i j-1 n-1 • while i>0 and A[i]>key do n-1 + S t • A[i+1] A[i] • i i-1 • A[i+1] key t : Anzahl Wiederholungen der while-Schleife bei Laufindex j j j
Laufzeitanalyse InsertionSort(Array A) Zeit: • for j 2 to length[A] do n • key A[j] n-1 • i j-1 n-1 • while i>0 and A[i]>key do n-1 + S t • A[i+1] A[i]S t • i i-1 • A[i+1] key t : Anzahl Wiederholungen der while-Schleife bei Laufindex j j j j
Laufzeitanalyse InsertionSort(Array A) Zeit: • for j 2 to length[A] do n • key A[j] n-1 • i j-1 n-1 • while i>0 and A[i]>key do n-1 + S t • A[i+1] A[i]S t • i i-1 S t • A[i+1] key t : Anzahl Wiederholungen der while-Schleife bei Laufindex j j j j j
Laufzeitanalyse InsertionSort(Array A) Zeit: • for j 2 to length[A] do n • key A[j] n-1 • i j-1 n-1 • while i>0 and A[i]>key do n-1 + S t • A[i+1] A[i]S t • i i-1 S t • A[i+1] key n-1 t : Anzahl Wiederholungen der while-Schleife bei Laufindex j j j j j
Laufzeitanalyse InsertionSort(Array A) Zeit: • for j 2 to length[A] do n • key A[j] n-1 • i j-1 n-1 • while i>0 and A[i]>key do n-1 + S t • A[i+1] A[i]S t • i i-1 S t • A[i+1] key n-1 t : Anzahl Wiederholungen der while-Schleife bei Laufindex j j j j 5n-4+3S t j j
Laufzeitanalyse Worst-Case Analyse • t =j-1 für absteigend sortierte Eingabe (schlechtester Fall) j
Laufzeitanalyse Worst-Case Analyse • t =j-1 für absteigend sortierte Eingabe (schlechtester Fall) j
Laufzeitanalyse Worst-Case Analyse • t =j-1 für absteigend sortierte Eingabe (schlechtester Fall) • Abstraktion von multiplikativen Konstanten O-Notation (gleich) j
Laufzeitanalyse Beispiel • Problem: Nullvektortest • Eingabe: Feld A[1,…,n] (n-dimensionaler Vektor) • Ausgabe: true, wenn A[i]=0, für alle 1in; false, sonst Nullvektortest(Array A) 1. outputtrue 2. i1 3. whileoutput=trueandindo 4. if A[i] <> 0 thenoutputfalse 5. ii+1 6. returnoutput
Laufzeitanalyse • Invariante: • Nach dem k-ten Schleifendurchlauf gilt: • i=k+1 und • output=true, gdw. A[j]=0 für alle 1jk Beispiel • Problem: Nullvektortest • Eingabe: Feld A[1,…,n] (n-dimensionaler Vektor) • Ausgabe: true, wenn A[i]=0, für alle 1in; false, sonst Nullvektortest(Array A) 1. outputtrue 2. i1 3. whileoutput=trueandindo 4. if A[i] <> 0 thenoutputfalse 5. ii+1 6. returnoutput
Laufzeitanalyse Nullvektortest(Array A) 1. output true 2. i1 3. while output=true and in do 4. if A[i] <> 0 then output false 5. ii+1 6. return output Laufzeit • Jede Anweisung braucht einen Zeitschritt
Laufzeitanalyse Laufzeit parametrisiert durch Länge der Eingabe n. Hier ist n = length[A]. Nullvektortest(Array A) 1. output true 2. i1 3. while output=true and in do 4. if A[i] <> 0 then output false 5. ii+1 6. return output Laufzeit • Jede Anweisung braucht einen Zeitschritt
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 3. while output=true and in do 4. if A[i] <> 0 then output false 5. ii+1 6. return output Laufzeit • Jede Anweisung braucht einen Zeitschritt
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do 4. if A[i] <> 0 then output false 5. ii+1 6. return output Laufzeit • Jede Anweisung braucht einen Zeitschritt
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do 4. if A[i] <> 0 then output false 5. ii+1 6. return output Laufzeit • Jede Anweisung braucht einen Zeitschritt Anzahl Durchläufe abhängig vonEingabe.
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do 4. if A[i] <> 0 then output false 5. ii+1 6. return output Definition • t=max{i: A[j]=0 für alle 0j<i; in} Anzahl Durchläufe abhängig vonEingabe. t=3
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false 5. ii+1 6. return output Definition • t=max{i: A[j]=0 für alle 0j<i; in} t=3
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 6. return output Definition • t=max{i: A[j]=0 für alle 0j<i; in} t=3
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 t 6. return output Definition • t=max{i: A[j]=0 für alle 0j<i; in} t=3
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 t 6. return output 1 Definition • t=max{i: A[j]=0 für alle 0j<i; in} t=3
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 t 6. return output 1 3t+4
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 t 6. return output 1 3t+4 Worst-Case Laufzeit • T(n) = maximale Laufzeit von Nullvektortest bei Eingabe der Länge n
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 t 6. return output 1 3t+4 Worst-Case Laufzeit • T(n) = maximale Laufzeit von Nullvektortest bei Eingabe der Länge n • T(n) ≤ 3n+4, da t maximal n ist
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 t 6. return output 1 3t+4 Worst-Case Laufzeit • T(n) = maximale Laufzeit von Nullvektortest bei Eingabe der Länge n • T(n) ≤ 3n+4, da t maximal n ist • T(n) ≥ 3n+4, da bei Eingabe eines Nullvektors 3n+4 Schritte benötigt werden
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 t 6. return output 1 3t+4 Worst-Case Laufzeit • T(n) = maximale Laufzeit von Nullvektortest bei Eingabe der Länge n • Also: T(n) = 3n+4
Laufzeitanalyse Diskussion • Die konstanten Faktoren sind wenig aussagekräftig, da wir bereits bei den einzelnen Befehlen konstante Faktoren ignorieren • Je nach Rechnerarchitektur und genutzten Befehlen könnte also z.B. 3n+4 langsamer sein als 5n+7 • Betrachte nun Algorithmus A mit Laufzeit 100n und Algorithmus B mit Laufzeit 5n² • Ist n klein, so ist Algorithmus B schneller • Ist n groß, so wird das Verhältnis Laufzeit B / Laufzeit A beliebig groß • Algorithmus B braucht also einen beliebigen Faktor mehr Laufzeit als A(wenn die Eingabe lang genug ist)
Laufzeitanalyse Idee (asymptotische Laufzeitanalyse) • Ignoriere konstante Faktoren • Betrachte das Verhältnis von Laufzeiten für n • Klassifiziere Laufzeiten durch Angabe von „einfachen Vergleichsfunktionen“ Beispiel • Die Laufzeit von Algorithmus Nullvektortest verhält sich für n(bei Ignorieren von Konstanten) wie f(n) = n.
Laufzeitanalyse O-Notation • O(f(n)) = {g(n) : c>0, n >0, so dass für alle n≥n gilt g(n) cf(n)} • (wobei f(n), g(n)>0) Interpretation • g(n)O(f(n)) bedeutet, dass g(n) für n höchstens genauso stark wächst wie f(n) • Beim Wachstum ignorieren wir Konstanten 0 0
Laufzeitanalyse Beispiele • 10nO(n) • 10nO(n²) • n²O(1000n) • O(1000n) = O(n) Hierarchie • O(log n)O(log²n)O(log n)O(n )O(n)O(n) • O(n)O(n²)O(n )O(2 ) • (für c>=2 und 0<e1/2) e c n c
Laufzeitanalyse W-Notation • W(f(n)) = {g(n) : c>0, n >0, so dass für alle n≥n gilt g(n) cf(n)} • (wobei f(n), g(n)>0) Interpretation • g(n)W(f(n)) bedeutet, dass g(n) für nmindestens so stark wächst wie f(n) • Beim Wachstum ignorieren wir Konstanten 0 0
Laufzeitanalyse Beispiele • 10nW(n) • 1000nW(n²) • n²W(n) • W(1000n) = W(n) • f(n) = W(g(n)) g(n) = O(f(n))
Laufzeitanalyse Q-Notation • g(n) Q(f(n)) g(n)=O(f(n)) und g(n)=W(f(n)) Beispiele • 1000n Q(n) • 10n²+1000n Q(n²) • n Q(n) 1-sin n
Laufzeitanalyse o-Notation • o(f(n)) {g(n): c>0 n >0, so dass für alle n≥n gilt cg(n)<f(n)} • (f(n), g(n) >0) w-Notation • f(n)w(g(n)) g(n)o(f(n)) 0 0
Laufzeitanalyse Beispiele • no(n²) • no(n) Eine weitere Interpretation • Grob gesprochen sind O,W,Q,o,w die „asymptotischen Versionen“ von ,,=,<,> (in dieser Reihenfolge) Schreibweise • Wir schreiben häufig f(n)=O(g(n)) anstelle von f(n)O(g(n))
Laufzeitanalyse Nullvektortest(Array A) Zeit 1. output true 1 2. i1 1 3. while output=true and in do t+1 4. if A[i] <> 0 then output false t 5. ii+1 t 6. return output 1 3t+4 Worst-Case Laufzeit • T(n) = maximale Laufzeit von Nullvektortest bei Eingabe der Länge n • Also: T(n) = 3n+4 = Q(n)
Laufzeitanalyse Worst-Case Analyse (Insertion Sort) • t =j-1 für absteigend sortierte Eingabe (schlechtester Fall) j
Zusammenfassung Rechenmodell • Abstrahiert von maschinennahen Einflüssen wie Cache, Pipelining, Prozessor, etc. • Jede Pseudocodeoperation braucht einen Zeitschritt Laufzeitanalyse • Normalerweise Worst-Case, manchmal Average-Case (sehr selten auch Best-Case) • Asymptotische Analyse für n • Ignorieren von Konstanten O-Notation