Algorithmen und Datenstrukturen -- Einführung

Werbung
Einleitung
EUKLID
Primzahltest
Einleitung
EUKLID
Primzahltest
Gliederung
Algorithmen und Datenstrukturen – Einführung
Algorithmen
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
1
Einleitung
2
EUKLID
3
Primzahltest
Winter 2008/2009, 20. Oktober 2008
D. Rösner
AuD 2008/2009 . . .
D. Rösner
Einleitung
EUKLID
Primzahltest
AuD 2008/2009 . . .
Einleitung
EUKLID
Primzahltest
Algorithmus
Frage:
Was ist die wichtigste Fähigkeit, die in einem Studium der
Informatik
oder Wirtschaftsinformatik
oder Computervisualistik
oder Computer Systems Engineering/Ingenieurinformatik
oder vergleichbarer Studiengänge
erworben und ausgebaut werden sollte?
mögliche Antwort:
Fähigkeit, für (viele) Probleme Lösungen finden zu können
Problemlösungen dabei in Form von Algorithmen, die dann
in ausführbare Programme umgesetzt
D. Rösner
AuD 2008/2009 . . .
Algorithmus ist einer der zentralen Begriffe der Informatik
Algorithmen:
gibt es auch unabhängig von Computern
gibt es schon seit tausenden von Jahren
Bezeichnung ’Algorithmus’ ist vom Namen des persischen
Gelehrten Muhammed Al Chwarizimi (etwa 783 bis 850)
abgeleitet (s.a. [PD08])
D. Rösner
AuD 2008/2009 . . .
Einleitung
EUKLID
Primzahltest
Einleitung
EUKLID
Primzahltest
Algorithmus
Algorithmus
Algorithmen (zumindest in einem intuitiven Sinne)
begegnen uns auch im Alltag:
Kochrezepte
Bau- und Montageanleitungen
Betriebsanleitungen
s.a. [SS02]
D. Rösner
AuD 2008/2009 . . .
Einleitung
EUKLID
Primzahltest
Ein Algorithmus ist eine präzise (d.h. in einer festgelegten
Sprache abgefasste) endliche Beschreibung eines
allgemeinen Verfahrens unter Verwendung ausführbarer
elementarer (Verarbeitungs-)Schritte.
D. Rösner
AuD 2008/2009 . . .
Einleitung
EUKLID
Primzahltest
EUKLIDs Algorithmus
EUKLIDs Algorithmus
Auf EUKLID (≈ 300 v. Chr.) geht ein Algorithmus zur
Bestimmung des grössten gemeinsamen Teiler (ggT)
zweier nicht negativer ganzer Zahlen zurück.
Der ggT von x und y ist definiert als diejenige Zahl z, für
die gilt:
Eine Möglichkeit zum Bestimmen des ggT (x, y):
Bestimme die Primfaktorzerlegung von x und von y und
bilde das Produkt derjenigen Primfaktoren, die sowohl in
der Faktorzerlegung von x wie in der von y vorkommen.
EUKLIDs Algorithmus ist ‘einfacher’ und eleganter. Er nutzt
die folgenden Beziehungen:
z ist Teiler von x,
z ist Teiler von y und
für jedes z’ mit
z’ Teiler von x und z’ Teiler von y gilt:
z’ ≤ z
D. Rösner
eine intuitive Begriffsbestimmung für Algorithmus (vgl.
[SS02])
AuD 2008/2009 . . .
ggT(x, y) = ggT(y, Rest von x/y) falls y > 0
ggT(x, y) = x falls y = 0
D. Rösner
AuD 2008/2009 . . .
Einleitung
EUKLID
Primzahltest
Einleitung
EUKLID
Primzahltest
EUKLIDs Algorithmus
EUKLIDs Algorithmus
eine mögliche Realisierung in Haskell:
ggT :: Int -> Int -> Int
Fragen:
Terminiert der Algorithmus immer?
Warum?
Wird immer der richtige Wert berechnet?
m.a.W.: Ist der Algorithmus korrekt?
Hilft Testen beim Beantworten dieser Frage?
D. Rösner
AuD 2008/2009 . . .
Einleitung
EUKLID
Primzahltest
Main> ggT 69 81
3
Main> ggT 43 101
1
Main> ggT 69 23
23
D. Rösner
AuD 2008/2009 . . .
Algorithmus Primzahltest
alternative Realisierung mit Wächtern (guards):
ggT’ :: Int -> Int -> Int
x y
y > 0 = ggT’ y (rem x y)
y == 0 = x
otherwise = error "ggT’: Argument y darf nicht negativ sein"
Bedingungen der Wächter werden nacheinander (von
oben nach unten) überprüft
sobald eine erfüllt ist, wird ihre rechte Seite (nach =)
ausgewertet und ergibt den Wert
otherwise als letzter Wächter trifft immer zu (sog. catch
all-Bedingung)
D. Rösner
einige Beispiele für Verwendung:
Einleitung
EUKLID
Primzahltest
EUKLIDs Algorithmus
ggT’
|
|
|
ggT x y =
if y > 0 then ggT y (rem x y)
else if y == 0 then x
else error "ggT: Argument y darf nicht negativ sein"
AuD 2008/2009 . . .
Primzahlen . . . z.B. wichtig für bestimmte
Verschlüsselungsverfahren
im folgenden werden Varianten eines Primzahltest
entwickelt (s.a. [SS02], p. 65)
zur Erinnerung:
Definition: Eine natürliche Zahl n (n > 1) ist genau dann
Primzahl, wenn sie nur durch sich selbst und durch 1 teilbar
ist.
Beispiele: prim oder nicht prim?
2 ist . . .
3 ist . . .
alle geraden Zahlen grösser 2 sind . . .
31 ist . . .
51 ist . . .
...
D. Rösner
AuD 2008/2009 . . .
Einleitung
EUKLID
Primzahltest
Einleitung
EUKLID
Primzahltest
Algorithmus Primzahltest
Algorithmus Primzahltest
erste Version des Algorithmus:
erster Schritt:
Test auf Teilbarkeit:
istTeilerVon :: Int -> Int -> Bool
istTeilerVon cand zahl = mod zahl cand == 0
realisiert mit einer Hilfsfunktion:
istPrim :: Int -> Bool
Beispiele für Verwendung:
Main> 5 ‘istTeilerVon‘ 20
True
Main> istTeilerVon 7 15
False
Main> istTeilerVon 7 63
True
D. Rösner
Um zu entscheiden, ob n > 1 Primzahl, teste, ob n durch
irgendeine Zahl m mit 2 <= m < n teilbar.
Wenn dies zutrifft, dann ist n nicht prim, andernfalls ist n
prim.
istPrim n = if n <= 1 then False else primtest 2 n
primtest m n
= if m >= n then True
else if istTeilerVon m n then False
else primtest (m + 1) n
AuD 2008/2009 . . .
D. Rösner
Einleitung
EUKLID
Primzahltest
Einleitung
EUKLID
Primzahltest
Algorithmus Primzahltest
Algorithmus Primzahltest
Variante 1 funktioniert (d.h. ist effektiv), ist aber nicht
effizient genug
verbesserte Variante:
Ziel: unnötigen Aufwand vermeiden
es brauchen nur m = 2 und dann nur noch ungerade m
getestet werden
es braucht auch nicht bis m = n getestet zu werden,
sondern es reicht zu testen, solange m*m <= n
AuD 2008/2009 . . .
Variante 2:
istPrim’ :: Int -> Bool
istPrim’ n
= if n <= 1 || (n > 2 && istTeilerVon 2 n) then False
else primtest 3
where
primtest m = if m * m > n then True
else if istTeilerVon m n then False
else primtest (m + 2)
Mit beiden Veränderungen lässt sich der Aufwand deutlich
verringern.
Hinweis: primtest ist hier lokale Definition (nach where),
d.h. nur innerhalb von istPrim’ sichtbar
Motto (manchmal): Make it work, then make it fast!
n ist innerhalb von primtest ’sichtbar’ und braucht daher
nicht als Parameter übergeben zu werden
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Einleitung
EUKLID
Primzahltest
Einleitung
EUKLID
Primzahltest
Algorithmus Primzahltest
Literatur:
weitere Variante:
istPrim’’ :: Int -> Bool
istPrim’’ n
= if n <= 1 then False else primtest 2
where
primtest m
= if m * m > n then True
else if istTeilerVon m n then False
else primtest (if (m==2) then (m+1) else (m+2))
Hinweis: der letzte else-Zweig in primtest könnte
gleichwertig auch wie folgt lauten:
...
Gustav Pomberger and Heinz Dobler.
Algorithmen und Datenstrukturen – Eine systematische
Einführung in die Programmierung.
Pearson Education Dtl. GmbH, München, 2008.
Gunter Saake and Kai-Uwe Sattler.
Algorithmen und Datenstrukturen – Eine Einführung mit
Java.
dpunkt.verlag, Heidelberg, 2002.
ISBN 3-89864-122-8.
else if istTeilerVon m n then False
else if (m==2) then primtest (m+1) else primtest (m + 2)
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Herunterladen