Algorithmen & Programmierung Aspekte von Algorithmen
Algorithmus (Wdh.) Aufgabe Beschreibung einer Abfolge von Schritten zur Lösung eines Problems in einer beliebigen Sprache Charakteristika eines Algorithmus Menge von Objekten, die durch den Algorithmus bearbeitet werden Menge von Operationen, die mit den Objekten ausgeführt werden und deren Zustand ändern können Grundoperationen Anfangszustand, in dem sich die Objekte vor Ablauf des Algorithmus befinden Vorbedingung Endzustand, in dem sich die Objekte nach der Abarbeitung des Algorithmus befinden Nachbedingung 124
Algorithmus (Wdh.) Steuerstrukturen Bestandteil jedes Algorithmus, steuern die Abfolge der Operationen Sequenz Selektion Iteration Prozess Durchführung einer Folge von Operationen des Algorithmus. Prozessor Durchführungseinheit eines Algorithmus 125
Algorithmen Fragen zu Algorithmen Notation und Ausdrucksmächtigkeit Berechenbarkeit Korrektheit 126
Notation & Ausdrucksmächtigkeit Beispiel Berechnung der Fakultät Mathematische Notation: 0! = 1 x! = x (x 1)! für x>0 Notation in C: int fakultaet(int x) { int erg = 1; while (x > 1) { erg = erg * x; x = x - 1; Frage Haben verschiedene Notationsformen die gleiche Ausdrucksmächtigkeit? } } return erg; Antwort Details in Lehrveranstaltungen zur Theoretischen Informatik 127
Berechenbarkeit Frage Ist alles programmier- bzw. berechenbar? Antwort Nein! Nichtentscheidbare Probleme Halteproblem Hält (terminiert) ein Programm auf einer gegebenen Eingabe oder läuft es unendlich? Bedeutung eines Algorithmus Berechnet ein Algorithmus die gewünschte Funktion? Berechnen zwei Algorithmen dieselbe Funktion? Details in Lehrveranstaltungen zur theoretischen Informatik 128
Korrektheit Wie kann man garantieren, dass Algorithmen und Programme die gewünschten Ergebnisse liefern? Beispiele für fatale und teure Programmfehler 1962 80 Millionen Dollar Schaden durch den Verlust der Venus-Sonde Mariner 1 wegen eines fehlenden Bindestrichs in einem Fortran-Programm 1982 Absturz eines Prototyps des F117-Kampfjets aufgrund der Vertauschung von Höhen- und Steuerruder bei der Programmierung 1996 370 Millionen US-Dollar Schaden aufgrund der notwendigen Sprengung des Prototyps einer Ariane 5-Rakete wegen einer Bereichsüberschreitung aufgrund eines Typumwandlungsfehlers 1999 Verlust der Mars-Sonde Climate Orbiter wegen der Verwechslung von Yard und Meter 2012 194 Millionen Euro Schaden durch Absturz des russischen Nachrichtensatelliten Express- AM4 aufgrund eines Programmierfehlers 2012 440 Millionen US-Dollar Schaden bzw. Aktienverlust innerhalb von 45 Minuten, verursacht durch einen Fehler in der Aktienhandelssoftware der Firma Knight Capital (Generierung fehlerhafter Handelsaufträge durch Kauf überteuerter Aktien) 129
Korrektheit Es werden zwei Arten von Korrektheit unterschieden: Partielle Korrektheit Ein Algorithmus ist partiell korrekt, wenn er für eine erfüllte Vorbedingung die spezifizierte Nachbedingung erreicht. Totale Korrektheit Ein Algorithmus ist total korrekt, wenn er partiell korrekt ist und terminiert. Bedeutung Ein partiell korrekter Algorithmus liefert das richtige Ergebnis, falls er jemals seine Berechnungen beendet. Ein total korrekter Algorithmus liefert das richtige Ergebnis nach endlicher Zeit. 130
Nachweis der Korrektheit Theoretischer Nachweis Es gibt formale Methoden zum Beweis der Korrektheit von Algorithmen, mit denen wir uns im Rahmen dieser Lehrveranstaltung nicht auseinandersetzen, z.b. Korrektheitskalküle Praktischer Nachweis? Ausführliche praktische Testläufe von Programmen sollten natürlich durchgeführt werden, insbesondere bei fehlendem theoretischen Korrektheitsbeweis, aber Merke: Testen kann ausschließlich die Existenz von Fehlern nachweisen, aber niemals die Abwesenheit von Fehlern! 131
Algorithmen Kennzeichen von Algorithmen Definiertheit Finitheit Ausführbarkeit Terminierung Allgemeinheit Determinismus und Determiniertheit Effizienz, Zeit- und Platzbedarf 132
Definiertheit Bedeutung Alle Schritte eines Algorithmus müssen eindeutig sein. Beispiel Zwei Algorithmen, um Millionär zu werden: Gehe ins Casino while (Gewinn < 1 000 000) Gewinne Geld beim Roulette Werde Kandidat bei Wer wird Millionär while (Gewinn < 1 000 000) Beantworte aktuelle Frage richtig Der jeweils letzte Schritt ist nicht definiert und unter den jeweiligen Umständen auch nicht definierbar. 133
Finitheit Beschreibungsformen von Algorithmen Wir haben in der ersten Vorlesung gesehen, dass Algorithmen auf verschiedene Weise beschrieben werden können, z.b. visuell, (natürlich)sprachlich, mathematisch, symbolisch.... Aber Jede dieser Beschreibungsformen muss endlich sein, d.h. sie darf nur eine maximale Menge an Platz, Papier, Größe, Datenspeicher etc. benötigen. Statische Finitheit Die Beschreibung einer Folge von Operationen muss endlich sein. 134
Finitheit Dynamische Finitheit Ein Algorithmus darf nur eine endliche und in der Praxis meist zusätzlich beschränkte Menge von Ressourcen benutzen: Ressourcenbeschränkung bzgl. Platz Die bei der Abarbeitung eines Algorithmus entstehenden Zwischenergebnisse müssen nicht nur endlich sein, sondern dürfen maximal die zur Verfügung stehenden Ressourcen nutzen. Ressourcenbeschränkung bzgl. Ausführungsdauer Ein Algorithmus muss seine Aufgabe nicht nur in endlicher, sondern auch in angemessener Zeit lösen. 135
Dynamische Finitheit - Beispiel Algorithmus zum Gewinn einer Million Euro Gehe ins Casino; Wähle einen beliebigen Betrag B; Einsatz = B; while (Gewinn < 1 000 000) { Setze Einsatz auf Farbe Rot if (Rot gewinnt) { Gewinn = Gewinn + Einsatz; Einsatz = B; } else { Gewinn = Gewinn Einsatz; Einsatz = Einsatz * 2; } } Ergebnis Typischer Roulettetisch Wenn man (1 000 000 / B) mal gewonnen hat, ist man Millionär. Problem Dynamische Finitheit bzgl. des maximal notwendigen Einsatzes UND des maximal möglichen Einsatzes 136
Ausführbarkeit Bedeutung Jeder Teil eines Algorithmus sollte entweder direkt oder mit Hilfe eines anderen Algorithmus ausführbar sein. Beispiel Algorithmus zur Zerlegung einer ganzen Zahl in die Summe zweier Primzahlen: Die Goldbachsche Vermutung besagt, dass sich eine gerade Zahl > 3 immer in die Summe zweier Primzahlen zerlegen lässt. Bis heute ist diese Vermutung nicht bewiesen, aber auch nicht widerlegt worden. Deshalb weiß niemand, ob der letzte else- Zweig ausführbar ist oder nicht. Lies eine ungerade ganze Zahl x>3 ein x1 = 2; x2 = 2; while ( x > x1 + x2 ) { while ( x1 + x2 < x ) x2 = Primzahlnachfolger(x2); if ( x1 + x2!= x ) { x1 = Primzahlnachfolger(x1); x2 = 2; } } if ( x == x1 + x2 ) Ausgabe("Zerlegung gefunden"); else Hole Fields-Medaille; 137
Terminierung Terminierende Algorithmen Terminierend sind die Algorithmen, die für jeden Anfangszustand (Eingabe) nach endlich vielen Schritten ein Resultat liefern und anhalten (terminieren). Nichtterminierende Algorithmen Nichtterminierende Algorithmen verursachen Prozesse, die ununterbrochen laufen. Nichtterminierung kann gewünscht sein, aber auch aus Programmfehlern oder nichtberücksichtigten Zuständen bearbeiteter Objekte resultieren. Produziert ein nichtterminierender Algorithmus Ausgaben, weiß man nicht, ob und wann die Ausgabe vollständig bzw. gültig ist. Möglicherweise können sich auch nichtterminierende Algorithmen als terminierend erweisen (z.b. wenn sie ein ungelöstes mathematisches Problem lösen, falls es lösbar ist) Bei nichtterminierenden Algorithmen ist nicht klar, ob sie nur noch länger rechnen müssen (um das Ergebnis zu bestimmen) oder ob es tatsächlich keine Lösung gibt. 138
Allgemeinheit Bedeutung Eine ganze Klasse von Problemen wird gelöst, d.h. nicht nur ein Problem. Spezifikation eines konkreten Problems Die Wahl eines einzelnen aktuell zu lösenden Problems aus dieser Klasse erfolgt über Parameter (Eingabedaten) Eingabedaten Algorithmus Ausgabedaten Algorithmus als Funktion Ausgabe = f(eingabe) 139
Determinismus Bedeutung Ein Algorithmus ist deterministisch, wenn unter den gleichen Voraussetzungen auf eine Anweisung immer die gleiche Anweisung folgt. Damit ist zu jedem Zeitpunkt der nachfolgende Abarbeitungsschritt eines Algorithmus eindeutig festgelegt. Nichtdeterministischer (randomisierter) Algorithmus Bezeichnet einen Algorithmus, in dem nichtreproduzierbare Zustände auftreten können. Der Zufall entscheidet über die durchzuführenden Anweisung (z.b. bei einer Selektion). Bedeutung nichtdeterministischer Algorithmen Randomisierte Algorithmen bilden eine wichtige Algorithmenklasse. Sie sind oft schneller als deterministische Algorithmen Details in der theoretischen Informatik. 140
Determiniertheit Bedeutung Ein Algorithmus ist determiniert, wenn er für die gleichen Eingabewerte und Startbedingungen immer das gleiche Ergebnis liefert. Diese Sicht korrespondiert zur Funktionsanalogie eines Algorithmus. Ein determinierter Algorithmus liefert für die gleiche Eingabe immer die gleiche Ausgabe. Determinismus vs. Determiniertheit Ein terminierender deterministischer Algorithmus ist immer determiniert. Aber: Ein determinierter Algorithmus muss nicht deterministisch sein, d.h. obwohl die gleiche Eingabe die gleiche Ausgabe bewirkt, können sich die Zwischenergebnisse eines nichtdeterministischen determinierten Algorithmus unterscheiden (was bei einem deterministischen Algorithmus nicht möglich wäre). 141
Effizienz, Zeit- und Platzbedarf Effizienz Zu jedem Algorithmus gibt es unendlich viele verschiedene Varianten, die die gleiche Aufgabe lösen. Wir suchen nach einer möglichst guten Variante hinsichtlich des Zeitbedarfs. Die Dauer der Ausführung wird als Gütekriterium eines Algorithmus angesehen. Abschätzung des Rechenaufwands eines Algorithmus erfolgt unabhängig von der konkreten Hardwareleistung in Abhängigkeit von der Problemgröße für den Idealfall (best case), den schlechtesten Fall (worst case) und im Mittel (average case). Platzbedarf Ein weiteres wichtiges Gütekriterium eines Algorithmus ist der Bedarf an Speicherplatz. 142
Test der Kennzeichen Beispiel - Euklidischer Algorithmus für a,b N 1. Falls a = b gilt: Brich die Berechnung ab; es gilt ggt = a. 2. Falls a > b gilt: Ersetze a durch a b und gehe zu Schritt 1 3. Es gilt a < b: Ersetze b durch b a und gehe zu Schritt 1 Test auf Allgemeinheit [ ] Terminierung [ ] statische Finitheit [ ] dynamische Finitheit [ ] Determinismus [ ] Determiniertheit [ ] Effizienz [ ] Ausführbarkeit [ ] 143
Test der Kennzeichen Beispiel - Euklidischer Algorithmus (a,b N) 1. Falls a = b gilt: Brich die Berechnung ab; es gilt ggt = a. 2. Falls a > b gilt: Ersetze a durch a b und gehe zu Schritt 1 3. Es gilt a < b: Ersetze b durch b a und gehe zu Schritt 1 Test auf Allgemeinheit und Ausführbarkeit Allgemeinheit ist gegeben, da dieser Algorithmus den größten gemeinsamen Teiler für alle natürlichen Zahlen berechnen kann (und nicht nur für eine bestimmte Zahl). Ausführbarkeit ist auch erfüllt, da es nur Vergleichsoperationen und Subtraktionsoperationen natürlicher Zahlen gibt, bei denen immer die kleinere von der größeren abgezogen wird (womit wir immer im Bereich der natürlichen Zahlen bleiben). 144
Test der Kennzeichen Beispiel - Euklidischer Algorithmus (a,b N) 1. Falls a = b gilt: Brich die Berechnung ab; es gilt ggt = a. 2. Falls a > b gilt: Ersetze a durch a b und gehe zu Schritt 1 3. Es gilt a < b: Ersetze b durch b a und gehe zu Schritt 1 Test auf Terminierung Im Allgemeinen kann diese Frage nicht beantwortet werden (Halteproblem), aber in diesem konkreten Fall können wir die Terminierung beweisen. 145
Test der Kennzeichen Beispiel - Euklidischer Algorithmus (a,b N) 1. Falls a = b gilt: Brich die Berechnung ab; es gilt ggt = a. 2. Falls a > b gilt: Ersetze a durch a b und gehe zu Schritt 1 3. Es gilt a < b: Ersetze b durch b a und gehe zu Schritt 1 Test auf statische und dynamische Finitheit Statische Finitheit ist erfüllt, da eine endliche Beschreibung des Algorithmus vorliegt. Dynamische Finitheit ist ebenfalls erfüllt, da für die Verarbeitung nur endlich viel Platz benötigt wird (für a und b). 146
Test der Kennzeichen Beispiel - Euklidischer Algorithmus (a,b N) 1. Falls a = b gilt: Brich die Berechnung ab; es gilt ggt = a. 2. Falls a > b gilt: Ersetze a durch a b und gehe zu Schritt 1 3. Es gilt a < b: Ersetze b durch b a und gehe zu Schritt 1 Test auf Determinismus und Determiniertheit Der Algorithmus ist deterministisch, da zu jedem Ausführungszeitpunkt nur eine Fortsetzungsmöglichkeit existiert. Der Algorithmus ist determiniert, da terminierende deterministische Algorithmen immer determiniert sind und somit das gleiche Ergebnis (für gleiche Eingabedaten) liefert. 147
Test der Kennzeichen Beispiel - Euklidischer Algorithmus (a,b N) 1. Falls a = b gilt: Brich die Berechnung ab; es gilt ggt = a. 2. Falls a > b gilt: Ersetze a durch a b und gehe zu Schritt 1 3. Es gilt a < b: Ersetze b durch b a und gehe zu Schritt 1 Test auf Effizienz Wir können zu diesem Zeitpunkt noch keine formalen Aussagen zur Effizienz treffen. Intuitiv scheint der Algorithmus von Euklid effizient zu sein. Ein anderes Verfahren zur Bestimmung des größten gemeinsamen Teilers wäre die Primfaktorzerlegung, das jedoch weniger effizient zu sein scheint. Allerdings könnten auch noch effizientere Verfahren existieren. 148
Kennzeichen unserer Algorithmen Wir wollen uns im Rahmen dieser Lehrveranstaltung mit Algorithmen beschäftigen, die sequentiell allgemein statisch finit ( benötigt ggf. Approximationen) dynamisch finit ( benötigt ggf. Approximationen) determiniert ausführbar möglichst effizient (auf Effizienz liegt kein Fokus, sie schadet aber auch nicht) meistens terminiert meistens deterministisch sind. 149
Algorithmenmodelle Funktionsmodell Wir haben bereits Ausgabedaten als Funktion der Eingabedaten betrachtet: Ausgabe = f(eingabe) Eingabedaten Algorithmus Ausgabedaten Konsequenz Die Eingabedaten sind unabhängig von den Ausgabedaten. Alternativer Ansatz Zwischen Ein- und Ausgabedaten wird nicht unterschieden, es werden lediglich Daten durch einen Algorithmus bearbeitet. Die Daten besitzen zu jedem Abarbeitungszeitpunkt einen be- stimmten Zustand. Die Bearbeitung der Daten durch den Algorithmus führt eine Zustandsänderung der Daten herbei. Algorithmus Daten 150
Zustandsmodell Zustandsänderung Die Werte der Daten können als Zeitreihe dt1, dt2,... angesehen werden. Ein einzelner Schritt s des Algorithmus kann dann wieder als Funktion verstanden werden: Vereinfachung dt+1 = st(dt) Zur Vereinfachung der Darstellung können die Zeitindizes weggelassen werden: d st(d) Die rechte Seite drückt hierbei den alten Zustand von d aus und die linke Seite den neuen Zustand, der Folgezustand ist damit eine Funktion des Vorzustandes. Realisierung in C Wir kennen bereits die Zuweisungsoperation und können die Zustands- änderung für eine Variable x wie folgt ausdrücken: x = f(x) while (i > 0) { y = y * x; i = i - 1; } 151
Konditionalmodell Bedeutung Ein Algorithmus besteht ausschließlich aus einer Menge von Wenn-Dann-Regeln (Konditionalklauseln) Wenn A gilt, dann geschehe X Wenn B gilt, dann geschehe Y Wenn C gilt, dann geschehe Z... Reihenfolge der Regeln Die Reihenfolge der Regeldefinition ist normalerweise nicht von Bedeutung. Bedingung Die Bedingung einer Konditionalklausel kann sowohl von einer Eingabe als auch einem Zustand abhängen, d.h. dass sie sowohl mit dem Funktions- als auch dem Zustandsmodell kompatibel ist. 152
Vergleich der Modelle Formulierung eines Algorithmus Konditionalmodell, Funktionsmodell und Zustandsmodell sind gleichmächtig. Praxisrelevanz Die meisten Programmiersprachen nutzen in der Regel alle drei Modelle, aber in jeweils individueller Ausprägung. Kriterien für Verwendung Möglichkeiten der Programmiersprache Art des Problems: Manche Probleme lassen sich in einem bestimmten Modell besser ausdrücken als in einem anderen. Persönliche Vorlieben des Programmierers 153
Ende der Vorlesung