Rekursive Auswertungsprozesse in Haskell

Werbung
Rekursive Auswertungsprozesse in Haskell
Auswertungsprozess, der durch eine rekursive Funktion bewirkt wird
Beispiel: Auswertung der rekursiven Fakultätsfunktion
0! := 1
n! := n ∗ (n − 1)!
fakultaet x
P raktische Inf ormatik
1, W S
= if x <= 1 then 1
else x*(fakultaet (x-1))
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 1
Auswertungsprozess, linear rekursiv
bei verzögerter 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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 2
Auswertungsprozess, linear rekursiv
(fakultaet 6) Auswertungsprozess ist linear rekursiv
Charakteristisch:
P raktische Inf ormatik
1, W S
nur eine rekursive Funktionsanwendung
in jedem Ausdruck der Reduktionsfolge
Zwischenausdrücke sind unbeschränkt in der Größe
2004/05, F olien Haskell−2,
(12. N ovember2004)
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 4
Alternative Berechnungen der Fakultätsfunktion
Iteriere folgende Regel:
Produkt
Zähler
⇒
⇒
Produkt ∗ Zähler
Zähler + 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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 5
Endrekursion
Eine Endrekursion ist eine lineare Rekursion.
Zusätzlich muss gelten:
alle rekursiven Aufrufe berechnen den Rückgabewert
ohne Nachverarbeitung
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 6
Auswertungsprozess, endrekursiv
Auswertung von (fakultaet_iter 5) bei verzögerter 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.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 7
Iterativer Auswertungsprozess: Fakultät (2)
Iterativer Auswertungsprozess:
(fakultaet_lin 6)
(fakt_iter_strikt
(fakt_iter_strikt
(fakt_iter_strikt
(fakt_iter_strikt
(fakt_iter_strikt
(fakt_iter_strikt
(fakt_iter_strikt
720
1 1 6)
1 2 6)
2 3 6)
6 4 6)
24 5 6)
120 6 6)
720 7 6)
Iterativer Prozess:
Charakteristisch:
P raktische Inf ormatik
1, W S
Ist eine Endrekursion
Argumente sind Basiswerte
(bzw. Größe des Gesamtausdrucks bleibt beschränkt.)
optimierte Rückgabe des Wertes
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 8
Optimierung der Endrekursion
imperative Programmiersprachen
Endrekursion i.a. nicht optimiert.
d.h. Wert wird durch alle Stufen der Rekursion zurückgegeben
Endrekursion ist optimiert
am Ende wird Wert unmittelbar zurückgegeben.
Haskell
Deshalb:
Iterationskonstrukte in imperativen Programmiersprachen:
for ...do, while, oder repeat ...until.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 9
Iteration in Haskell
In Haskell:
Iterative Auswertungsprozesse
nur mittels guter Programmierung
Naive Implementierung, verzögerte Reihenfolge der Auswertung
tendieren zu:
linear rekursiven, nicht endrekursiven bzw. nicht iterativen Prozessen.
Vergleich: Iterativ gegen linear rekursiv:
Anzahl Auswertungsschritte bleibt i.a. gleich
Größe der Zwischenausdrücke ist kleiner
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 10
Baumrekursion
Beispiel Berechnung der Fibonacci-Zahlen
1, 1, 2, 3, 5, 8, 13, 21, . . .
F ib(n) :=


 0
1

 F ib(n − 1) + F ib(n − 2)
fib n = if n <= 0 then 0
else if n == 1 then 1
else fib (n-1) + fib(n-2)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 11
falls n = 0
falls n = 1
sonst
Auswertungsprozess zu fib
fibs: applikative Variante von fib
Der Auswertungs-Prozess ergibt folgende Zwischen-Ausdrücke:
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)
(((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
.......
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 12
+ fibs 3
Auswertungsprozess zu fibs: Baum der Aufrufe
5
4
3
3
2
1
2
1
1
2
0
1
1
0
0
Das ist Baumrekursion
Charakteristisch: Ausdrücke in der Reduktionsfolge
• können unbegrenzt wachsen
• enthalten mehrere rekursive Aufrufe
• Aber: nicht geschachtelt
(d.h. die Argumente eines rekursiven Aufrufs
enthalten keine rekursiven Aufrufe)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 13
Geschachtelte Rekursion
Ist der allgemeine Fall
wird normalerweise selten benötigt, da i.a. nicht effizient berechenbar.
Beispiel: Die Ackermannfunktion
----ack 0
ack 1
ack x
ack x
Ackermanns Funktion
y
=
0
=
0 | x >= 2
=
y | x > 0 && y > 0 =
---1
2
x+2
ack (ack (x-1) y) (y-1)
Vorstellung neuer syntaktischer Möglichkeiten in Haskell:
Auswertung:
von oben nach unten wird probiert, welche Definitionsgleichung passt:
1) Argumente anpassen
2) Bedingung rechts vom | prüfen
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 14
Optimierte Ackermannfunktion
----ackopt
ackopt
ackopt
ackopt
ackopt
ackopt
Ackermanns Funktion optimiert ---0 y = 1
1 0 = 2
x 0 = x+2
x 1 = 2*x
x 2 = 2^x
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 Komplexitätstheorie
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 15
Tabelle der Rekursionsprozesse:
linear rekursiv
endrekursiv
iterativ
Baumrekursion
geschachtelte
Baumrekursion
P raktische Inf ormatik
1, W S
maximal ein rekursiver Unterausdruck
linear rekursiv und Gesamtresultat ist Wert des
rekursiven Unterausdrucks
endrekursiv und Argumente sind Basiswerte
mehrere rekursive Unterausdruck, Argument des
rekursiven Ausdrucks ohne weitere Rekursion
mehrere rekursive Unterausdrücke auch in den
Argumenten
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 16
Optimierung: Iteration statt Rekursion
Beispiel
Berechnung von (fib
fib 3 wird
fib 2 wird
fib 1 wird
5)
2 mal berechnet
3 mal berechnet
5 mal berechnet
Genauer: Bei Berechnung von fib n für n ≥ 2
wird fib(1) jeweils (fib n)-mal berechnet
√
Φn
fib n ≈ √
Fazit:
5
wobei Φ = 1+2 5 ≈ 1.6180
fib(n) wächst exponentiell
# Reduktionen für fib(n) ist exponentiell
d.h. die Laufzeit von fib ist exponentiell
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 17
Iterative Version von Fib
Beobachtung: zur Berechnung von fib(n) benötigt man
nur die Werte fib(i) für 1 ≤ i ≤ n.
Idee: Berechnung einer Wertetabelle für fib.
Verbesserte Variante:
aus fib (n − 1) und fib (n − 2) berechne fib(n)
Ohne Doppelberechnung
Rechenvorschrift: (a, b) → (a + b, a)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 18
Iterative Version von fib: Funktionen
fib_lin n
=
fib_iter a b zaehler =
(fib_iter_strikt 1 0 n)
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))
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 19
Prozess für (fib lin 5)
(fib_lin 5)
(fib_iter_strikt
(fib_iter_strikt
(fib_iter_strikt
(fib_iter_strikt
(fib_iter_strikt
5
P raktische Inf ormatik
1, W S
1
1
2
3
5
0
1
1
2
3
2004/05, F olien Haskell−2,
5)
4)
3)
2)
1)
(12. N ovember2004)
Seite 20
Analyse der fib-Optimierung
Für (fib_lin n) gilt:
• ist operational äquivalent zu fib
• benötigt linear viele Reduktionen abhängig von n
• Größe der Ausdrücke ist beschränkt
• Platzbedarf ist konstant (d.h. unabhängig) von n.
(unter Vernachlässigung der Darstellungsgröße der Zahlen)
erzeugt Iterativen Auswertungsprozess
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 21
Terminierung: Hält 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 hält an für jede positive natürliche Zahl
als Eingabe
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 22
Beispielausführungen von drein
Zum Experimentieren verwende dreinlst.
für 5: 5, 16, 8, 4, 2, 1
für 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 geprüft für alle Zahlen
< 240
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 23
Terminierung
Die Theorie zeigt:
Programmiersprachen, die Programme ausschließen, die manchmal
nicht terminieren
sind nicht allgemein.
D.h. nicht äquivalent zur Turingmaschine
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 24
Terminierungsnachweise
Normalerweise mit vollständiger 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 für n ∈ IN0:
Induktionsbasis ist 0 und 1:
fib 0 und fib 1 terminieren und ergeben Resultat 0 bzw. 1.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 25
Terminierungsnachweis (2)
Induktionsschritt: Für n > 1 gilt:
fib n reduziert zu fib (n − 1) + fib (n − 2).
Induktionshypothese gilt für n − 1 und n − 2, also terminiert fib n.
Insgesamt ist damit die Terminierung gezeigt. QED
Ungelöst: Die einfachen Ansätze zum Terminierungsbeweis für die
3n + 1-Funktion scheitern, da die Argumente unregelmäßig größer und
kleiner werden.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 26
Ressourcenbedarf von Programmen, Effizienz,
Wachstumsraten und Größenordnungen
wichtige Ressourcen:
•
Zeit
•
Platz
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 27
Weitere Ressourcen / Maße:
•
Anzahl benötigter Prozessoren bei parallelen Algorithmen
•
Größe des Programms
•
Kosten für die Kommunikation
•
Anzahl der Aufrufe bestimmter Unterprozeduren (Dienste):
Datenbankzugriffe, usw.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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 für Verifikation / Änderung eines Programms
Kosten innerhalb eines organisatorischen Rahmens
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 29
Optimierung
Optimierung :=
Reduktion des Ressourcenbedarf von Programmen
durch Abänderungen des Programms
ohne Funktionalitätsänderung.
Es gibt verschiedene Prioritäten bei Optimierung:
Wettervorhersage Simulationen:
Anwendung mit Datenübertragung:
Java:
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 30
Zeit
Kommunikation
Kommunikation,Portierbarkeit
Optimierung (2). Zu beachten ist:
• Wie oft wird dieses Programm benötigt? Lohnt sich der Optimieraufwand ?
• optimierte Programme sind oft unübersichtlicher.
• Optimierung wird durch Compiler erledigt
• Optimierung kann die Portierbarkeit verschlechtern
• experimentelle Feststellung des Ressourcenbedarfs ist
fehlerbehaftet und abhängig von (Version der) Programmierumgebung
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 31
Analyse von Programmen
Wir verwenden für Haskell-Programme folgende Messungen.
Benutze verzögerte Auswertung
Zeit:
Anzahl der Transformationsschritte
Platz: (Gesamt-Speicher):
Maximale Größe der Ausdrücke
Arbeitsspeicher:
Maximale Größe der Ausdrücke
(ohne die Eingabe)
arithmetische und Boolesche Operationen = 1 Transformationsschritt.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 32
Analyse von Programmen (2)
Angabe des Ressourcenbedarf eines Algorithmus
in Abhängigkeit von der Größe der Eingabe.
Notation für Algorithmus alg bei Eingabe der Größe n:
redalg(n)
maximale Anzahl der Reduktionen bei verzögerter Auswertung für alle Eingaben der Größe n.
P latzalg(n)
Platzbearf: maximale Größe der Ausdrücke (des gerichteten Graphen) bei verzögerter Auswertung für alle Eingaben der Größe n.
Die Eingaben nicht mitzählen
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 33
Analyse von Programmen (3)
Bei genauerer Analyse einer Problemklasse:
Bezugsgrößen:
!?:
Turingmaschine
oder anderes abstraktes Maschinenmodell
Abhängigkeit vom Maschinenmodell?
Aufwand eines Einzelschrittes (abstr. Maschine)?
Aufwand der eingebauten Funktionen?
(Multiplikation, Addition, Konversionen,usw.).
benötigter Platz für Zahlen? I.a. nicht konstant.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 34
Beispiel: fib
fib n = if n <= 0 then 0
else if n == 1 then 1
else fib (n-1) + fib(n-2)
Bezugsgröße: eingegebene Zahl n
Behauptung:
Beweis:
# rekursive Aufrufe für (fib n) ist ≤ fib(n + 1)
mit vollständiger Induktion
redfib(n) ≤ c ∗ fib(n + 1) wobei c eine Konstante ist.
fib(n) ≈ 1.6n ⇒ redfib(n) ≈ 1.6n (einfach exponentiell)
andere Bezugsgröße: Größe der Darstellung der Zahl n:
n
hat size(n) = dlog10(n)e Dezimalstellen.
Zeitbedarf: ≈ 1.6(10
P raktische Inf ormatik
1, W S
size(n) )
2004/05, F olien Haskell−2,
(doppelt exponentiell).
(12. N ovember2004)
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 38
Beispiel fakultaet n
Es sind: 5 ∗ (n − 1) + 3 Reduktionsschritte.
Vermutung: redfakultaet(n) = 5 ∗ (n − 1) + 3
Nachweis mit vollständiger Induktion:
Beh: fakultaet (n-1) (als Ausdruck)
benötigt 5 ∗ (n − 2) + 4 Reduktionsschritte:
für n ≥ 2
Basis: fakultaet (2-1) benötigt 4 Reduktionsschritte
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 39
Beispiel fakultaet n: Nachweis
Ind. Schritt:
Nachzuweisen ist: fakultaet (n-1) benötigt 5 ∗ (n − 2) + 4 für n > 2.
fakultaet (n-1)
if (n-1) <= 1 then ...
if n1 <= 1 then ...
if False then ...
n1*fakultaet (n1-1)
-- n1 ist Basiswert > 1
Das sind 4 + 5 ∗ (n1 − 2) + 4 + 1 = 5 ∗ (n − 2) + 4 Reduktionsschritte
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 41
Komplexitäten von Algorithmen
Beachte:
breite Streuung des Ressourcenbedarfs ist möglich für
die Menge aller Eingaben einer bestimmten Größe.
Z.B. (3n+1)-Funktion mit Bezugsgröße: Anzahl der Stellen
Komplexitäten von Platz und Zeit:
Ressourcenbedarf
im schlimmsten Fall
im besten Fall
im Mittel
P raktische Inf ormatik
1, W S
(worst-case)
(best-case)
Minimum von # Reduktionen
bzw. Minimum der Größe der Ausdrücke.
(average case)
Welche Verteilung?
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 42
Komplexitäten von Algorithmen
Ein Algorithmus ist effizient, wenn er wenig Ressourcen benötigt
Ein Algorithmus ist optimal, wenn er nicht schlechter“ ist als andere
”
Algorithmen zur gleichen Problemklasse
(Zeit/Platz)-Komplexität einer Problemklasse:
≡ Ressourcenverbrauch des optimalen Algorithmus.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 43
O-Schreibweise
Verwendung: asymptotische Größenordnung von
numerischen Funktionen
hier für: redalg (n) und P latzalg (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) für alle genügend großen n.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 44
O-Schreibweise: Bemerkungen
Beachte R(n) = O(f (n)) keine Gleichung
Beachte R(n) = O(f (n)) ist eine Abschätzung nach oben
Die Angabe R(n) = O(f (n)) sollte möglichst optimales f verwenden
Sprechweisen:
R(n) ist von der Größenordnung f (n)
R(n) hat höchstens Größenordnung f (n)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 45
Beispiele und Eigenschaften zu O()
•
√
n = O(n)
• p(n) = O(2n) für 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 nicht
dn = O(cn).
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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 beschränkt
ist, dann gilt f (n) = O(1).
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 47
Beispiel fib
fib Bezugsgröße:
P raktische Inf ormatik
1, W S
n: Eingabe
d: Größe der Darstellung der Zahl n
redfib(n)
platzfib(n)
=
=
O(1.62n)
O(n)
redfib lin(n)
platzfib lin(n)
=
=
O(n)
O(n)
redfib lin(d)
platzfib lin(d)
=
=
O(10d)
O(10d)
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 48
Einige Komplexitäten
O(1)
O(log(n))
O(n)
O(n ∗ log(n))
O(n2)
O(n3)
O(nk )
O(2n)
P raktische Inf ormatik
1, W S
konstant
logarithmisch
linear
fastlinear (oder auch n-log-n)
quadratisch
kubisch
polynomiell
exponentiell
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 49
Komplexitäten: Veranschaulichung
beispielhafte Tabelle zur intuitiven Veranschaulichung:
Eingabedaten
Algorithmus
log2(n)
n
n2
n3
2n
P raktische Inf ormatik
1, W S
10
100
1000
0.000003 sec
0.00001 sec
0.0001 sec
0.001 sec
0.001 sec
0.000007 sec
0.0001 sec
0.01 sec
1 sec
4 ∗ 1016 Jahre
0.00001
0.001 sec
1 sec
15 min
nahezu ∞
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 50
Kommentare zu O()
•
•
•
•
•
Viele relevante Optimierungen ändern Größenordnung O()
nicht
Verwendung eines schnelleren Rechners:
nur konstante Verbesserung der Zeit, d.h. O() ändert sich
nicht.
Die Bestimmung der genauen Komplexität des Ressourcenbedarfs einer Problemklasse ist jeweils ein sehr schweres theoretisches Problem.
Oft sind nur gute obere Abschätzungen bekannt
Bekannte untere Schranken sind oft trivial oder zu schwach
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 51
Ω-Schreibweise
Ziel:
Größenordnung von numerischen Funktionen nach unten abschätzen.
Seien R, f : IN+ → IR+ zwei Funktionen:
R(n) = Ω(f (n)), wenn es eine Konstante Kgibt, so daß
R(n) ≥ K ∗ f (n) für alle genügend großen n.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 52
Ω-Eigenschaften
Analog zu O(·).
•
•
•
•
•
•
•
•
•
√
n
√ = Ω( n)
n = Ω(1).
2n = Ω(p(n)) für 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
beschränkt ist, dann gilt f (n) = Ω(1).
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 53
Schnelle Berechnung von Potenzen
bn für positive ganze Zahlen n.
Die Potenzen sind rekursiv definiert durch:
(
bn :=
1
falls n = 0
b ∗ 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 Größenordnung O(n)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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:


 1
falls n = 0
bn := (bn/2)2 falls n gerade und ≥ 2


b ∗ bn−1 falls n ungerade
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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 abhängig von n ist O(log(n))
z.B. für n = 1000:
14 Multiplikationen.
tatsächlicher Platz- und Zeitbedarf: O((log(n)3),
wegen Multiplikation von großen Zahlen
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 56
Analyse des Algorithmus zum größ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 =
P raktische Inf ormatik
if b == 0
then a
else ggt b (rem a b)
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 57
Satz von Lamé
SATZ (Lamé): Wenn der Euklidische ggt-Algorithmus k Schritte
benötigt,
dann ist die kleinere Zahl der Eingabe ≥ f ib(k).
Platz- und Zeitbedarf von ggt: O(log(n))
Begründung:
Wenn n die kleinere Zahl ist und der Algorithmus k Schritte benötigt,
dann ist n ≥ f ib(k) ≈ 1.6180k
Also ist k = O(log(n))
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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 für Algorithmus:
Teste für viele verschiedene a: Wenn für 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 möglich
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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
P raktische Inf ormatik
1, W S
= and
2004/05, F olien Haskell−2,
(map (fermat_test_it n)
(take 100 (randomInts 2 n))))
(12. N ovember2004)
Seite 61
Primzahltest: Bemerkungen
Dies ist ein probabilistischer Algorithmus
Eigenschaften
Zeitverbrauch pro Test: O(log n).
Die Antwort: ist keine Primzahl“ ist immer korrekt,
”
während 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.
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 62
Primzahltest: Neuere Ergebnisse
Prüfung einer Zahl auf Primzahleigenschaft ist in polynomieller Zeit
möglich
(d.h. in O(log(n)) ).
(siehe: M. Agrawal, N. Kayal, N. Saxena: PRIMES is in P )
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 63
Beispiel: Fermatsche Primzahlen
n
Vermutung von Pierre de Fermat: 22 + 1 ist immer eine Primzahl
geometrische Konstruierbarkeit mittels Zirkel und Lineal
von gleichseitigen Vielecken ist möglich,
wenn die Anzahl der Seiten die Form
2m ∗ p hat und p eine Fermatsche Primzahl ist
n
Widerlegung der Vermutung: 22 + 1 ist keine Primzahl für n =
5, 6, 7, 8, 9
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
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, . . .)
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 65
Beispiel: Mersennesche Primzahlen
sind von der Form 2p − 1, wobei p selbst eine Primzahl ist.
Mersennesche Primzahlen sind
Rekordhalter als größte Primzahlen
Es sind Primzahlen für 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 Primzahl
224036583 − 1,
Siehe http://www.mersenne.org/history.htm#found
p = 2281 ist machbar mit Haskell Interpreter (einige Minuten)
mersenne_prim_test 2281
P raktische Inf ormatik
1, W S
2004/05, F olien Haskell−2,
(12. N ovember2004)
Seite 66
Herunterladen