Grundlagen: Algorithmen und Datenstrukturen - Lehrstuhl für ...
Grundlagen: Algorithmen und Datenstrukturen - Lehrstuhl für ...
Grundlagen: Algorithmen und Datenstrukturen - Lehrstuhl für ...
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