Upload
doanduong
View
214
Download
0
Embed Size (px)
Citation preview
Rekursive Auswertungsprozesse in Haskell
Auswertungsprozess, der durch eine rekursive Funktion bewirkt wird
Beispiel: Auswertung der rekursiven Fakultatsfunktion
0! := 1n! := n ∗ (n− 1)!
fakultaet x = if x <= 1 then 1
else x*(fakultaet (x-1))
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 1
Auswertungsprozess, linear rekursiv
bei verzogerter Auswertung
(Nicht jeder Zwischenzustand ist angegeben)
(fakultaet 6)
(6 * (fakultaet (6-1)))
(6 * (5 * (fakultaet (5-1))))
(6 * (5 * (4 * (fakultaet (4-1)))))
(6 * (5 * (4 * (3 * (fakultaet (3-1))))))
(6 * (5 * (4 * (3 * (2 * (fakultaet (2-1)))))))
(6 * (5 * (4 * (3 * (2 * 1)))))
(6 * (5 * (4 * (3 * 2))))
(6 * (5 * (4 * 6)))
(6 * (5 * 24))
(6 * 120)
720
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 2
Auswertungsprozess, linear rekursiv
(fakultaet 6) Auswertungsprozess ist linear rekursiv
Charakteristisch: nur eine rekursive Funktionsanwendungin jedem Ausdruck der Reduktionsfolge
Zwischenausdrucke sind unbeschrankt in der Große
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 3
Applikative Funktionen
Eine Funktion ist applikativ,wenn
zuerst die Argumente ausgewertet werden,dann der (eigentliche) Rumpf der Funktion
Eine Funktion nennt man strikt,wenn
die Argumente auf jeden Fall ausgewertet werden,der Zeitpunkt jedoch nicht festgelegt ist.
applikativ ⇒ strikt
Wenn f applikativ die applikative Variante von f,dann gilt i.a: f und f applikativ sind semantisch verschieden
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 4
Alternative Berechnungen der Fakultatsfunktion
Iteriere folgende Regel:Produkt ⇒ Produkt ∗ ZahlerZahler ⇒ Zahler + 1
Programm:
fakultaet_iter n = fakt_iter 1 1 n
fakt_iter produkt zaehler max =
if zaehler > max
then produkt
else fakt_iter (zaehler * produkt) (zaehler + 1) max
fakt_iter_strikt produkt zaehler max =
strikt_3 produkt zaehler max
(if zaehler > max
then produkt
else fakt_iter_strikt (zaehler * produkt) (zaehler + 1) max)
fakultaet_lin n = fakt_iter_strikt 1 1 n
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 5
Endrekursion
Eine Endrekursion ist eine lineare Rekursion.
Zusatzlich muss gelten:
alle rekursiven Aufrufe berechnen den Ruckgabewert
ohne Nachverarbeitung
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 6
Auswertungsprozess, endrekursiv
Auswertung von (fakultaet_iter 5) bei verzogerter Auswertung
(fakultaet_iter 5)
(fakt_iter 1 1 5)
(fakt_iter (1*1) (1+1) 5)
(fakt_iter (2*(1*1)) (2+1) 5)
(fakt_iter (3*(2*(1*1))) (3+1) 5)
(fakt_iter (4*(3*(2*(1*1)))) (4+1) 5)
(fakt_iter (5*(4*(3*(2*(1*1))))) (5+1) 5)
(5*(4*(3*(2*(1*1)))))
120
Das ist eine lineare Rekursion, es ist auch eine Endrekursion
Auswertungsprozess zu fakultaet 6 nicht endrekursiv,da fakultaet (...) eingebettet in weitere Berechnung.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 7
Iterativer Auswertungsprozess: Fakultat (2)
Iterativer Auswertungsprozess:
(fakultaet_lin 6)
(fakt_iter_strikt 1 1 6)
(fakt_iter_strikt 1 2 6)
(fakt_iter_strikt 2 3 6)
(fakt_iter_strikt 6 4 6)
(fakt_iter_strikt 24 5 6)
(fakt_iter_strikt 120 6 6)
(fakt_iter_strikt 720 7 6)
720
Iterativer Prozess:
Charakteristisch: Ist eine EndrekursionArgumente sind Basiswerte(bzw. Große des Gesamtausdrucks bleibt beschrankt.)optimierte Ruckgabe des Wertes
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 8
Optimierung der Endrekursion
imperative Program-
miersprachen
Endrekursion i.a. nicht optimiert.
d.h. Wert wird durch alle Stufen der Rekur-
sion zuruckgegebenHaskell Endrekursion ist optimiert
am Ende wird Wert unmittelbar zuruckgege-
ben.
Deshalb:
Iterationskonstrukte in imperativen Programmiersprachen:
for ...do, while, oder repeat ...until.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 9
Iteration in Haskell
In Haskell: Iterative Auswertungsprozessenur mittels guter Programmierung
Naive Implementierung, verzogerte Reihenfolge der Auswertung
tendieren zu:
linear rekursiven, nicht endrekursiven bzw. nicht iterativen Prozessen.
Vergleich: Iterativ gegen linear rekursiv:Anzahl Auswertungsschritte bleibt i.a. gleichGroße der Zwischenausdrucke ist kleiner
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 10
Baumrekursion
Beispiel Berechnung der Fibonacci-Zahlen
1, 1, 2, 3, 5, 8, 13, 21, . . .
Fib(n) :=
0 falls n = 01 falls n = 1Fib(n− 1) + Fib(n− 2) sonst
fib n = if n <= 0 then 0
else if n == 1 then 1
else fib (n-1) + fib(n-2)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 11
Auswertungsprozess zu fib
fibs: applikative Variante von fib
Der Auswertungs-Prozess ergibt folgende Zwischen-Ausdrucke:
fibs 5
fibs 4 + fibs 3
(fibs 3 + fibs 2) + fibs 3
((fibs 2 + fibs 1) + fibs 2) + fibs 3
(((fibs 1 + fib 0) + fibs 1) + fibs 2) + fibs 3
(((1+0) + fibs 1) + fibs 2) + fibs 3
((1 + fibs 1) + fibs 2) + fibs 3
((1+1) + fibs 2) + fibs 3
(2 + fibs 2) + fibs 3
(2 + (fibs 1 + fibs 0)) + fibs 3
.......
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 12
Auswertungsprozess zu fibs: Baum der Aufrufe
5
43
2
1 0
1
3
2 1
1 0
2
1 0
Das ist Baumrekursion
Charakteristisch: Ausdrucke in der Reduktionsfolge• konnen unbegrenzt wachsen• enthalten mehrere rekursive Aufrufe• Aber: nicht geschachtelt
(d.h. die Argumente eines rekursiven Aufrufsenthalten keine rekursiven Aufrufe)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 13
Geschachtelte Rekursion
Ist der allgemeine Fallwird normalerweise selten benotigt, da i.a. nicht effizient berechenbar.
Beispiel: Die Ackermannfunktion
----- Ackermanns Funktion ----
ack 0 y = 1
ack 1 0 = 2
ack x 0 | x >= 2 = x+2
ack x y | x > 0 && y > 0 = ack (ack (x-1) y) (y-1)
Vorstellung neuer syntaktischer Moglichkeiten in Haskell:Auswertung:von oben nach unten wird probiert, welche Definitionsgleichung passt:1) Argumente anpassen2) Bedingung rechts vom | prufen
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 14
Optimierte Ackermannfunktion
----- Ackermanns Funktion optimiert ----
ackopt 0 y = 1
ackopt 1 0 = 2
ackopt x 0 = x+2
ackopt x 1 = 2*x
ackopt x 2 = 2^x
ackopt x y | x > 0 && y > 0 = ackopt (ackopt (x-1) y) (y-1)
*Main> logI10 (ackopt 5 3)
19728.301029995662 --(Anzahl DezimalStellen)
-- ( == 2^65536)
• sehr schnell wachsende Funktion• man kann nachweisen: ack nicht primitiv rekursiv• hat Anwendung in der Komplexitatstheorie
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 15
Tabelle der Rekursionsprozesse:
linear rekursiv maximal ein rekursiver Unterausdruckendrekursiv linear rekursiv und Gesamtresultat ist Wert des
rekursiven Unterausdrucksiterativ endrekursiv und Argumente sind BasiswerteBaumrekursion mehrere rekursive Unterausdruck, Argument des
rekursiven Ausdrucks ohne weitere Rekursiongeschachtelte
Baumrekursion
mehrere rekursive Unterausdrucke auch in den
Argumenten
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 16
Optimierung: Iteration statt Rekursion
Beispiel
Berechnung von (fib 5)
fib 3 wird 2 mal berechnetfib 2 wird 3 mal berechnetfib 1 wird 5 mal berechnet
Genauer: Bei Berechnung von fib n fur n ≥ 2
wird fib(1) jeweils (fib n)-mal berechnet
fib n ≈ Φn√
5wobei Φ = 1+
√5
2 ≈ 1.6180
Fazit: fib(n) wachst exponentiell# Reduktionen fur fib(n) ist exponentielld.h. die Laufzeit von fib ist exponentiell
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 17
Iterative Version von Fib
Beobachtung: zur Berechnung von fib(n) benotigt man
nur die Werte fib(i) fur 1 ≤ i ≤ n.
Idee: Berechnung einer Wertetabelle fur fib.
Verbesserte Variante: aus fib (n− 1) und fib (n− 2) berechne fib(n)Ohne Doppelberechnung
Rechenvorschrift: (a, b) → (a + b, a)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 18
Iterative Version von fib: Funktionen
fib_lin n = (fib_iter_strikt 1 0 n)
fib_iter a b zaehler = if zaehler <= 0
then b
else fib_iter (a + b) a (zaehler - 1)
fib_iter_strikt a b zaehler =
strikt_3 a b zaehler
(if zaehler <= 0
then b
else fib_iter_strikt (a + b) a (zaehler - 1))
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 19
Prozess fur (fib lin 5)
(fib_lin 5)
(fib_iter_strikt 1 0 5)
(fib_iter_strikt 1 1 4)
(fib_iter_strikt 2 1 3)
(fib_iter_strikt 3 2 2)
(fib_iter_strikt 5 3 1)
5
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 20
Analyse der fib-Optimierung
Fur (fib_lin n) gilt:• ist operational aquivalent zu fib
• benotigt linear viele Reduktionen abhangig von n• Große der Ausdrucke ist beschrankt• Platzbedarf ist konstant (d.h. unabhangig) von n.
(unter Vernachlassigung der Darstellungsgroße der Zahlen)
erzeugt Iterativen Auswertungsprozess
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 21
Terminierung: Halt ein Programm an?
((3n + 1)-Funktion)
drein x = if x == 1 then 1
else if geradeq x
then drein (x ‘div‘ 2)
else drein (3*x+1)
geradeq n = (rem n 2) == 0
Collatz Vermutung:
diese Funktion halt an fur jede positive naturliche Zahl
als Eingabe
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 22
Beispielausfuhrungen von drein
Zum Experimentieren verwende dreinlst.
fur 5: 5,16,8,4,2,1fur 27:27,82,41,124,62,31,94,47,142,71,214,107,322,161,484,242,121,
364,182,91,274,137,412,206,103,310,155,466,233,700,350,175,
526,263,790,395,1186,593,1780,890,445,1336,668,334,167,502,
251,754,377,1132,566,283,850,425,1276,638,319,958,479,1438,
719,2158,1079,3238,1619,4858,2429,7288,3644,1822,911,2734,
1367,4102,2051,6154,3077,9232,4616,2308,1154,577,1732,866,433,
1300,650,325,976,488,244,122,61,184,92,46,23,70,35,106,53,160,
80,40,20,10,5,16,8,4,2,1
Die Terminierung dieser Funktion drein wurde gepruft fur alle Zahlen
< 240
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 23
Terminierung
Die Theorie zeigt:
Programmiersprachen, die Programme ausschließen, die manchmal
nicht terminieren
sind nicht allgemein.
D.h. nicht aquivalent zur Turingmaschine
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 24
Terminierungsnachweise
Normalerweise mit vollstandiger Induktion
bzw. Mit Induktion zu einer fundierten Ordnung.
Beispiel:
fib n = if n <= 0 then 0
else if n == 1 then 1
else fib (n-1) + fib(n-2)
Beh: fib(n) terminiert mit einer ganzen Zahl fur n ∈ IN0:
Induktionsbasis ist 0 und 1:
fib 0 und fib 1 terminieren und ergeben Resultat 0 bzw. 1.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 25
Terminierungsnachweis (2)
Induktionsschritt: Fur n > 1 gilt:
fib n reduziert zu fib (n− 1) + fib (n− 2).
Induktionshypothese gilt fur n− 1 und n− 2, also terminiert fib n.
Insgesamt ist damit die Terminierung gezeigt. QED
Ungelost: Die einfachen Ansatze zum Terminierungsbeweis fur die
3n+1-Funktion scheitern, da die Argumente unregelmaßig großer und
kleiner werden.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 26
Ressourcenbedarf von Programmen, Effizienz,
Wachstumsraten und Großenordnungen
wichtige Ressourcen:
• Zeit
• Platz
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 27
Weitere Ressourcen / Maße:
• Anzahl benotigter Prozessoren bei parallelen Algorithmen
• Große des Programms
• Kosten fur die Kommunikation
• Anzahl der Aufrufe bestimmter Unterprozeduren (Dienste):Datenbankzugriffe, usw.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 28
Weitere Ressourcen / Maße (2)
Man kann auch noch betrachten:
• Aufwand zur Erstellung des Programms• organisatorischer Aufwand zur Nutzung• Aufwand zum Portieren eines Programms in andere
(Rechner-)umgebungen.• Aufwand fur Verifikation / Anderung eines Programms• Kosten innerhalb eines organisatorischen Rahmens
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 29
Optimierung
Optimierung := Reduktion des Ressourcenbedarf von Programmendurch Abanderungen des Programmsohne Funktionalitatsanderung.
Es gibt verschiedene Prioritaten bei Optimierung:
Wettervorhersage Simulationen: ZeitAnwendung mit Datenubertragung: KommunikationJava: Kommunikation,Portierbarkeit
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 30
Optimierung (2). Zu beachten ist:
• Wie oft wird dieses Programm benotigt? Lohnt sich der Optimier-
aufwand ?
• optimierte Programme sind oft unubersichtlicher.
• Optimierung wird durch Compiler erledigt
• Optimierung kann die Portierbarkeit verschlechtern
• experimentelle Feststellung des Ressourcenbedarfs ist
fehlerbehaftet und abhangig von (Version der) Programmierumge-
bung
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 31
Analyse von Programmen
Wir verwenden fur Haskell-Programme folgende Messungen.
Benutze verzogerte Auswertung
Zeit: Anzahl der Transformationsschritte
Platz: (Gesamt-Speicher): Maximale Große der Ausdrucke
Arbeitsspeicher: Maximale Große der Ausdrucke(ohne die Eingabe)
arithmetische und Boolesche Operationen = 1 Transformationsschritt.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 32
Analyse von Programmen (2)
Angabe des Ressourcenbedarf eines Algorithmus
in Abhangigkeit von der Große der Eingabe.
Notation fur Algorithmus alg bei Eingabe der Große n:
redalg(n) maximale Anzahl der Reduktionen bei verzogerter Aus-
wertung fur alle Eingaben der Große n.
Platzalg(n) Platzbearf: maximale Große der Ausdrucke (des gerich-
teten Graphen) bei verzogerter Auswertung fur alle Ein-
gaben der Große n.
Die Eingaben nicht mitzahlen
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 33
Analyse von Programmen (3)
Bei genauerer Analyse einer Problemklasse:
Bezugsgroßen: Turingmaschineoder anderes abstraktes Maschinenmodell
!?: Abhangigkeit vom Maschinenmodell?Aufwand eines Einzelschrittes (abstr. Maschine)?Aufwand der eingebauten Funktionen?
(Multiplikation, Addition, Konversionen,usw.).benotigter Platz fur Zahlen? I.a. nicht konstant.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 34
Beispiel: fib
fib n = if n <= 0 then 0
else if n == 1 then 1
else fib (n-1) + fib(n-2)
Bezugsgroße: eingegebene Zahl n
Behauptung: # rekursive Aufrufe fur (fib n) ist ≤ fib(n + 1)Beweis: mit vollstandiger Induktion
redfib(n) ≤ c ∗ fib(n + 1) wobei c eine Konstante ist.fib(n) ≈ 1.6n ⇒ redfib(n) ≈ 1.6n (einfach exponentiell)
andere Bezugsgroße: Große der Darstellung der Zahl n:
n hat size(n) = dlog10(n)e Dezimalstellen.
Zeitbedarf: ≈ 1.6(10size(n)) (doppelt exponentiell).
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 35
Beispiel fakultaet
fakultaet x = if x <= 1 then 1
else x*(fakultaet (x-1))
Anzahl der Reduktionen:
fakultaet 1
if 1 <= 1 then ...
if True then ...
1
fakultaet 1 : 3 Reduktionschritte
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 36
Beispiel fakultaet 2
fakultaet 2
if 2 <= 1 then ...
if False then ...
2*(fakultaet (2-1))
2*(if (2-1) <= 1 then ... )
2*(if 1 <= 1 then ... )
2*(if True then ... )
2* 1
2
fakultaet 2 : 8 Reduktionschritte
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 37
Beispiel fakultaet 3
fakultaet 3
if 3 <= 1 then ...
if False then ...
3*(fakultaet (3-1))
3*(if (3-1) <= 1 then ... )
3*(if 2 <= 1 then ... )
3*(if False then ... )
3*(2*fakultaet (2-1))
3*(2*(if 2-1 <= 1 then ...
3*(2*(if 1 <= 1 then ... ))
3*(2*(if True then ... ))
3*(2* 1)
3*2
6
fakultaet 3 : 13 Reduktionschritte
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 38
Beispiel fakultaet n
Es sind: 5 ∗ (n− 1) + 3 Reduktionsschritte.
Vermutung: redfakultaet(n) = 5 ∗ (n− 1) + 3
Nachweis mit vollstandiger Induktion:Beh: fakultaet (n-1) (als Ausdruck)
benotigt 5 ∗ (n− 2) + 4 Reduktionsschritte:fur n ≥ 2
Basis: fakultaet (2-1) benotigt 4 Reduktionsschritte
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 39
Beispiel fakultaet n: Nachweis
Ind. Schritt:
Nachzuweisen ist: fakultaet (n-1) benotigt 5 ∗ (n− 2) + 4 fur n > 2.
fakultaet (n-1)
if (n-1) <= 1 then ...
if n1 <= 1 then ... -- n1 ist Basiswert > 1
if False then ...
n1*fakultaet (n1-1)
Das sind 4 + 5 ∗ (n1− 2) + 4 + 1 = 5 ∗ (n− 2) + 4 Reduktionsschritte
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 40
Beispiel fakultaet n : Nachweis
Anfangs-Reduktions-Schritt
fakultaet n
if n <= 1 then ...
if False then ...
n*fakultaet (n-1)
Das sind 3 + (5 ∗ (n− 2) + 4) + 1 = 5 ∗ (n− 1) + 3
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 41
Komplexitaten von Algorithmen
Beachte: breite Streuung des Ressourcenbedarfs ist moglich furdie Menge aller Eingaben einer bestimmten Große.
Z.B. (3n+1)-Funktion mit Bezugsgroße: Anzahl der Stellen
Komplexitaten von Platz und Zeit:
Ressourcenbedarf
im schlimmsten Fall (worst-case)im besten Fall (best-case)
Minimum von # Reduktionenbzw. Minimum der Große der Ausdrucke.
im Mittel (average case)Welche Verteilung?
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 42
Komplexitaten von Algorithmen
Ein Algorithmus ist effizient, wenn er wenig Ressourcen benotigt
Ein Algorithmus ist optimal, wenn er”nicht schlechter“ ist als andere
Algorithmen zur gleichen Problemklasse
(Zeit/Platz)-Komplexitat einer Problemklasse:
≡ Ressourcenverbrauch des optimalen Algorithmus.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 43
O-Schreibweise
Verwendung: asymptotische Großenordnung von
numerischen Funktionen
hier fur: redalg(n) und Platzalg(n)
Definition
Seien R, f : IN+ → IR+ zwei Funktionen: Wir schreiben:
R(n) = O(f(n)), wenn es eine Konstante K gibt, so daßR(n) ≤ K ∗ f(n) fur alle genugend großen n.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 44
O-Schreibweise: Bemerkungen
Beachte R(n) = O(f(n)) keine Gleichung
Beachte R(n) = O(f(n)) ist eine Abschatzung nach oben
Die Angabe R(n) = O(f(n)) sollte moglichst optimales f verwenden
Sprechweisen:
R(n) ist von der Großenordnung f(n)
R(n) hat hochstens Großenordnung f(n)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 45
Beispiele und Eigenschaften zu O()
•√
n = O(n)
• p(n) = O(2n) fur alle Polynome p.
• Wenn f(n) = O(c ∗ g(n)), dann auch f(n) = O(g(n)).
• Wenn c > 1 und e > 0 eine Konstante, dann gilt: f(n) = O(cn+e)gdw. f(n) = O(cn)
• Wenn c, d > 1, dann gilt: f(n) = O(logc(n)) gdw. f(n) = O(logd(n))
• Wenn c, d > 1, und c < d, dann gilt: cn = O(dn) , aber nichtdn = O(cn).
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 46
Beispiele und Eigenschaften zu O()
• Wenn f(n) = O(g(n)) und g(n) = O(h(n), dann gilt auch
f(n) = O(h(n)).
• Wenn eine Funktion f durch eine Konstante nach oben beschrankt
ist, dann gilt f(n) = O(1).
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 47
Beispiel fib
fib Bezugsgroße: n: Eingabed: Große der Darstellung der Zahl n
redfib(n) = O(1.62n)platzfib(n) = O(n)
redfib lin(n) = O(n)platzfib lin(n) = O(n)
redfib lin(d) = O(10d)platzfib lin(d) = O(10d)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 48
Einige Komplexitaten
O(1) konstantO(log(n)) logarithmischO(n) linearO(n ∗ log(n)) fastlinear (oder auch n-log-n)O(n2) quadratischO(n3) kubischO(nk) polynomiellO(2n) exponentiell
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 49
Komplexitaten: Veranschaulichung
beispielhafte Tabelle zur intuitiven Veranschaulichung:
Eingabedaten 10 100 1000Algorithmuslog2(n) 0.000003 sec 0.000007 sec 0.00001n 0.00001 sec 0.0001 sec 0.001 secn2 0.0001 sec 0.01 sec 1 secn3 0.001 sec 1 sec 15 min2n 0.001 sec 4 ∗ 1016 Jahre nahezu ∞
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 50
Kommentare zu O()
• Viele relevante Optimierungen andern Großenordnung O()
nicht• Verwendung eines schnelleren Rechners:
nur konstante Verbesserung der Zeit, d.h. O() andert sich
nicht.• Die Bestimmung der genauen Komplexitat des Ressourcenbe-
darfs einer Problemklasse ist jeweils ein sehr schweres theore-
tisches Problem.• Oft sind nur gute obere Abschatzungen bekannt• Bekannte untere Schranken sind oft trivial oder zu schwach
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 51
Ω-Schreibweise
Ziel:
Großenordnung von numerischen Funktionen nach unten abschatzen.
Seien R, f : IN+ → IR+ zwei Funktionen:
R(n) = Ω(f(n)), wenn es eine Konstante Kgibt, so daßR(n) ≥ K ∗ f(n) fur alle genugend großen n.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 52
Ω-Eigenschaften
Analog zu O(·).
• n = Ω(√
n)•
√n = Ω(1).
• 2n = Ω(p(n)) fur alle Polynome p.• Wenn f(n) = Ω(c ∗ g(n)), dann auch f(n) = Ω(g(n)).• m Wenn c > 1 und e > 0 eine Konstante, dann gilt:
f(n) = Ω(cn+e) gdw. f(n) = Ω(cn)• Wenn c, d > 1, dann gilt: f(n) = Ω(logc(n)) gdw. f(n) =
Ω(logd(n))• Wenn c, d > 1, und c < d, dann gilt: dn = Ω(cn) , aber
nicht cn = Ω(dn).• Wenn f(n) = Ω(g(n)) und g(n) = Ω(h(n), dann gilt auch
f(n) = Ω(h(n)).• Wenn eine Funktion f durch eine Konstante nach unten
beschrankt ist, dann gilt f(n) = Ω(1).
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 53
Schnelle Berechnung von Potenzen
bn fur positive ganze Zahlen n.
Die Potenzen sind rekursiv definiert durch:
bn :=
1 falls n = 0b ∗ bn−1 sonst
Direkte Kodierung des Algorithmus ergibt ein rekursives Programm:
potenz b n = if n == 0
then 1
else b * (potenz b (n - 1))
Platz- und Zeitbedarf sind von der Großenordnung O(n)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 54
Optimierung der Potenzberechnung
Idee: Statt b8 = b ∗ b ∗ b ∗ b ∗ b ∗ b ∗ b ∗ b berechne
• b2 := b ∗ b
• b4 = b2 ∗ b2
• b8 = b4 ∗ b4
allgemeine Rechenvorschrift:
bn :=
1 falls n = 0(bn/2)2 falls n gerade und ≥ 2b ∗ bn−1 falls n ungerade
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 55
Haskell-Programm zur Potenz
potenz_log b n = if n == 0 then 1
else if geradeq n
then quadrat (potenz_log b (n ‘div‘ 2))
else b * (potenz_log b (n - 1))
geradeq n = (rem n 2) == 0
Platz- und Zeitbedarf abhangig von n ist O(log(n))
z.B. fur n = 1000: 14 Multiplikationen.
tatsachlicher Platz- und Zeitbedarf: O((log(n)3),
wegen Multiplikation von großen Zahlen
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 56
Analyse des Algorithmus zum großten
gemeinsamen Teiler
ggT(a, b) (Euklids Algorithmus)
Teile a durch b gibt Rest r,
wenn r = 0, dann ggT(a, b) := b
wenn r 6= 0, dann berechne ggT(b, r).
Beispiel ggT(30,12) = ggT(12,6) = 6
ggt a b = if b == 0
then a
else ggt b (rem a b)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 57
Satz von Lame
SATZ (Lame): Wenn der Euklidische ggt-Algorithmus k Schritte
benotigt,
dann ist die kleinere Zahl der Eingabe ≥ fib(k).
Platz- und Zeitbedarf von ggt: O(log(n))
Begrundung:
Wenn n die kleinere Zahl ist und der Algorithmus k Schritte benotigt,
dann ist n ≥ fib(k) ≈ 1.6180k
Also ist k = O(log(n))
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 58
Test auf Primzahl-Eigenschaft
Problem: Gegeben n.
Frage: ist n eine Primzahl?
Methode 1: finde den kleinsten Teiler > 1:
primzahlq n = n == (kleinster_teiler n)
kleinster_teiler n = finde_teiler n 2
finde_teiler n pruef_teiler =
if n < (quadrat pruef_teiler) then n
else if teiltq pruef_teiler n
then pruef_teiler
else finde_teiler n (pruef_teiler + 1)
teiltq a b = 0 == (rem b a)
(worst-case) Zeitbedarf: O(√
n)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 59
Primzahltest: Methode 2
Benutze kleinen Fermatschen Satz.
Satz (Fermat): Wenn p eine Primzahl ist und 1 < a < p,
dann ist ap ≡ a(mod p)
Idee fur Algorithmus:
Teste fur viele verschiedene a: Wenn fur ein a: an 6≡ a(mod n), dann ist
n keine Primzahl.
Bei ausreichend vielen Zahlen a mit an ≡ a(mod n):
mit hoher Wahrscheinlichkeit ist n Primzahl
Aber: Ausnahmen sind moglich
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 60
Primzahltest: Programm zu Methode 2
potenzmod b e m =
if e == 0 then 1
else if geradeq e
then rem (quadrat (potenzmod b (e ‘div‘ 2) m))
m
else rem (b * (potenzmod b (e - 1) m))
m
fermat_test_it n rnd =
let a = (rnd ‘mod‘ n)
in (potenzmod a n n) == a
fermat_test n = and (map (fermat_test_it n)
(take 100 (randomInts 2 n))))
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 61
Primzahltest: Bemerkungen
Dies ist ein probabilistischer Algorithmus
Eigenschaften
Zeitverbrauch pro Test: O(log n).
Die Antwort:”ist keine Primzahl“ ist immer korrekt,
wahrend”ist eine Primzahl“ nur mit hoher Wahrscheinlichkeit korrekt
Die Ausnahmen nennt man Carmichael-Zahlen.
561,1105,1729,2465,2821,6601,8911,10585,15841,29341, . . . .
Teilbarkeitstest durch die Primzahlen bis 43
schliesst alle Carmichaelzahlen ≤ 106 aus.
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 62
Primzahltest: Neuere Ergebnisse
Prufung einer Zahl auf Primzahleigenschaft ist in polynomieller Zeit
moglich
(d.h. in O(log(n)) ).
(siehe: M. Agrawal, N. Kayal, N. Saxena: PRIMES is in P )
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 63
Beispiel: Fermatsche Primzahlen
Vermutung von Pierre de Fermat: 22n+ 1 ist immer eine Primzahl
geometrische Konstruierbarkeit mittels Zirkel und Lineal
von gleichseitigen Vielecken ist moglich,
wenn die Anzahl der Seiten die Form
2m ∗ p hat und p eine Fermatsche Primzahl ist
Widerlegung der Vermutung: 22n+ 1 ist keine Primzahl fur n =
5,6,7,8,9
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 64
Beispiel: Fermatsche Primzahlen
Main> fermat_prim_test 4
(65537,True) -- ist Primzahl
Main> fermat_prim_test 5
(4294967297,False)
Main> fermat_prim_test 6
(18446744073709551617,False)
Main> fermat_prim_test 7
(340282366920938463463374607431768211457,False)
Aber: einen Teiler zu berechnen dauert sehr (zu) lange.
Mit iterativer Version von potenzmod:
auch n = 10,11,12,13,14 widerlegbar.
Offen: (n = 33,34,35,40,41,44,45,46,47,50, . . .)
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 65
Beispiel: Mersennesche Primzahlen
sind von der Form 2p − 1, wobei p selbst eine Primzahl ist.
Mersennesche Primzahlen sindRekordhalter als großte Primzahlen
Es sind Primzahlen fur folgende Werte von p:2,3,5,7,13,17,19,31,61,89,107,127,521,607,1279,2203,2281,
3217,4253,4423,9689,9941,11213,19937, . . .
Der aktuelle Rekord ist p = 24036583, d.h. die Mersennesche Primzahl224036583 − 1,
Siehe http://www.mersenne.org/history.htm#found
p = 2281 ist machbar mit Haskell Interpreter (einige Minuten)
mersenne_prim_test 2281
Praktische Informatik 1, WS 2004/05, Folien Haskell−2, (12. November2004) Seite 66