Grundlagen: Algorithmen und Datenstrukturen Hanjo Täubig Lehrstuhl für Effiziente Algorithmen (Prof. Dr. Ernst W. Mayr) Institut für Informatik Technische Universität München Sommersemester 2011 H. Täubig (TUM) GAD SS’11 1 / 604 Einführung Beispiele Kreis zeichnen Wie kann ein Computer einen Kreis zeichnen? H. Täubig (TUM) GAD SS’11 24 / 604 Einführung Beispiele Kreis zeichnen: mit Winkelfunktionen Naiver Ansatz: Verwendung von sin und cos für α = 0 . . . 2π y=R sin(α) α −R H. Täubig (TUM) x=R cos(α) GAD R SS’11 25 / 604 Einführung Beispiele Kreis zeichnen: mit Winkelfunktionen Kreis1 Eingabe : radius R for i = 0; i < n; i++ do plot(R ∗ cos(2π ∗ i/n), R ∗ sin(2π ∗ i/n)); Kreisumfang: u = 2π · R ⇒ Bei Pixelbreite von 1 Einheit reicht n = 7R. Problem: sin und cos sind teuer! H. Täubig (TUM) GAD SS’11 26 / 604 Einführung Beispiele Kreis zeichnen: mit Wurzelfunktion Besserer Ansatz: x2 + y2 = R2 √ y = ± R2 − x2 bzw. R x −R H. Täubig (TUM) GAD y R SS’11 27 / 604 Einführung Beispiele Kreis zeichnen: mit Wurzelfunktion Kreis2 Eingabe : radius R for x = −R; x ≤ R; x++ do y = sqrt(R ∗ R − x ∗ x); plot(x, y); plot(x, -y); Problem: sqrt ist auch noch relativ teuer! H. Täubig (TUM) GAD SS’11 28 / 604 Einführung Beispiele Kreis zeichnen: mit Multiplikation Besserer Ansatz: Ausnutzung von Spiegelachsen (x,y) (−x,y) (y,x) (−y,x) −R R (y,−x) (−y,−x) (x,−y) (−x,−y) H. Täubig (TUM) GAD SS’11 29 / 604 Einführung Beispiele Kreis zeichnen: mit Multiplikation Noch besserer Ansatz: Ist der Grundlinienmittelpunkt des Pixels innerhalb des Kreises? ja: x ← x + 1, nein: x ← x + 1, y ← y − 1 H. Täubig (TUM) GAD SS’11 30 / 604 Einführung Beispiele Kreis zeichnen: mit Multiplikation Mittelpunkt des ersten Quadrats: (x, y) = (0, R) Position seines Grundlinienmittelpunkts: (0, R − 12 ) Test, ob (x, y) innerhalb des Kreises: F(x, y) := x 2 + y 2 − R 2 < 0 1. Quadrat: F(0, R − 12 ) = 02 + (R − 12 )2 − R 2 = Quadrat rechts daneben: F(1, R − 12 ) = 12 + (R − 12 )2 − R 2 = 54 − R < 0? Update: 1 4 − R < 0? F(x + 1, y) = (x + 1)2 + y 2 − R 2 = (x 2 + 2x + 1) + y 2 − R 2 F(x + 1, y) = F(x, y) + 2x + 1 F(x + 1, y − 1) = (x + 1)2 + (y − 1)2 − R 2 = (x 2 + 2x + 1) + (y 2 − 2y + 1) − R 2 F(x + 1, y − 1) = F(x, y) + 2x − 2y + 2 H. Täubig (TUM) GAD SS’11 31 / 604 Einführung Beispiele Kreis zeichnen: mit Multiplikation Bresenham1 x = 0; y = R; plot(0, R); plot(R, 0); plot(0, −R); plot(−R, 0); F = 54 − R; while x < y do if F < 0 then F = F + 2 ∗ x + 1; else F = F + 2 ∗ x − 2 ∗ y + 2; y = y − 1; x = x + 1; plot(x, y); plot(−x, y); plot(−y, x); plot(−y, −x); plot(y, x); plot(y, −x); plot(x, −y); plot(−x, −y); Es geht sogar noch etwas schneller! H. Täubig (TUM) GAD SS’11 32 / 604 Einführung Beispiele Kreis zeichnen: mit Addition / Subtraktion Ersetzung der Korrekturterme für F: F = F + 2x + 1 → F = F + dE F = F + 2x − 2y + 2 → F = F + dSE mit dE = 2x + 1 Anfangswerte: und dSE = 2x − 2y + 2 dE (0, R) = 2 · 0 + 1 = 1 dSE (0, R) = 2 · 0 − 2 · R + 2 = 2 − 2 · R Updates nach rechts (E) und nach unten rechts (SE): dE (x + 1, y) = 2 · (x + 1) + 1 = dE (x, y) + 2 dSE (x + 1, y) = 2 · (x + 1) − 2 · y − 2 = dSE (x, y) + 2 dE (x + 1, y − 1) = 2 · (x + 1) + 1 = dE (x, y) + 2 dSE (x + 1, y − 1) = 2 · (x + 1) − 2 · (y − 1) + 2 = dSE (x, y) + 4 H. Täubig (TUM) GAD SS’11 33 / 604 Einführung Beispiele Kreis zeichnen: mit Addition / Subtraktion Der Bruch 54 kann durch 1 ersetzt werden, weil sich F immer um eine ganze Zahl ändert. D.h. F= 5 −R +k <0 4 ist äquivalent zu F =1−R +k <0 Vorteil: nur noch ganze Zahlen! H. Täubig (TUM) GAD SS’11 34 / 604 Einführung Beispiele Kreis zeichnen: mit Addition / Subtraktion Bresenham2 x = 0; y = R; plot(0, R); plot(R, 0); plot(0, −R); plot(−R, 0); F = 1 − R; dE = 1; dSE = 2 − R − R; while x < y do if F < 0 then F = F + dE ; dSE = dSE + 2; else F = F + dSE ; y = y − 1; dSE = dSE + 4; x = x + 1; dE = dE + 2; plot(x, y); plot(−x, y); plot(−y, x); plot(−y, −x); plot(y, x); plot(y, −x); plot(x, −y); plot(−x, −y); H. Täubig (TUM) GAD SS’11 35 / 604 Einführung Beispiele Bresenham-Algorithmus von Anfang der 1960er Jahre hat Jack Bresenham Algorithmen zur Linien- und Kreisdarstellung entwickelt Diese verwenden nur einfache Additionen ganzer Zahlen und sind damit deutlich schneller als die naiven Ansätze. Diese und weitere Beispiele: Taschenbuch der Algorithmen (Springer, 2008) H. Täubig (TUM) GAD SS’11 36 / 604 Effizienz Übersicht 3 Effizienz Effizienzmaße Rechenregeln für O-Notation Maschinenmodell Java Laufzeitanalyse Durchschnittliche Laufzeit H. Täubig (TUM) GAD SS’11 37 / 604 Effizienz Effizienzmaße Übersicht 3 Effizienz Effizienzmaße Rechenregeln für O-Notation Maschinenmodell Java Laufzeitanalyse Durchschnittliche Laufzeit H. Täubig (TUM) GAD SS’11 38 / 604 Effizienz Effizienzmaße Effizienzmessung Exakte Spezifikation der Laufzeit eines Algorithmus (bzw. einer DS-Operation): Menge I der Instanzen Laufzeit des Algorithmus T : I 7→ N Problem: T sehr schwer exakt bestimmbar Lösung: Gruppierung der Instanzen (meist nach Größe) H. Täubig (TUM) GAD SS’11 39 / 604 Effizienz Effizienzmaße Eingabekodierung Was ist die Größe einer Instanz? Speicherplatz in Bits oder Wörtern Aber Vorsicht bei der Kodierung! Beispiel: Gegeben: Gesucht: Primfaktorisierung Zahl x ∈ N Primfaktoren von x (Primzahlen p1 , . . . , pk mit x = Q i piei ) Bekannt als hartes Problem (wichtig für RSA!) H. Täubig (TUM) GAD SS’11 40 / 604 Effizienz Effizienzmaße Eingabekodierung - Beispiel Primfaktorisierung Trivialer Algorithmus j√ k Teste von y = 2 bis x alle Zahlen, ob diese x teilen und wenn ja, dann bestimme wiederholt das Ergebnis der Division bis die Teilung nicht mehr ohne Rest möglich ist √ Laufzeit: x Teilbarkeitstests und höchstens log2 x Divisionen Unäre Kodierung von x (x Einsen als Eingabe): Laufzeit linear, Anzahl der Teilbarkeitstests und Divisionen ist sogar sublinear, aber die Eingabe muss einmal ganz gelesen werden Binäre Kodierung von x (dlog2 xe Bits): (bezüglich der Länge der Eingabe) H. Täubig (TUM) GAD Laufzeit exponentiell SS’11 41 / 604 Effizienz Effizienzmaße Eingabekodierung Betrachtete Eingabegröße: Größe von Zahlen: binäre Kodierung Größe von Mengen / Folgen von Zahlen: Hier wird oft nur die Anzahl der Elemente betrachtet(!) Beispiel (Sortieren) Gegeben: Folge von Zahlen a1 , . . . , an ∈ N Gesucht: sortierte Folge der Zahlen Größe der Eingabe: n H. Täubig (TUM) GAD SS’11 42 / 604 Effizienz Effizienzmaße Effizienzmessung Für ein gegebenes Problem sei In die Menge der Instanzen der Größe n. Effizienzmaße: Worst case: t(n) = max{T (i) : i ∈ In } Average case: t(n) = 1 X T (i) |In | i∈In Best case: t(n) = min{T (i) : i ∈ In } H. Täubig (TUM) GAD SS’11 43 / 604 Effizienz Effizienzmaße Effizienzmaße: Vor- und Nachteile worst case: liefert Garantie für die Effizienz des Algorithmus (auch wichtig für Robustheit) best case: Vergleich mit worst case liefert Aussage über die Abweichung innerhalb der Instanzen gleicher Größe average case: nicht unbedingt übereinstimmend mit dem “typischen Fall” in der Praxis (evt. schwer formal zu erfassen), kann durch Wahrscheinlichkeitsverteilung noch verallgemeinert werden exakte Formeln für t(n) meist sehr aufwendig ⇒ betrachte asymptotisches Wachstum H. Täubig (TUM) GAD SS’11 44 / 604