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 = if x <= 1 then 1 else x*(fakultaet (x-1)) P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 2
Auswertungsprozess, linear rekursiv (fakultaet 6) Auswertungsprozess ist linear rekursiv Charakteristisch: nur eine rekursive Funktionsanwendung in jedem Ausdruck der Reduktionsfolge Zwischenausdrücke sind unbeschränkt in der Größe P raktische Informatik 1, W S 2004/05, F olien 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 P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 4
Alternative Berechnungen der Fakultätsfunktion Iteriere folgende Regel: Produkt Produkt Zähler 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 5
Endrekursion Eine Endrekursion ist eine lineare Rekursion. Zusätzlich muss gelten: alle rekursiven Aufrufe berechnen den Rückgabewert ohne Nachverarbeitung P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 7
Iterativer Auswertungsprozess: Fakultät (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 Endrekursion Argumente sind Basiswerte (bzw. Größe des Gesamtausdrucks bleibt beschränkt.) optimierte Rückgabe des Wertes P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 8
Optimierung der Endrekursion imperative Programmiersprachen Haskell 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. Deshalb: Iterationskonstrukte in imperativen Programmiersprachen: for...do, while, oder repeat...until. P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 10
Baumrekursion Beispiel Berechnung der Fibonacci-Zahlen 1, 1, 2, 3, 5, 8, 13, 21,... F ib(n) := fib n = if n <= 0 then 0 else if n == 1 then 1 else fib (n-1) + fib(n-2) 0 falls n = 0 1 falls n = 1 F ib(n 1) + F ib(n 2) sonst P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 11
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) + 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... P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 12
Auswertungsprozess zu fibs: Baum der Aufrufe 3 2 1 1 0 4 2 5 1 0 2 1 0 3 1 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 13
Geschachtelte Rekursion Ist der allgemeine Fall wird normalerweise selten benötigt, 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 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 Informatik 1, W S 2004/05, F olien 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 Komplexitätstheorie P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 15
Tabelle der Rekursionsprozesse: linear rekursiv endrekursiv iterativ Baumrekursion geschachtelte Baumrekursion 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 P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 16
Beispiel Optimierung: Iteration statt Rekursion Berechnung von (fib 5) fib 3 wird fib 2 wird fib 1 wird 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 fib n Φn 5 wobei Φ = 1+ 5 2 1.6180 Fazit: fib(n) wächst exponentiell # Reduktionen für fib(n) ist exponentiell d.h. die Laufzeit von fib ist exponentiell P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien 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)) P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 19
Prozess für (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 P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 < 2 40 P raktische Informatik 1, W S 2004/05, F olien 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 äquivalent zur Turingmaschine P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 IN 0 : Induktionsbasis ist 0 und 1: fib 0 und fib 1 terminieren und ergeben Resultat 0 bzw. 1. P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 26
Ressourcenbedarf von Programmen, Effizienz, Wachstumsraten und Größenordnungen wichtige Ressourcen: Zeit Platz P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien 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 für Verifikation / Änderung eines Programms Kosten innerhalb eines organisatorischen Rahmens P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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: Zeit Kommunikation Kommunikation,Portierbarkeit P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 30
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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 31
Analyse von Programmen Wir verwenden für Haskell-Programme folgende Messungen. Benutze verzögerte Auswertung Zeit: Platz: (Gesamt-Speicher): Arbeitsspeicher: Anzahl der Transformationsschritte Maximale Größe der Ausdrücke Maximale Größe der Ausdrücke (ohne die Eingabe) arithmetische und Boolesche Operationen = 1 Transformationsschritt. P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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: red alg (n) P latz alg (n) maximale Anzahl der Reduktionen bei verzögerter Auswertung für alle Eingaben der Größe 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien 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) Bezugsgröße: eingegebene Zahl n Behauptung: # rekursive Aufrufe für (fib n) ist fib(n + 1) Beweis: mit vollständiger Induktion red fib (n) c fib(n + 1) wobei c eine Konstante ist. fib(n) 1.6 n red fib (n) 1.6 n (einfach exponentiell) andere Bezugsgröße: Größe der Darstellung der Zahl n: n hat size(n) = log 10 (n) Dezimalstellen. Zeitbedarf: 1.6 (10size(n)) (doppelt exponentiell). P raktische Informatik 1, W S 2004/05, F olien 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 P raktische Informatik 1, W S 2004/05, F olien 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 P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 37
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 Beispiel fakultaet 3 fakultaet 3 : 13 Reduktionschritte P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 38
Beispiel fakultaet n Es sind: 5 (n 1) + 3 Reduktionsschritte. Vermutung: red fakultaet (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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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... -- n1 ist Basiswert > 1 if False then... n1*fakultaet (n1-1) Das sind 4 + 5 (n1 2) + 4 + 1 = 5 (n 2) + 4 Reduktionsschritte P raktische Informatik 1, W S 2004/05, F olien 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 P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 (worst-case) (best-case) Minimum von # Reduktionen bzw. Minimum der Größe der Ausdrücke. (average case) Welche Verteilung? P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 43
O-Schreibweise Verwendung: asymptotische Größenordnung von numerischen Funktionen hier für: red alg (n) und P latz alg (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 Informatik 1, W S 2004/05, F olien 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 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 45
Beispiele und Eigenschaften zu O() n = O(n) p(n) = O(2 n ) 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(c n+e ) gdw. f(n) = O(c n ) Wenn c, d > 1, dann gilt: f(n) = O(log c (n)) gdw. f(n) = O(log d (n)) Wenn c, d > 1, und c < d, dann gilt: c n = O(d n ), aber nicht d n = O(c n ). P raktische Informatik 1, W S 2004/05, F olien 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 beschränkt ist, dann gilt f(n) = O(1). P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 47
Beispiel fib fib Bezugsgröße: n: Eingabe d: Größe der Darstellung der Zahl n red fib (n) = O(1.62 n ) platz fib (n) = O(n) red fib lin (n) = O(n) platz fib lin (n) = O(n) red fib lin (d) = O(10 d ) platz fib lin (d) = O(10 d ) P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 48
Einige Komplexitäten O(1) konstant O(log(n)) logarithmisch O(n) linear O(n log(n)) fastlinear (oder auch n-log-n) O(n 2 ) quadratisch O(n 3 ) kubisch O(n k ) polynomiell O(2 n ) exponentiell P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 49
Komplexitäten: Veranschaulichung beispielhafte Tabelle zur intuitiven Veranschaulichung: Eingabedaten 10 100 1000 Algorithmus log 2 (n) 0.000003 sec 0.000007 sec 0.00001 n 0.00001 sec 0.0001 sec 0.001 sec n 2 0.0001 sec 0.01 sec 1 sec n 3 0.001 sec 1 sec 15 min 2 n 0.001 sec 4 10 16 Jahre nahezu P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 52
Ω-Eigenschaften Analog zu O( ). n = Ω( n) n = Ω(1). 2 n = Ω(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) = Ω(c n+e ) gdw. f(n) = Ω(c n ) Wenn c, d > 1, dann gilt: f(n) = Ω(log c (n)) gdw. f(n) = Ω(log d (n)) Wenn c, d > 1, und c < d, dann gilt: d n = Ω(c n ), aber nicht c n = Ω(d n ). 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 53
Schnelle Berechnung von Potenzen b n für positive ganze Zahlen n. Die Potenzen sind rekursiv definiert durch: b n := { 1 falls n = 0 b b n 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 54
Optimierung der Potenzberechnung Idee: Statt b 8 = b b b b b b b b berechne b 2 := b b b 4 = b 2 b 2 b 8 = b 4 b 4 allgemeine Rechenvorschrift: b n := 1 falls n = 0 (b n/2 ) 2 falls n gerade und 2 b b n 1 falls n ungerade P raktische Informatik 1, W S 2004/05, F olien 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 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 56
Analyse des Algorithmus zum größten ggt(a, b) (Euklids Algorithmus) gemeinsamen Teiler Teile a durch b gibt Rest r, wenn r = 0, dann ggt(a, b) := b wenn r 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) P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 57
Satz von Lamé SATZ (Lamé): Wenn der Euklidische ggt-algorithmus k Schritte benötigt, dann ist die kleinere Zahl der Eingabe fib(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 fib(k) 1.6180 k Also ist k = O(log(n)) P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 58
Problem: Gegeben n. Test auf Primzahl-Eigenschaft 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 Informatik 1, W S 2004/05, F olien 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 a p a(mod p) Idee für Algorithmus: Teste für viele verschiedene a: Wenn für ein a: a n a(mod n), dann ist n keine Primzahl. Bei ausreichend vielen Zahlen a mit a n a(mod n): mit hoher Wahrscheinlichkeit ist n Primzahl Aber: Ausnahmen sind möglich P raktische Informatik 1, W S 2004/05, F olien 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)))) P raktische Informatik 1, W S 2004/05, F olien 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, 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 10 6 aus. P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) 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 Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 63
Beispiel: Fermatsche Primzahlen Vermutung von Pierre de Fermat: 2 2n + 1 ist immer eine Primzahl geometrische Konstruierbarkeit mittels Zirkel und Lineal von gleichseitigen Vielecken ist möglich, wenn die Anzahl der Seiten die Form 2 m p hat und p eine Fermatsche Primzahl ist Widerlegung der Vermutung: 2 2n + 1 ist keine Primzahl für n = 5, 6, 7, 8, 9 P raktische Informatik 1, W S 2004/05, F olien 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,...) P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 65
Beispiel: Mersennesche Primzahlen sind von der Form 2 p 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 2 24036583 1, Siehe http://www.mersenne.org/history.htm#found p = 2281 ist machbar mit Haskell Interpreter (einige Minuten) mersenne_prim_test 2281 P raktische Informatik 1, W S 2004/05, F olien Haskell 2, (12. November2004) Seite 66