Einführung in die Informatik I Algorithmen und deren Programmierung Prof. Dr. Nikolaus Wulff
Definition Algorithmus Ein Algorithmus ist eine präzise formulierte Handlungsanweisung zur Lösung einer gleichartigen Klasse von Problemen. Ein Algorithmus besteht meist aus einer Folge von Anweisungen, die von einem Menschen/einer Maschine interpretiert und geeignet abgearbeitet werden können. Wenn er immer in einer endlichen Anzahl von Schritten beendet ist, terminiert der Algorithmus. Ein deterministischer Algorithmus hat eine eindeutig festgelegte Schrittfolge. Ist das Endergebnis, bei vorgegebenen Eingangsdaten, eindeutig bestimmt, so ist der Algorithmus determiniert. Prof. Dr. Nikolaus Wulff Informatik I 2
Algorithmen Beispiele Umgangssprachliche Algorithmen: Jedes (gute, genaue) Koch- und Backrezept. Bedienungsanleitung eines Telefons. Tonfolge einer Melodie an Hand von Noten.... Mathematische Algorithmen: Zerlegung einer natürlichen Zahl in Primfaktoren. Finden des größten gemeinsamen Teilers (ggt). Lösen von Ax=y per Gauss-Eliminationsverfahren. Lösen von f(x)=0 per Newton-Verfahren. Prof. Dr. Nikolaus Wulff Informatik I 3
Entwicklung des ggt Algorithmus Zur Illustration wird ein Algorithmus zur Bestimmung des größten gemeinsamen Teilers ggt entwickelt. Für Zahlen a, b N gilt die Beziehung ggt a,b kgv a,b =a b Der Algorithmus wurde bereits um ~330 v.chr. beschrieben: Wenn b aber a nicht misst, und man nimmt bei a, b abwechselnd immer das Kleinere vom Größeren weg, dann muss (schließlich) eine Zahl übrig bleiben, die die Vorangehende misst... Prof. Dr. Nikolaus Wulff Informatik I 4
Euklidischer Algorithmus Gesucht ist der ggt(a,b) für a, b N 0. Setze m=a und n=b. 1. Falls m < n vertausche m und n. 2. Berechne r = m n. 3. Setze m=n, n=r. 4. Falls r>0 ist, so mache weiter bei 1. 5. Die Zahl m ist der gesuchte ggt(a,b). Schleife Dies ist eine exakte, deterministische Vorschrift. Da m und n immer kleiner werden, muss der Algorithmus nach endlich vielen Schritten terminieren. Prof. Dr. Nikolaus Wulff Informatik I 5
Flussdiagramm Algorithmen lassen sich mittels Flussdiagrammen grafisch visualisieren. Sie bestehen aus einfachen elementaren Symbolen: Anfang: Hier beginnt die Ausführung Anweisung/Elementaraktion Der Pfeil zeigt auf nächste Anweisung Test: Im Karo steht eine Bedingung (if) Ende: Hier endet die Ausführung Prof. Dr. Nikolaus Wulff Informatik I 6
Flussdiagramm des ggt Start 0 m := a n := b T 1 m < n F 4 T r > 0 F 5 1 r := m m := n n := r r := m - n 2 3 m := n n := r Ziel Prof. Dr. Nikolaus Wulff Informatik I 7
C Implementierung des ggt int ggt(int a, int b) { int r, m = a, n = b; do { if (m < n) { r = m; m = n; n = r; } r = m - n; m = n; n = r; } while(r>0); return m; } 0 1 2 3 4 5 Prof. Dr. Nikolaus Wulff Informatik I 8
Ablauf einer ggt Berechnung Ablauf der Berechnung vom ggt(64,24): r 1 = 64 24 = 40, m 1 = 40, n 1 = 24 r 2 = 40 24 = 16, m 2 = 24, n 2 = 16 r 3 = 24 16 = 8, m 3 = 16, n 3 = 8 r 4 = 16 8 = 8, m 4 = 8, n 4 = 8 r 5 = 8 8 = 0, m 5 = 8, n 5 = 0 Nach fünf Iterationen ist das Ergebnis 8 ermittelt. Ist dies die beste Methode um den ggt zu berechnen? Problematisch sind die vielen Subtraktionen bei großen Unterschieden zwischen a und b. Prof. Dr. Nikolaus Wulff Informatik I 9
Optimierung des ggt Algorithmus Eine Analyse des größten gemeinsamen Teilers zeigt: ggt(a, b) = ggt(b, a) und ggt(a, b) = ggt(a, a-b) Um z.b. den ggt(10,2) zu berechnen muss 5 mal die 2 abgezogen werden: ggt(10,2) = ggt(8,2) = ggt(6,2) = ggt(4,2) = ggt(2,2) = 2 Der ggt kann wesentlich schneller berechnet werden, wenn anstatt mehrfacher Subtraktionen eine Division mit Rest erfolgt, d.h. für a=qb+r: ggt(a, b) = ggt(qb+r, b) = ggt(b, r) Die Modulo a/b=q mod r Variante benötigt weniger Schritte, da q Subtraktionen eingespart werden. Prof. Dr. Nikolaus Wulff Informatik I 10
Optimierter ggt Algorithmus Gesucht ist der ggt(a,b) für 0. Setze m=a und n=b. 1. Falls m < n vertausche m und n. 2. Berechne r = m mod n. 3. Setze m=n, n=r. a, b N 4. Falls r>0 ist, so mache weiter bei 1. 5. Die Zahl m ist der gesuchte ggt(a,b). Die Modulo Operation ist leicht mit einem Rechner auszuführen und der Algorithmus terminiert auch bei großen Unterschieden zwischen a und b wesentlich schneller. Eine kleine Änderung mit großer Wirkung! Prof. Dr. Nikolaus Wulff Informatik I 11
ggt mit Modulo Operation int ggt(int a, int b) { int r, m = a, n = b; do { if (m < n) { r = m; m = n; n = r; } r = m % n; m = n; n = r; } while(r>0); return m; } 0 1 2 3 4 5 Prof. Dr. Nikolaus Wulff Informatik I 12
Optimierte ggt Implementierung int ggt(int m, int n) { int r; do { if (m < n) { r = m, m = n, n = r; } r = m % n; m = n; n = r; } while(r>0); return m; } Da C Kopien von a und b verwendet, kann das Kopieren von a nach m und b nach n entfallen... Prof. Dr. Nikolaus Wulff Informatik I 13
Zahlen raten Aufgabe ist es, eine bestimmte ganze Zahl n aus einer endlichen Menge zu erraten. M =[a, b] N Geantwortet wird immer nur mit die Zahl n ist kleiner, größer oder gleich einer gegebenen Zahl z. Gesucht ist die beste Strategie, um die Zahl n möglichst schnell zu finden. Ein deterministisches Verfahren, das immer zum Erfolg führt, ist bei z=a zu beginnen und dann immer z um eins zu erhöhen bis n gefunden wurde, dies wird spätesten nach m=(b-a) Versuchen der Fall sein. Dies ist die dümmste und ungünstigste Variante und benötigt im Mittel m/2 Versuche. Prof. Dr. Nikolaus Wulff Informatik I 14
Intervallhalbierung Effizienter ist das Verfahren der Intervallhalbierung: 1. Wähle als gesuchte Zahl z =(b+a)/2. 2. Falls z < n setze als neue untere Intervallgrenze a = z und gehe zu 1. 3. Fall z > n setze als neue obere Intervallgrenze b = z und gehe zu 1. 4. Es gilt z = n und die gesuchte Zahl ist gefunden. Um die m-elementige Menge M auf 1 zu reduzieren sind maximal m < 2 k Operationen notwendig. D.h. dieser Algorithmus hat eine Laufzeit ~ log 2 m. Prof. Dr. Nikolaus Wulff Informatik I 15
Flussdiagramm Intervallhalbierung Start 1 a := z z := (a+b)/2 b := z 2 3 T T F z < n z > n F 4 Ziel Prof. Dr. Nikolaus Wulff Informatik I 16
Nullstellensuche Ein weiteres Beispiel für einen einfachen Algorithmus ist das Bisektionsverfahren zur Suche der Nullstelle einer stetigen Funktion f :R R auf einem endlichen Intervall I =[a,b] R mit f a f b 0. Letztere Bedingung garantiert, unter Anwendung des Zwischenwertsatzes für stetige Funktionen, dass mindestens eine Nullstelle [a, b] existieren muss mit f =0. Das eben illustrierte Verfahren auf einer diskreten Menge M lässt sich direkt auf ein Intervall übertragen. Durch fortgesetzte Halbierung des Intervalls I wird die gesuchte Nullstelle immer enger eingegrenzt. Prof. Dr. Nikolaus Wulff Informatik I 17
Das Bisektionsverfahren Analog zum Zahlenraten lautet die Anweisung für das Bisektionsverfahren generiere eine Folge {x k }: 1. Wähle als gesuchte Zahl x =(b+a)/2. 2. Falls f(x) < 0 setze als neue untere Intervallgrenze a = x und gehe zu 4. 3. Fall f(x) > 0 setze als neue obere Intervallgrenze b = x und gehe zu 4. 4. Die Bedingung f(z) = 0 wird allerdings kaum zu erfüllen sein. Statt dessen wird gesetzt: Falls das verbleibende Fehlerintervall (b-a)/2 größer ist, als eine vorgegebene Fehlerschranke, so gehe zu Schritt 1. 5. Das aktuelle x k approximiert die gesuchte Nullstelle genau genug, d.h x k Prof. Dr. Nikolaus Wulff Informatik I 18
Das Bisektionsverfahren Quelle: http://de.wikipedia.org/wiki/bisektion X 2 X 4 X 3 X 1 Das Bisektionsverfahren: Durch fortgesetzte Intervallhalbierung entsteht eine konvergente Folge {x k } mit lim k x k = und f =0 Prof. Dr. Nikolaus Wulff Informatik I 19
Konvergenzverhalten Nach der ersten Iteration ist x 1 =(a+b)/2 und der maximale Fehler 1 = x 1 b a /2. Nach der k-ten Iteration ist der Fehler k bedingt durch die Intervallschachtelung abschätzbar zu: k = x k b a /2 k D. h. die Zahlen {x k } definieren eine konvergente Cauchy-Folge: Zu beliebigem > 0 gibt es mit m :=log 2 b a / ein n:= m 1 N so dass k = x k k n Prof. Dr. Nikolaus Wulff Informatik I 20
Algorithmen entwickeln Die Lösung eines Problems zu finden ist nicht einfach und auch nicht systematisch standardisiert. Algorithmen zu entwickeln ist eine Kunst. Algorithmen und Daten werden im Rechner immer als Binärfolgen codiert. Der Algorithmus muss i. A. immer mathematisch definiert und formal auf seine Korrektheit überprüft werden. Hierzu werden häufig Beweise durch vollständige Induktion, Beweise durch Widerspruch oder aber im mathematischen Kontext Approximationen durch konvergente Cauchy-Folgen verwendet. Prof. Dr. Nikolaus Wulff Informatik I 21
Zusammenfassung Um einen Algorithmus zu entwickeln bedarf es zunächst einer Lösungsidee. Das Auffinden dieser Lösungsidee ist meist der schwierigste Teil der Arbeit und ein kreativer Akt. Sodann muss sichergestellt werden, dass diese Idee (mathematisch, formal) korrekt ist. Erst als letzter Schritt wird die Idee des Algorithmus mit Hilfe einer konkreten Programmiersprache implementiert, ausreichend getestet und auf Fehler untersucht. Prof. Dr. Nikolaus Wulff Informatik I 22