Algorithmen und Datenstrukturen -- Einführung

Werbung
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Gliederung
Algorithmen und Datenstrukturen – Einführung
Weitere Aspekte von Algorithmen
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
1
2
3
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Winter 2008/2009, 3. November 2008
D. Rösner
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
D. Rösner
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Aufwandbetrachtungen:
Beispiel: Berechnung der Fibonacci-Zahlen
für ein Problem gibt es oft unterschiedlich aufwendige
Lösungen
Beispiel: Fibonacci-Zahlen
die Folge der Fibonacci-Zahlen ist definiert durch:
Anfangswerte:
die Definition der Fibonacci-Zahlen lässt sich direkt in
einen rekursiven Algorithmus umsetzen
in Haskell: Variante mit Pattern matching
fib :: Int -> Int
fib0 = 1, fib1 = 1
für alle anderen Werte (d.h. für n ≥ 2) gilt die folgende
rekursive Definition:
fibn = fibn−1 + fibn−2
fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
die Fibonacci-Zahlen wurden von Leonardo von Pisa (ca.
1170 – 1250; genannt Fibonacci) entwickelt, um u.a. die
Vermehrung von Kaninchen-Populationen zu beschreiben
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Beispiel: Berechnung der Fibonacci-Zahlen
die Werte in der Folge wachsen sehr schnell an
so ergeben sich die ersten 30 Fibonacci-Zahlen als
Main> take 30 [(n, fib n)| n <- [0 ..]]
[(0,1),(1,1),(2,2),(3,3),(4,5),(5,8),(6,13),(7,21),
(8,34),(9,55),(10,89),(11,144),(12,233),(13,377),
(14,610),(15,987),(16,1597),(17,2584),(18,4181),
(19,6765),(20,10946),(21,17711),(22,28657),(23,46368),
(24,75025),(25,121393),(26,196418),(27,317811),
(28,514229),(29,832040)]
D. Rösner
Beispiel: Berechnung der Fibonacci-Zahlen
die direkte Umsetzung der Definition erfordert einen
Aufwand, der exponentiell in Abhängigkeit von n anwächst
dies ergibt sich aus folgender Abschätzung nach unten für
den mindestens erforderlichen Aufwand (hier gemessen in
Anzahl von Funktionsaufrufen):
wegen fib n = fib (n - 1) + fib (n - 2) :
aufwand(fib n) ≥ 2 * aufwand(fib (n - 2))
≥ 2 * 2 * aufwand(fib (n - 4))
...
für n gerade:
≥ 2(n/2−1) * aufwand(fib 2)
= 2n/2
analog für n ungerade:
≥ 2(n−1)/2−1 * aufwand(fib 3)
≥ 2(n−1)/2
D. Rösner
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Beispiel: Berechnung der Fibonacci-Zahlen
Vergleich von Funktionen
asymptotischer Vergleich von Funktionen
zusammengefasst:
O (sprich: gross-0)
Aufwand für Berechnung von fib n (hier gemessen in
Anzahl von Funktionsaufrufen) wächst in Abhängigkeit von
n mindestens so stark wie 2(n−1)/2
für “asymptotisch kleiner als oder gleich“
im Kontrast dazu ist der Aufwand für die Berechnung von
fastFib n (vgl. letzte Vorlesung und [Tho99], pp. 75)
nur eine lineare Funktion von n
Definition (vgl. [GT01], 3.6):
D. Rösner
AuD 2008/2009 . . .
Seien im folgenden f und g Funktionen von den natürlichen
Zahlen in die nichtnegativen reellen Zahlen.
f(n) ist O(g(n))
wenn es eine reelle Konstante c > 0 und eine natürliche
Zahl n0 ≥ 1 gibt, so dass
f(n) ≤ c g(n) für alle n ≥ n0
D. Rösner
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Vergleich von Funktionen
Vergleich von Funktionen
Θ (sprich: gross-Theta)
Ω (sprich: gross-0mega)
für “asymptotisch gleich“
für “asymptotisch grösser als oder gleich“
Definition (vgl. [GT01], 3.6):
Definition (vgl. [GT01], 3.6):
f(n) ist Ω(g(n))
wenn g(n) ist O(f(n)) d.h. es gibt eine reelle Konstante c > 0
und eine natürliche Zahl n0 ≥ 1, so dass
f(n) ≥ c g(n) für alle n ≥ n0
D. Rösner
AuD 2008/2009 . . .
f(n) ist Θ(g(n))
wenn
f(n) ist O(g(n)) und
f(n) ist Ω(g(n))
m.a.W. es gibt reelle Konstanten c > 0 und d > 0 und eine
natürliche Zahl n0 ≥ 1, so dass
c g(n) ≤ f(n) ≤ d g(n) für alle n ≥ n0
D. Rösner
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Vergleich von Funktionen
Vergleich von Funktionen
Beispiele (vgl. [GT01], 3.6):
20 n3 + 10 n log n + 5 ist O(n3 )
Begründung:
für n ≥ 1 : log n < n
n log n < n2 ≤ n3
10 n log n ≤ 10 n3
Damit: 20 n3 + 10 n log n + 5 ≤ 35 n3
D. Rösner
AuD 2008/2009 . . .
AuD 2008/2009 . . .
Beispiele (vgl. [GT01], 3.6):
jedes Polynom ak nk + ak −1 nk −1 + . . . + a0 ist O(nk )
3 log n + log log n ist O(log n)
Begründung:
für n ≥ 2 : log log n ≤ log n
Damit: 3 log n + log log n ≤ 4 log n für n ≥ 2
D. Rösner
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Aufwand bei Listenfunktionen
Aufwand bei Listenfunktionen
Test, ob ein Element in einer Liste der Länge n enthalten
Zugriff auf das erste Listenelement (den Listenkopf)
im Prelude definiert als:
head
:: [a] -> a
head (x:_)
der Aufwand ist unabhängig von der Länge der Liste
konstant, d.h. O(1)
elem _ []
elem y (x:xs)
= False
= if y == x then True
else elem y xs
schlechtester Fall (sog. “worst case“): y ist überhaupt nicht
in der Liste enthalten (oder als letztes Element)
Aufwand (hier z.B. Zahl der rekursiven Aufrufe und der
Tests auf Gleichheit) ist linear bezeogen auf n, d.h. O(n)
D. Rösner
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
AuD 2008/2009 . . .
Aufwandbetrachtungen:
O-Notation
Listenfunktionen
Aufwand bei Listenfunktionen
Schnittbildung zweier Listen, d.h. Bestimmung derjenigen
Elemente, die in beiden Listen enthalten
intersect
intersect _ []
intersect [] _
intersect (x:xs) y
:: a -> [a] -> Bool
günstigster Fall: y ist gleich dem ersten Listenelement
= x
D. Rösner
elem
:: [a] -> [a] -> [a]
= []
= []
= if elem x y
then x:(intersect xs y)
else (intersect xs y)
schlechtester Fall: die Listen haben keine gemeinsamen
Elemente
mit m = length (x:xs) und n = length y ergeben sich m mal
n Tests auf Enthaltensein
Literatur:
Michael T. Goodrich and Roberto Tamassia.
Data Structures and Algorithms in Java.
John Wiley & Sons, New York, 2001.
ISBN 0-471-38367-8; 2nd edition.
Simon Thompson.
Haskell - The Craft of Functional Programming.
Addison Wesley Longman Ltd., Essex, 1999.
2nd edition, ISBN 0-201-34275-8; Accompanying Web site:
http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e.
m.a.W.: Aufwand ist quadratisch, d.h. O(n2 )
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Herunterladen