03.01.2015 Aufrufe

Grundlagen: Algorithmen und Datenstrukturen - Lehrstuhl für ...

Grundlagen: Algorithmen und Datenstrukturen - Lehrstuhl für ...

Grundlagen: Algorithmen und Datenstrukturen - Lehrstuhl für ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

<strong>Gr<strong>und</strong>lagen</strong>: <strong>Algorithmen</strong> <strong>und</strong> <strong>Datenstrukturen</strong><br />

Hanjo Täubig<br />

<strong>Lehrstuhl</strong> für Effiziente <strong>Algorithmen</strong><br />

(Prof. Dr. Ernst W. Mayr)<br />

Institut für Informatik<br />

Technische Universität München<br />

Sommersemester 2011<br />

H. Täubig (TUM) GAD SS’11 1 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen<br />

Wie kann ein Computer einen Kreis zeichnen<br />

H. Täubig (TUM) GAD SS’11 24 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Winkelfunktionen<br />

Naiver Ansatz:<br />

Verwendung von sin <strong>und</strong> cos für α = 0 . . . 2π<br />

y=R sin( α)<br />

−R<br />

α<br />

x=R cos( α)<br />

R<br />

H. Täubig (TUM) GAD SS’11 25 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Winkelfunktionen<br />

Kreis1<br />

Eingabe : radius R<br />

for i = 0; i < n; i++ do<br />

plot(R ∗ cos(2π ∗ i/n), R ∗ sin(2π ∗ i/n));<br />

Kreisumfang: u = 2π · R<br />

⇒ Bei Pixelbreite von 1 Einheit reicht n = 7R.<br />

Problem:<br />

sin <strong>und</strong> cos sind teuer!<br />

H. Täubig (TUM) GAD SS’11 26 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Wurzelfunktion<br />

Besserer Ansatz: x 2 + y 2 = R 2 bzw. y = ± √ R 2 − x 2<br />

R<br />

y<br />

−R<br />

x<br />

R<br />

H. Täubig (TUM) GAD SS’11 27 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Wurzelfunktion<br />

Kreis2<br />

Eingabe : radius R<br />

for x = −R; x ≤ R; x++ do<br />

y = sqrt(R ∗ R − x ∗ x);<br />

plot(x, y);<br />

plot(x, -y);<br />

Problem:<br />

sqrt ist auch noch relativ teuer!<br />

H. Täubig (TUM) GAD SS’11 28 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Multiplikation<br />

Besserer Ansatz: Ausnutzung von Spiegelachsen<br />

(−x,y)<br />

(x,y)<br />

(−y,x)<br />

(y,x)<br />

−R<br />

(−y,−x)<br />

R<br />

(y,−x)<br />

(−x,−y)<br />

(x,−y)<br />

H. Täubig (TUM) GAD SS’11 29 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Multiplikation<br />

Noch besserer Ansatz:<br />

Ist der Gr<strong>und</strong>linienmittelpunkt des Pixels innerhalb des Kreises<br />

ja: x ← x + 1, nein: x ← x + 1, y ← y − 1<br />

H. Täubig (TUM) GAD SS’11 30 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Multiplikation<br />

Mittelpunkt des ersten Quadrats: (x, y) = (0, R)<br />

Position seines Gr<strong>und</strong>linienmittelpunkts: (0, R − 1 2 )<br />

Test, ob (x, y) innerhalb des Kreises:<br />

F(x, y) := x 2 + y 2 − R 2 < 0<br />

1. Quadrat: F(0, R − 1 2 ) = 02 + (R − 1 2 )2 − R 2 = 1 4 − R < 0<br />

Quadrat rechts daneben:<br />

F(1, R − 1 2 ) = 12 + (R − 1 2 )2 − R 2 = 5 4 − R < 0<br />

Update:<br />

F(x + 1, y) = (x + 1) 2 + y 2 − R 2 = (x 2 + 2x + 1) + y 2 − R 2<br />

F(x + 1, y) = F(x, y) + 2x + 1<br />

F(x + 1, y − 1) = (x + 1) 2 + (y − 1) 2 − R 2<br />

= (x 2 + 2x + 1) + (y 2 − 2y + 1) − R 2<br />

F(x + 1, y − 1) = F(x, y) + 2x − 2y + 2<br />

H. Täubig (TUM) GAD SS’11 31 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Multiplikation<br />

Bresenham1<br />

x = 0; y = R;<br />

plot(0, R); plot(R, 0); plot(0, −R); plot(−R, 0);<br />

F = 5 4 − R;<br />

while x < y do<br />

if F < 0 then<br />

F = F + 2 ∗ x + 1;<br />

else<br />

F = F + 2 ∗ x − 2 ∗ y + 2;<br />

y = y − 1;<br />

x = x + 1;<br />

plot(x, y); plot(−x, y); plot(−y, x); plot(−y, −x);<br />

plot(y, x); plot(y, −x); plot(x, −y); plot(−x, −y);<br />

Es geht sogar noch etwas schneller!<br />

H. Täubig (TUM) GAD SS’11 32 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Addition / Subtraktion<br />

Ersetzung der Korrekturterme für F:<br />

F = F + 2x + 1 → F = F + d E<br />

F = F + 2x − 2y + 2 → F = F + d SE<br />

mit d E = 2x + 1 <strong>und</strong> d SE = 2x − 2y + 2<br />

Anfangswerte:<br />

d E (0, R) = 2 · 0 + 1 = 1<br />

d SE (0, R) = 2 · 0 − 2 · R + 2 = 2 − 2 · R<br />

Updates nach rechts (E) <strong>und</strong> nach unten rechts (SE):<br />

d E (x + 1, y) = 2 · (x + 1) + 1 = d E (x, y) + 2<br />

d SE (x + 1, y) = 2 · (x + 1) − 2 · y − 2 = d SE (x, y) + 2<br />

d E (x + 1, y − 1) = 2 · (x + 1) + 1 = d E (x, y) + 2<br />

d SE (x + 1, y − 1) = 2 · (x + 1) − 2 · (y − 1) + 2 = d SE (x, y) + 4<br />

H. Täubig (TUM) GAD SS’11 33 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Addition / Subtraktion<br />

Der Bruch 5 4<br />

kann durch 1 ersetzt werden,<br />

weil sich F immer um eine ganze Zahl ändert.<br />

D.h.<br />

F = 5 4 − R + k < 0<br />

ist äquivalent zu<br />

F = 1 − R + k < 0<br />

Vorteil:<br />

nur noch ganze Zahlen!<br />

H. Täubig (TUM) GAD SS’11 34 / 604


Einführung<br />

Beispiele<br />

Kreis zeichnen: mit Addition / Subtraktion<br />

Bresenham2<br />

x = 0; y = R; plot(0, R); plot(R, 0); plot(0, −R); plot(−R, 0);<br />

F = 1 − R;<br />

d E = 1; d SE = 2 − R − R;<br />

while x < y do<br />

if F < 0 then<br />

F = F + d E ;<br />

d SE = d SE + 2;<br />

else<br />

F = F + d SE ;<br />

y = y − 1;<br />

d SE = d SE + 4;<br />

x = x + 1; d E = d E + 2;<br />

plot(x, y); plot(−x, y); plot(−y, x); plot(−y, −x);<br />

plot(y, x); plot(y, −x); plot(x, −y); plot(−x, −y);<br />

H. Täubig (TUM) GAD SS’11 35 / 604


Einführung<br />

Beispiele<br />

Bresenham-Algorithmus<br />

von Anfang der 1960er Jahre hat Jack Bresenham<br />

<strong>Algorithmen</strong> zur Linien- <strong>und</strong> Kreisdarstellung entwickelt<br />

Diese verwenden nur einfache Additionen ganzer Zahlen <strong>und</strong><br />

sind damit deutlich schneller als die naiven Ansätze.<br />

Diese <strong>und</strong> weitere Beispiele:<br />

Taschenbuch der <strong>Algorithmen</strong> (Springer, 2008)<br />

H. Täubig (TUM) GAD SS’11 36 / 604


Effizienz<br />

Übersicht<br />

3 Effizienz<br />

Effizienzmaße<br />

Rechenregeln für O-Notation<br />

Maschinenmodell<br />

Java<br />

Laufzeitanalyse<br />

Durchschnittliche Laufzeit<br />

H. Täubig (TUM) GAD SS’11 37 / 604


Effizienz<br />

Effizienzmaße<br />

Übersicht<br />

3 Effizienz<br />

Effizienzmaße<br />

Rechenregeln für O-Notation<br />

Maschinenmodell<br />

Java<br />

Laufzeitanalyse<br />

Durchschnittliche Laufzeit<br />

H. Täubig (TUM) GAD SS’11 38 / 604


Effizienz<br />

Effizienzmaße<br />

Effizienzmessung<br />

Exakte Spezifikation der Laufzeit eines Algorithmus<br />

(bzw. einer DS-Operation):<br />

Menge I der Instanzen<br />

Laufzeit des Algorithmus T : I ↦→ N<br />

Problem:<br />

Lösung:<br />

T sehr schwer exakt bestimmbar<br />

Gruppierung der Instanzen (meist nach Größe)<br />

H. Täubig (TUM) GAD SS’11 39 / 604


Effizienz<br />

Effizienzmaße<br />

Eingabekodierung<br />

Was ist die Größe einer Instanz<br />

Speicherplatz in Bits oder Wörtern<br />

Aber Vorsicht bei der Kodierung!<br />

Beispiel:<br />

Gegeben:<br />

Primfaktorisierung<br />

Zahl x ∈ N<br />

Gesucht: Primfaktoren von x (Primzahlen p 1 , . . . , p k mit x = ∏ i p e i)<br />

i<br />

Bekannt als hartes Problem (wichtig für RSA!)<br />

H. Täubig (TUM) GAD SS’11 40 / 604


Effizienz<br />

Effizienzmaße<br />

Eingabekodierung - Beispiel Primfaktorisierung<br />

Trivialer Algorithmus<br />

Teste von y = 2 bis ⌊ √ x<br />

⌋<br />

alle Zahlen, ob diese x teilen <strong>und</strong> wenn ja,<br />

dann bestimme wiederholt das Ergebnis der Division bis die Teilung<br />

nicht mehr ohne Rest möglich ist<br />

Laufzeit:<br />

√ x Teilbarkeitstests <strong>und</strong> höchstens log2 x Divisionen<br />

Unäre Kodierung von x (x Einsen als Eingabe): Laufzeit linear,<br />

Anzahl der Teilbarkeitstests <strong>und</strong> Divisionen ist sogar sublinear,<br />

aber die Eingabe muss einmal ganz gelesen werden<br />

Binäre Kodierung von x (⌈log 2 x⌉ Bits):<br />

(bezüglich der Länge der Eingabe)<br />

Laufzeit exponentiell<br />

H. Täubig (TUM) GAD SS’11 41 / 604


Effizienz<br />

Effizienzmaße<br />

Eingabekodierung<br />

Betrachtete Eingabegröße:<br />

Größe von Zahlen:<br />

binäre Kodierung<br />

Größe von Mengen / Folgen von Zahlen:<br />

Hier wird oft nur die Anzahl der Elemente betrachtet(!)<br />

Beispiel (Sortieren)<br />

Gegeben: Folge von Zahlen a 1 , . . . , a n ∈ N<br />

Gesucht: sortierte Folge der Zahlen<br />

Größe der Eingabe: n<br />

H. Täubig (TUM) GAD SS’11 42 / 604


Effizienz<br />

Effizienzmaße<br />

Effizienzmessung<br />

Für ein gegebenes Problem sei I n die Menge der Instanzen der<br />

Größe n.<br />

Effizienzmaße:<br />

Worst case:<br />

Average case:<br />

Best case:<br />

t(n) = max{T(i) : i ∈ I n }<br />

t(n) = 1 ∑<br />

T(i)<br />

|I n |<br />

i∈I n<br />

t(n) = min{T(i) : i ∈ I n }<br />

H. Täubig (TUM) GAD SS’11 43 / 604


Effizienz<br />

Effizienzmaße<br />

Effizienzmaße: Vor- <strong>und</strong> Nachteile<br />

worst case:<br />

liefert Garantie für die Effizienz des Algorithmus<br />

(auch wichtig für Robustheit)<br />

best case:<br />

Vergleich mit worst case liefert Aussage über die Abweichung<br />

innerhalb der Instanzen gleicher Größe<br />

average case:<br />

nicht unbedingt übereinstimmend mit dem “typischen Fall” in der<br />

Praxis (evt. schwer formal zu erfassen), kann durch<br />

Wahrscheinlichkeitsverteilung noch verallgemeinert werden<br />

exakte Formeln für t(n) meist sehr aufwendig<br />

⇒ betrachte asymptotisches Wachstum<br />

H. Täubig (TUM) GAD SS’11 44 / 604

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!