Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
Algorithmen und ihre Eigenschaften
Klaus Becker 2018
2
Algorithmen und ihre Eigenschaften
3
Teil 1 Fallstudie - PageRank
4
Internetrecherche Wenn man im Internet nach Information sucht, dann benutzt man sehr häufig eine Suchmaschine. Hier gibt man den Suchbegriff (oder mehrere Suchbegriffe) ein, die Suchmaschine liefert dann die Adressen von Webseiten zu diesem Suchbegriff.
5
Das Ranking-Problem Die hier benutzte Suchmaschine Google hat mehr als 40 Millionen Suchergebnisse zum Suchbegriff „Informatik“ gefunden. Die ersten 10 dieser Suchergebnisse werden mit einer Kurzbeschreibung angezeigt. Die Suchmaschine Google liefert also zunächst nur eine Auswahl von Webseiten zum eingegebenen Suchbegriff. Hier ergibt sich das folgende Problem: Ranking-Problem: Wie können / sollen Suchergebnisse (Webseiten zu einem Suchbegriff) sinnvoll der Reihe nach angeordnet werden?
6
Die Relevanz von Webseiten
Es gibt unterschiedliche Ansätze, die Relevanz von Webseiten zu bestimmen. Bewerte diese Ansätze (Vorteile / Nachteile). Seiteninhalt: Man könnte untersuchen, welche Schlüsselwörter im Header genannt werden. Man könnte auch untersuchen, wo und wie oft die Suchbegriffe im Text vorkommen. Domainname: Ein Domainname wie deutet darauf hin, dass es auf dieser Webseite um die (deutsche Bundes-) Bahn geht. Aktualität: Man könnte die Aktualität der Webseite berücksichtigen: Wann ist sie zuletzt aktualisiert worden? Zugriffszahlen, Verweildauer: Man könnte die Anzahl der Zugriffe auf die Webseite und die Verweildauer ermitteln. Verlinkung: Man könnte die Anzahl der Links zählen, die auf eine Webseite verweisen.
7
WWW als Hypermedia-System
Informationen sind im WWW in Dokumenten (mit Texten, Bildern, Audio-Sequenzen, Video-Clips, Animationen) dargestellt, die mit Hilfe von Verweisen miteinander verknüpft sind. Ein solches System vernetzter Dokumente nennt man Hypertext-System oder besser Hypermedia-System. Welche Seite hat eine hohe Relevanz? Wie könnte man das an der Verlinkung erkennen?
8
Verlinkung als Lösungsansatz
„PageRank verlässt sich auf die einzigartige demokratische Natur des World Wide Webs, indem es die weitverzweigte Link-Struktur als einen Indikator für die individuelle Einschätzung der Qualität einer Seite nimmt. Der Kern ist dabei, dass Google einen Link von Seite A zu Seite B als ein "Votum" von Seite A für Seite B interpretiert.“ (Google, Erklärungen zu PageRang, Quelle:
9
Vereinfachte Webseitenwelt
Ziel ist es, eine Webseite danach zu bewerten, wie viele andere auf sie verlinken und wie stark verlinkt diese anderen Seiten wiederum sind. Links von Webseiten, auf die selbst viele Links verweisen, werden dabei stärker berücksichtigt als Links, die ihren Ursprung auf Webseiten haben, auf die nur wenige oder gar keine Links verweisen. Vereinfachte Webseitenwelt
10
Ein Simulationsverfahren
Brin, Page: “PageRank can be thought of as a model of user behavior. We assume there is a "random surfer" who is given a web page at random and keeps clicking on links, never hitting "back" but eventually gets bored and starts on another random page. The probability that the random surfer visits a page is its PageRank.” (vgl.
11
Ein erstes Surfmodell C D A B
Wir gehen von folgenden vereinfachenden Annahmen aus: (A1) Zu Beginn verteilen sich alle Besucher gleichmäßig auf die Webseiten. (A2) Alle Besucher ("Surfer") folgen jeweils im gleichen Takt einem Link auf eine weitere Webseite. Wenn auf einer Webseite mehrere Links vorkommen, dann verteilen sich die Besucher gleichmäßig auf die verschiedenen Links. Aufgabe: Ergänze die Tabelle. D A B A B C D 300 300 150 150
12
Modellkritik Wir gehen von folgenden vereinfachenden Annahmen aus: (A1) Zu Beginn verteilen sich alle Besucher gleichmäßig auf die Webseiten. (A2) Alle Besucher ("Surfer") folgen jeweils im gleichen Takt einem Link auf eine weitere Webseite. Wenn auf einer Webseite mehrere Links vorkommen, dann verteilen sich die Besucher gleichmäßig auf die verschiedenen Links. Aufgabe: Welche Schwierigkeiten ergeben sich bei den Webseiten E und F? F C D A E B
13
Ein verbessertes Surfmodell
Wir gehen von folgenden vereinfachenden Annahmen aus: (A1) … (A2) … (A3) Besucher, die in eine Sackgasse geraten (d.h. Webseiten besuchen, die keine Links auf weitere Seiten enthalten), besuchen im nächsten Schritt irgend eine der gegebenen Webseiten. Wir nennen sie ab jetzt "Sackgassenjumper". Sie teilen sich dabei gleichmäßig auf alle zur Verfügung stehenden Webseiten auf. Aufgabe: Ergänze in der Tabelle die nächste Zeile. F C D A E B A B C D E F 300 300
14
Modellkritik Wir haben ein Modell entwickelt, um das Surfverhalten von Nutzern im Internet zu beschreiben. Modelle vereinfachen dabei sehr häufig die zu beschreibende Realität. Aufgabe: (a) Mache dir klar, welche Vereinfachungen bei der Beschreibung des realen Surfverhaltens von Nutzern getroffen wurden. (b) Sind diese Vereinfachungen akzeptabel? F C D A E B
15
Ein weiter verfeinertes Surfmodell
Wir gehen von folgenden vereinfachenden Annahmen aus: (A1) … (A2) … (A3) … (A4) Ein bestimmter Prozentsatz der Nutzer (z.B. 20%) springt in jedem Takt zu einer beliebigen Webseite. Sie teilen sich dabei gleichmäßig auf alle zur Verfügung stehenden Webseiten auf. Aufgabe: Ergänze in der Tabelle die nächste Zeile. F C D A E A B C D E F 300 300 180 460 246.5 254.5 619.8 340.9 91.8 246.5 B
16
Modellkritik Wir haben ein Modell entwickelt, um das Surfverhalten von Nutzern im Internet zu beschreiben. Modelle vereinfachen dabei sehr häufig die zu beschreibende Realität. Aufgabe: (a) Mache dir klar, welche Vereinfachungen bei der Beschreibung des realen Surfverhaltens von Nutzern getroffen wurden. (b) Sind diese Vereinfachungen akzeptabel? F C D A E B
17
Automatisierung der Berechnungen
Wir gehen von folgenden vereinfachenden Annahmen aus: (A1) Zu Beginn wird jede Webseite von einer bestimmten Anzahl von Nutzern besucht. Wir bezeichnen die Anzahlen mit a, b, c, d, e und f (im Beispiel: 300). (A2) … (A3) … (A4) … F C D A a = 300 b = 300 c = 300 d = 300 e = 300 f = 300 a_neu = (0.8*c)/ (0.2*(a+b+c+d+e+f))/6 + (0.8*f)/6 ... E B
18
Automatisierung der Berechnungen
... a_neu = (0.8*c)/ (0.2*(a+b+c+d+e+f))/6 + (0.8*f)/6 b_neu = c_neu = d_neu = e_neu = f_neu = F C D A E B Aufgabe: Entwickle die fehlenden Berechnungsformeln.
19
Implementierung a = 300 Aufgabe: b = 300
c = 300 d = 300 e = 300 f = 300 a_neu = (0.8*c)/ (0.2*(a+b+c+d+e+f))/6 + (0.8*f)/6 ... Aufgabe: Implementiere die Berechnungen mit einer Tabellenkalkulation.
20
Implementierung a = 300 Aufgabe: b = 300
c = 300 d = 300 e = 300 f = 300 a_neu = (0.8*c)/ (0.2*(a+b+c+d+e+f))/6 + (0.8*f)/6 ... Aufgabe: Implementiere die Berechnungen mit Hilfe von Python. def erzeugeRankingwerte(): … return … >>> erzeugeRankingwerte() ( , , , , , )
21
Ranking-Algorithmus Die Relevanz von Webseiten lässt sich mit dem folgenden Simulationsverfahren bestimmen, bei dem das Surfverhalten einer vorgegebenen Anzahl von Webseitenbesuchern nach einfachen Regeln durchgespielt wird. ALGORITHMUS erzeugeRankingwerte: Lege den Surf- und Sprunganteil fest. Lege die Ausgangsbesucherzahlen fest. Lege die Anzahl der Simulationsschritte fest. Setze einen Zähler auf 0. SOLANGE der Zähler kleiner als die Anzahl der Simulationsschritte ist: Berechne die neuen Besucherzahlen. Erhöhe den Zähler um 1. Gib die Besucherzahlen als Anteile zurück.
22
Ranking-Algorithmus Das informell beschriebene Verfahren lässt sich jetzt wie folgt präzisieren: ALGORITHMUS erzeugeRankingwerte: Lege den Surf- und Sprunganteil fest. Lege die Ausgangsbesucherzahlen fest. Lege die Anzahl der Simulationsschritte fest. Setze einen Zähler auf 0. SOLANGE der Zähler kleiner als die Anzahl der Simulationsschritte ist: Berechne die neuen Besucherzahlen. Erhöhe den Zähler um 1. Gib die Besucherzahlen als Anteile zurück.
23
Verallgemeinerung Aufgabe:
Simuliere das Surfverhalten in der folgenden Webseitenwelt. Benutze dieselben Annahmen wie bisher.
24
PageRank Viele Menschen nutzen das Internet (genauer: WWW), wenn sie Information über ein bestimmtes Thema suchen. Meist geben sie ein oder mehrere Stichwörter in eine Suchmaschine ein - und schon kann es mit der Informationsaufnahme losgehen. Suchmaschinen finden oft eine riesige Anzahl von Webseiten, die die eingegebenen Suchbegriffe enthalten. Suchmaschinen nutzen dann eingebaute Strategien, um diese Webseiten dem Nutzer zu präsentieren. Mit Hilfe vorgegebener Algorithmen - zu denen auch das hier entwickelte Verfahren gehört - werden die Webseiten mit Rankingzahlen bewertet und dann entsprechend dieser Rankingwerte nach ihrer Relevanz sortiert angezeigt. Das ist sicher sinnvoll, hat aber auch Konsequenzen. Viele Nutzer schauen sich die ersten Suchergebnisse genauer an, die weiteren - so glaubt man - werden wohl nicht viel Neues bringen. Das hat zur Folge, dass viele Nutzer nur das finden, was von eingebauten Ranking-Algorithmen für besonders relevant befunden wurde. Ranking-Algorithmen steuern auf diese Weise die Informationsaufnahme der Nutzer.
25
Entwicklung der Google-Suche
Vor Google: Suchmaschinen überprüfen, wie oft der gesuchte Begriff auf einer Webseite auftaucht. 1997: Larry Page und Sergey Brin, zwei Studenten der Stanford University, melden eine Software zum Patent an. Idee: Brin und Page gingen davon aus, dass relevante Inhalte im Netz von Betreibern anderer Seiten öfter erwähnt und damit auch verlinkt würden als Seiten, die qualitativ minderwertig sind. Die Rangfolge in den Ergebnissen einer Suchanfrage wurde durch den User bestimmt. Jetzt zählte die Meinung der Menschen im Internet darüber, was denn nun qualitativ hochwertige und lohnende Beiträge zu einem bestimmten Thema seien. Heute: Verfahren, mit dem Google das Ranking bestimmt, ist geheim. Das Ranking wird von mehr als 200 „Signalen“ festgelegt (Suchbegriff im Domainnamen, Worthäufigkeit auf der seite, Aktualität der seite, Sprachniveau der seite, Links von sozialen Netzwerken auf die Seite, …). Quelle:
26
PageRank "Die perfekte Suchmaschine versteht genau das, was man meint, und liefert genau das, wonach man sucht.« Das war die Vision von Larry Page, als er Google im Jahre 1998 mitgründete. Seither arbeiten die Kalifornier daran, diesem Ziel näher zu kommen. Vor drei Jahren ist ihnen ein großer Schritt gelungen. Tippten bis dahin zwei Nutzer die gleichen Wörter in Googles Suchmaske, bekamen diese dieselbe Antwort. Heute bekommt jeder Suchende eine individuell auf ihn zugeschnittene Reaktion des Computers. Doch so beginnt sich die Welt des Suchenden auf die beschauliche Sammlung seiner Vorlieben zu verengen. Aus dem Tor ins World Wide Web wird ein Tor, das letztlich zu ihm selbst zurückführt. In seinem Buch Filter Bubble kritisiert der Netzpublizist Eli Pariser, dass man sich im Internet in vorgefilterten Blasen bewege: »Mehr und mehr wird dein Computermonitor zum Spiegel, der deine eigenen Interessen reflektiert, während algorithmische Aufseher beobachten, was du anklickst!«" Quelle:
27
Bedeutung von Algorithmen
Quelle:
28
Perspektiven informatischer Bildung
Aufbau und Funktionsweise von Informatiksystemen erklären Wechselwirkungen Informatiksystem- Mensch-Gesellschaft reflektieren Informatiksysteme systematisch entwickeln mit Informatiksystemen interagieren, Informatiksysteme vielfältig nutzen Quellen:
29
Fallstudie - Ägyptische Multiplikation
Teil 2 Fallstudie - Ägyptische Multiplikation
30
Papyrus Rhind Algorithmen werden seit den Anfängen der Mathematik beim Rechnen benutzt. Im "Papyrus Rhind" wird beschrieben, wie in Ägypten Zahlen multipliziert wurden. Im Jahre 1858 kaufte der englische Archäologe A.H. Rhind in Luxor ein aus zwei Stücken bestehendes Papyrus. Erst einige Jahrzehnte später stellte sich heraus, dass das dritte, fehlende Mittelstück sich in einem New Yorker Museum befand. Zusammen hat das Dokument eine Länge von 5,25 m und eine Breite von 33 cm. Es wurde rund 1700 Jahre vor Christi Geburt geschrieben und enthält viele Mathematikaufgaben. Heute heißt dieses Schriftstück Papyrus Rhind. siehe:
31
Rechnen mit Hieroglyphenzahlen
Aufgaben: (a) Versuche, anhand der Beispiele zu erschließen, wie Zahlen im alten Ägypten dargestellt wurden. (b) Welche Gemeinsamkeiten und welche Unterschiede gibt es zu unserer Zahldarstellung heute? (c) Hieroglyphenzahlen lassen sich gut schriftlich addieren und subtrahieren. Beschreibe, wie man dabei vorgehen kann. (d) Warum kann man unsere schriftliche Multiplikation nicht mit Hieroglyphenzahlen nachbilden? (e) Recht gut funktioniert das Verdoppeln und Halbieren von Hieroglyphenzahlen. Probiere das selbst aus.
32
Ägyptische Multiplikation
13 12 6 24 3 48 1 96 156 Aufgabe: Welche Rechnung ist hier dargestellt? Übersetze hierzu die Zahldarstellungen in unsere gewohnte Dezimaldarstellung.
33
Ägyptische Multiplikation
Aufgaben: Finde heraus, wie die ägyptische Multiplikation funktioniert. Berechne mit dem Verfahren die folgenden Produkte: 16 * 7 = 9 * 120 = 15 * 14 = Überprüfe auch, ob die erzielten Ergebnisse stimmen.
34
Fachlicher Hintergrund
12 + 24 48 96 156 Aufgabe: Warum liefert das Multiplikationsverfahren korrekte Ergebnisse? Verdeutliche das auch am folgenden Beispiel.
35
Beschreibung des Verfahrens
Aufgabe: Schreibe eine Anleitung, nach der jemand zwei Zahlen mit dem Verfahren der Ägypter multiplizieren soll.
36
Beschreibung des Verfahrens
Schreibe die beiden zu multiplizierenden Zahlen nebeneinander. Halbiere die Zahlen auf der linken Seite, bis man zur 1 gelangt. Verdopple die Zahlen auf der rechten Seite. Streiche die rechts stehenden Zahlen, wenn die links stehende Zahl gerade ist. Bilde die Summe der nicht gestrichenen rechts stehenden Zahlen. umgangssprachliche Beschreibung Problem: Ist die Beschreibung so, dass eine Person das Verfahren schematisch abarbeiten kann?
37
Beschreibung des Verfahrens
Schreibe die beiden zu multiplizierenden Zahlen nebeneinander. Halbiere die Zahlen auf der linken Seite, bis man zur 1 gelangt. Verdopple die Zahlen auf der rechten Seite. Streiche die rechts stehenden Zahlen, wenn die links stehende Zahl gerade ist. Bilde die Summe der nicht gestrichenen rechts stehenden Zahlen. 3 halbieren? 12 13 6 3 Schwierigkeit: Ist jeweils klar, wie die einzelnen Anweisungen ausgeführt werden?
38
Beschreibung des Verfahrens
Schreibe die beiden zu multiplizierenden Zahlen nebeneinander. Halbiere die Zahlen auf der linken Seite, bis man zur 1 gelangt. Verdopple die Zahlen auf der rechten Seite. Streiche die rechts stehenden Zahlen, wenn die links stehende Zahl gerade ist. Bilde die Summe der nicht gestrichenen rechts stehenden Zahlen. Immer weiter verdoppeln? 12 13 6 26 3 52 1 104 208 … Schwierigkeit: Ist nach jedem Schritt klar, wie es weitergeht?
39
Beschreibung des Verfahrens
Schreibe die beiden zu multiplizierenden Zahlen nebeneinander. Wenn die linke Zahl größer als 1 ist, dann halbiere sie und verdopple die rechte Zahl und schreibe die beiden neuen Zahlen unter die vorangehenden Zahlen. ... Wenn die linke Zahl gleich 1 ist, dann streiche alle rechts stehenden Zahlen, sofern die links stehende Zahl gerade ist. Bilde die Summe der nicht gestrichenen rechts stehenden Zahlen. Die Beschreibung ist ja unendlich lang! 12 13 6 26 3 52 1 104 Schwierigkeit: Eine Beschreibung muss endlich sein! 156
40
Beschreibung des Verfahrens
Bei den Zahlen 12 und 13 geht das so: Halbiere 12 und verdopple 13 und schreibe die sich ergebenden Zahlen 6 und 26 unter die Ausgangszahlen. Halbiere jetzt 6 und verdopple 26 und schreibe die sich ergebenden Zahlen 3 und 52 unter die Ausgangszahlen. … Und wie geht das bei 14 und 15? 12 13 6 26 3 52 1 104 156 Schwierigkeit: Eine Beschreibung muss den allgemeinen Fall erfassen!
41
Fachkonzept - Algorithmus
Ein Algorithmus ist eine Verarbeitungsvorschrift, die so präzise formuliert ist, dass sie auch von einer Maschine abgearbeitet werden kann. Kriterien: Ausführbarkeit, d. h. der ausführende Prozessor muss die Einzelschritte abarbeiten können Eindeutigkeit, d. h. die Abfolge der Schritte ist eindeutig festgelegt Endlichkeit, d. h. seine Beschreibung besteht aus einem Text endlicher Länge Allgemeinheit, d. h. es wird eine ganze Klasse von Problemen gelöst
42
Anforderungen an Algorithmen
Ausführbarkeit bedeutet, dass der "Prozessor" (Maschine, Person oder auch gedachte Einheit, die den Algorithmus ausführen soll) jeden Einzelschritt des Algorithmus ausführen kann. Beachte, dass die Ausführbarkeit eines Algorithmus immer von den Möglichkeiten des "Prozessors" abhängt. Eindeutigkeit bedeutet, dass die Abfolge der einzelnen Schritte genau festgelegt ist. Bei der Abarbeitung der Anweisungen eines Algorithmus muss also immer genau feststehen, wie es weitergeht. Hieraus ergibt sich, dass ein Algorithmus bei denselben Ausgangsdaten immer zum selben Ergebnis kommt. Beachte, dass wir im Rahmen der theoretischen Informatik auch eine Form der Mehrdeutigkeit bei Algorithmen zulassen. Endlichkeit bedeutet, dass die Beschreibung aus einem Text endlicher Länge besteht. Die Endlichkeit der Darstellung ist eigentlich eine Selbstverständlichkeit, da eine unendlich lange Beschreibung in der Praxis nicht vorkommen kann. Allgemeinheit bedeutet, dass nicht nur ein singuläres Problem, sondern eine ganze Klasse von Problemen gelöst werden soll. Die Forderung nach der Allgemeinheit der Problemstellung lässt man natürlich fallen, wenn man nur an der Lösung eines Einzelfalls interessiert ist.
43
Multiplikationsalgorithmus
12 + 24 48 96 156 60 13*12 = 13* = 6* = 3* = 1* = 0* = 156
44
Multiplikationsalgorithmus
Beachte: Die Beschreibung in Struktogrammform verwendet „Bausteine“ (wie Variablen, Kontrollstrukturen …), die in der Informatik zur automatisierten Verarbeitung von Daten benutzt werden. Algorithmus in Struktogrammform
45
Bausteine von Algorithmen
Eine Elementaranweisung beschreibt eine Basisaktion des betrachteten Prozessors. S E Eingabe: zahl1 Eingabeanweisung E Eingabe: zahl2 E produkt = 0 Wertzuweisung W S F S E produkt = produkt + zahl2 S E zahl1 = zahl1 / 2 E zahl2 = zahl2 * 2 E Ausgabe: produkt Ausgabeanweisung
46
Bausteine von Algorithmen
Sequenzbildung Kontrollstrukturen dienen dazu, den Ablauf der Ausführungsschritte festzulegen. Wichtige Kontrollstrukturen sind die Fallunterscheidung, die Wiederholung sowie die Sequenzbildung (Hintereinanderreihung). S E Eingabe: zahl1 E Eingabe: zahl2 E produkt = 0 W Wiederholung S Fallunterscheidung F S E produkt = produkt + zahl2 S E zahl1 = zahl1 / 2 E zahl2 = zahl2 * 2 E Ausgabe: produkt
47
Implementierung Aufgabe:
Entwickle eine Python-Funktion zum Algorithmus. Teste ob die Funktion korrekt arbeitet. def multiplikation(zahl1, zahl2): … return … >>> multiplikation(13, 12) … >>> …
48
Implementierung Aufgabe:
Kann man mit dem ägyptischen Multiplikationsverfahren auch folgende Produkte bestimmen? Probiere es aus. 3*0 = …; 0*5 = …; 6*(-3) = …; (-3)*7= …; 10*0.5 = …; 0.5*10 = …
49
Darstellung von Algorithmen
Algorithmen lassen sich auf unterschiedliche Weise darstellen: Schreibe die beiden zu multiplizierenden Zahlen nebeneinander. Halbiere die Zahlen auf der linken Seite, bis man zur 1 gelangt. Verdopple die Zahlen auf der rechten Seite. Streiche die rechts stehenden Zahlen, wenn die links stehende Zahl gerade ist. Bilde die Summe der nicht gestrichenen rechts stehenden Zahlen. umgangssprachlich Struktogramm def multiplikation(zahl1, zahl2): … return … Programm
50
Algorithmische Verfahren
Das Rechnen mit Zahlen ist eine bedeutende Kulturleistung der Menschheit, die gewaltige Auswirkungen hat. Viele Bereiche unseres Lebens wären kaum noch oder gar nicht denkbar, wenn sie nicht von Zahlen und Berechnungen mit diesen Zahlen begleitet wären. Schon sehr früh hat man versucht, das Rechnen mit Zahlen zu automatisieren. So sind z.B. unsere Verfahren zum schriftlichen Rechnen Verfahren, die man schematisch durchführen kann, ohne sie im geringsten Maße verstanden zu haben. Diese Form der Automatisierung ermöglicht es, sehr viele Berechnungen ohne Nachdenken schnell auszuführen. Algorithmen wurden also schon entwickelt und benutzt, lange bevor es Computer gab. Zu diesen algorithmischen Verfahren gehört auch das von den Ägyptern benutzte Verfahren zur Multiplikation von Zahlen. Ohne algorithmische Rechenverfahren wäre es den Ägyptern wohl kaum möglich gewesen, eine funktionierende Gesellschaft aufzubauen, die sogar in der Lage war, riesige Pyramiden zu bauen.
51
Bedienungs-anleitung
Algorithmen im Alltag ZUTATEN für 5 Portionen: 650g Erdbeeren 150g Zucker 2 Pk Vanillezucker 5 EL Weinbrand 400 ml Sahne (gut gekühlt) ZUBEREITUNG Erdbeeren kalt abbrausen, abtropfen lassen und trocken tupfen. Blütenansatz entfernen. 150 Gramm der Früchte zugedeckt beiseite stellen. Restliche Erdbeeren in Stücke schneiden. Zucker, Vanillezucker und Weinbrand darunterheben und alles 30 Minuten zugedeckt ziehen lassen. Dann mit dem Mixstab fein pürieren. Die Hälfte der Sahne steif schlagen und unter das Püree ziehen. Die Creme im Gefrierfach oder in der Tiefkühltruhe gefrieren lassen. Restliche Sahne halbsteif schlagen. Mit einem Esslöffel Nocken von der Mousse abstechen und auf Dessertteller verteilen. Die halbsteife Sahne angießen und das Dessert mit den ganzen Erdbeeren garnieren. Quelle: Rezept Bedienungs-anleitung Auch im Alltag gibt es Verfahrensbeschreibungen, die algorithmische Züge aufweisen. Die Anforderungen an den "Prozessor" sind aber in der Regel nicht so hoch wie bei Algorithmen in der Informatik.
52
Al-Khwarizmi Die Bezeichnung „Algorithmus“ leitet sich aus dem Namen „Al-Khwarizmi“ – einem arabischen Mathematiker – ab. Abu Abd Allah Mohammed Ibn Musa Al-Khwarizmi lebte etwa von 780 bis 850 n. Chr. Er stammte aus Choresm (arab. Khwarizmi), eine Gegend südlich des Aralsees, die heute Teil von Usbekistan und Turkmenistan ist. Für seinen Namen sind mehrere Schreibweisen gebräuchlich, z.B. Alhwarizmi, Al-Hwarizmi, al-Khowarizmi oder auch Mohammed ben Musa. Al-Khwarizmi beschäftigte sich u. a. mit Verfahren zur Lösung von Gleichungen. Er verfasste Bücher, die sich mit Algebra, Astronomie und Geographie beschäftigten, sowie Werke über indische Ziffern und den Jüdischen Kalender.
53
Exkurs – Korrektheit von Algorithmen
Teil 3 Exkurs – Korrektheit von Algorithmen
54
Korrektheit als Problem
Oft findet man folgende Situation vor: Gesucht ist ein Algorithmus, der ein bestimmtes Verhalten hat. Nachdem man einen Algorithmus entwickelt hat, stellt sich die Frage, ob er auch tatsächlich das leistet, was er vorgibt zu leisten bzw. was vom ihm erwartet wird.
55
Spezifikation Das Verhalten eines Algorithmus lässt sich mit einer Spezifikation präzise beschreiben. Eine Spezifikation besteht (hier) aus einer Vorbedingung, die den Ausgangszustand beschreibt, sowie einer Nachbedingung, die den Endzustand beschreibt. Vorbedingung vorher: { zahl1 = a; zahl2 = b; a, b N } nachher: { produkt = a*b } Nachbedingung
56
Korrektheit von Algorithmen
Ein Algorithmus heißt terminierend bzgl. einer Spezifikation, wenn er bei jedem Ausgangszustand, der die Vorbedingung erfüllt, nach endlich vielen Verarbeitungsschritten zu einem Ende kommt. Ein Algorithmus heißt (total) korrekt bzgl. einer Spezifikation, wenn er terminierend ist und jeden Ausgangszustand, der die Vorbedingung erfüllt, in einen Endzustand überführt, der die Nachbedingung erfüllt. vorher: { zahl1 = a; zahl2 = b; a, b N } (total) korrekt bzgl. der angegebenen Spezifikation nachher: { produkt = a*b }
57
Korrektheitsnachweis mit Testen
Beim Testen eines Algorithmus wird der Algorithmus bei bestimmten vorgegebenen Testdaten ausgeführt und dabei überprüft, ob er in diesen Fällen das gewünschte Verhalten zeigt. Mit dieser Methode kann man das Vorhandensein von Fehlern entdecken. Man kann aber in der Regel nicht nachweisen, dass der Algorithmus korrekt bzgl. der gegebenen Spezifikation ist. vorher: { zahl1 = a; zahl2 = b; a, b N } x = 13; y = 12: ok x = 3; y = 0: ok ... nachher: { produkt = a*b }
58
Teststrategien Testdaten sollten immer sorgfältig ausgewählt werden. Man sollte sowohl typische als auch untypische Eingabewerte betrachten. Besondere Aufmerksamkeit ist auf Sonderfälle und Grenzwerte zu richten. Unter letzteren versteht man Werte, die gerade noch als Eingabewerte zugelassen sind (z. B. größter und kleinster Wert, leerer Text, leere Eingabe usw.). Oft ist es auch günstig, zufällig erzeugte Testdaten zu verwenden. Bei der Durchführung von Tests sollte man vorher notieren, welche Ausgabe das Programm laut Spezifikation liefern soll. Danach überprüft man, ob der Algorithmus tatsächlich dieses Verhalten zeigt. In einem Exkurs zur Testausführung mit Python zeigen wir, wie solche Testfälle in lauffähige Implementierungen von Algorithmen integriert werden können.
59
Testen mit Python Es gibt verschiedene Möglichkeiten, einen Algorithmus in Python zu testen. # Implementierung des Algorithmus def multiplikation(zahl1, zahl2): produkt = 0 while zahl1 > 0: if zahl1 % 2 == 1: produkt = produkt + zahl2 zahl1 = zahl1 // 2 zahl2 = zahl2 * 2 return produkt # Test print(multiplikation(13, 12)) print(multiplikation(12, 13)) print(multiplikation(4, 1)) print(multiplikation(1, 4)) print(multiplikation(3, 0)) print(multiplikation(0, 3)) >>> 156 4 Testergebnisse Testfälle
60
Testen mit Python def multiplikation(zahl1, zahl2): """
156 >>> multiplikation(12, 13) produkt = 0 while zahl1 > 0: if zahl1 % 2 == 1: produkt = produkt + zahl2 zahl1 = zahl1 // 2 zahl2 = zahl2 * 2 return produkt if __name__ == "__main__": import doctest doctest.testmod(verbose=True) Trying: multiplikation(13, 12) Expecting: 156 ok multiplikation(12, 13) 1 items had no tests: __main__ 1 items passed all tests: 2 tests in __main__.multiplikation 2 tests in 2 items. 2 passed and 0 failed. Test passed. von Python erzeugtes Testprotokoll vorher festgelegte Testfälle mit erwarteten Ergebnissen
61
alternativ: doctest.testmod()
Testen mit Python def multiplikation(zahl1, zahl2): """ >>> multiplikation(13, 12) 156 >>> multiplikation(12, 13) 154 produkt = 0 while zahl1 > 0: if zahl1 % 2 == 1: produkt = produkt + zahl2 zahl1 = zahl1 // 2 zahl2 = zahl2 * 2 return produkt if __name__ == "__main__": import doctest doctest.testmod(verbose=False) Failed example: multiplikation(12, 13) Expected: 154 Got: 156 ********************************************************************** 1 items had failures: 1 of 2 in __main__.multiplikation ***Test Failed*** 1 failures. Es wird kein ausführliches Testprotokoll erzeugt. Es werden nur Fehler angezeigt. alternativ: doctest.testmod()
62
Verwendung von multiplikation(…, …)
Testen mit Python def multiplikation(zahl1, zahl2): """ >>> multiplikation(13, 12) 156 >>> multiplikation(12, 13) … # if __name__ == "__main__": import doctest doctest.testmod(verbose=True) 1 items had no tests: __main__ 0 tests in 1 items. 0 passed and 0 failed. Test passed. Zahl 1: 5 Zahl 2: 6 Produkt: 30 >>> Das Testprotokoll wird so immer erzeugt. Mit der Bedingung if __name__ == "__main__": wird das Testprotokoll bei der Verwendung in externen Dateien nicht erzeugt. from aegyptischeMultiplikation import * zahl1 = int(input("Zahl 1: ")) zahl2 = int(input("Zahl 2: ")) produkt = multiplikation(zahl1, zahl2) print("Produkt: ", produkt) Verwendung von multiplikation(…, …)
63
Übung def multiplikation(zahl1, zahl2): """
156 >>> multiplikation(12, 13) produkt = 0 while zahl1 > 0: if zahl1 % 2 == 1: produkt = produkt + zahl2 zahl1 = zahl1 // 2 zahl2 = zahl2 * 2 return produkt if __name__ == "__main__": import doctest doctest.testmod(verbose=True) Aufgaben Führe die Tests selbst durch. Ergänze weitere wichtige Testfälle.
64
Übung Aufgabe: Betrachte den folgenden Algorithmus zum Primzahltestproblem. Ist der Algorithmus korrekt bzgl. der angegebenen Spezifikation? Implementiere den Algorithmus und untersuche die Korrektheit mit Testfällen. Korrigiere ggf. den Algorithmus. ALGORITHMUS istPrimzahl(n): {n = a; a N} prim = True k = 2 SOLANGE k < n: WENN n % k == 0: prim = False k = k+1 {prim = True, falls a eine Primzahl ist, und prim = False, falls a keine Primzahl ist} Rückgabe: prim
65
Exkurs: Verifikation von Algorithmen
Behauptung: Der Algorithmus „Ägyptische Multiplikation“ ist korrekt bzgl. der angegebenen Spezifikation. vorher: { zahl1 = a; zahl2 = b; a, b N } Beweis: Der Algorithmus ist für alle natürlichen Zahlen terminierend, da zahl1 in jedem Schleifendurchlauf verkleinert wird und man eine natürliche Zahl nur endlich oft verkleinern kann, bis man die Zahl 0 erreicht. Wir zeigen jetzt, dass die Bedingung („Schleifeninvariante“) {zahl1 * zahl2 + produkt = a * b} vor dem ersten und nach jedem Schleifendurchlauf erfüllt ist. Vor dem ersten Schleifendurchlauf gilt diese Bedingung, da hier zahl1 = a und zahl2 = b und produkt = 0 gilt. Als nächstes zeigen wir, dass die genannte Bedingung nach einem Schleifendurchlauf noch gilt, sofern sie vorher bereits erfüllt war. Wir nehmen also an, dass die Bedingung {zahl1 * zahl2 + produkt = a * b} vor der Ausführung der Anweisungen der Schleife gilt. Die Werte der Variablen zahl1, zahl2 und produkt nach der Ausführung der Schleife bezeichnen wir mit zahl1', zahl2' und produkt'. nachher: { produkt = a*b }
66
Exkurs: Verifikation von Algorithmen
Fall 1: zahl1 ist ungerade. Es gibt dann eine Zahl n mit zahl1 = 2*n+1. Nach dem Schleifendurchlauf gilt: produkt' = produkt + zahl2; zahl1' = n; zahl2' = zahl2*2. Insgesamt ergibt sich dann: zahl1' * zahl2' + produkt' = n * zahl2*2 + produkt + zahl2 = (2*n+1)*zahl2 + produkt = zahl1 * zahl2 + produkt = a * b Fall 2: zahl1 ist gerade. Es gibt dann eine Zahl n mit zahl1 = 2*n. produkt' = produkt; zahl1' = n; zahl2' = zahl2*2. zahl1' * zahl2' + produkt' = n * zahl2*2 + produkt = (2*n)*zahl2 + produkt = zahl1 * zahl2 + produkt = a *b Kommt es zum Verlassen der Schleife, so gilt folglich {zahl1 * zahl2 + produkt = a * b} und zusätzlich die Bedingung zahl1 = 0. Hieraus folgt, dass die Nachbedingung {produkt = a * b} vor der Rückgabe der Daten erfüllt ist. vorher: { zahl1 = a; zahl2 = b; a, b N } nachher: { produkt = a*b }
67
Exkurs – Effizienz von Algorithmen
Teil 4 Exkurs – Effizienz von Algorithmen
68
Schnelles Potenzieren
Obwohl das Multiplikationsverfahren der Ägypter heute kaum noch benutzt wird, hat der Algorithmus und die dahinter steckende Idee nichts an ihrer Bedeutung verloren. Die Idee wird heute beim "schnellen Potenzieren" benutzt. In der freien Enzyklopädie Wikipedia findet man unter dem Stichwort "schnelles Potenzieren" die folgende Verfahrensbeschreibung: "Der Exponent wird schrittweise halbiert (das Ergebnis wird abgerundet) und die Basis schrittweise quadriert. Man streicht die Zeilen mit geradem Exponenten. Das Produkt der nichtgestrichenen rechten Zahlen ist die gesuchte Potenz."
69
Schnelles Potenzieren
So … 3 9 27 81 … 243 3^16 = ? oder so? 3 9 81 6561 3^16 = ?
70
Schnelles Potenzieren
3 9 81 6561 243 3^13 = ? Darstellung in Tabellenform: x y pot 3 13 1 9 6 1*3 = 3 81 6561 3*81 = 243 243*6561 =
71
Äquivalenz von Algorithmen
Zwei Algorithmen heißen äquivalent, wenn sie bei gleichen Ausgangszuständen jeweils gleiche Endzustände erzeugen. äquivalent äquivalent
72
Effizienz von Algorithmen
Von zwei äquivalenten Algorithmen heißt der effizienter, der mit weniger Ressourcen (d. h. Rechenzeit oder Speicherplatz) auskommt. effizienter
73
Laufzeitmessung mit Python
Es gibt verschiedene Möglichkeiten, den Aufwand eines Algorithmus in Python zu messen. # Deklaration def potenz_naiv(x, y): pot = 1 while y > 0: pot = pot * x y = y - 1 return pot # Test mit Laufzeitmessung from time import * t1 = clock() ergebnis = potenz_naiv(1, ) t2 = clock() t = t2 - t1 print("Rechenzeit: ", t) Verwendung einer "internen Uhr" >>> Rechenzeit: Aufgabe: Bestimme auch die Laufzeit zum schnellen Potenzieren.
74
Aktionen zählen mit Python
Es gibt verschiedene Möglichkeiten, den Aufwand eines Algorithmus in Python zu messen. # Deklaration def potenz_naiv(x, y): z = 0 pot = 1 while y > 0: z = z + 1 pot = pot * x y = y - 1 return (pot, z) # Test mit Laufzeitmessung (ergebnis, anzahl) = potenz_naiv(1, ) print("Anzahl der Schleifendurchläufe: ", anzahl) Zähler für Schleifendurchläufe >>> Anzahl der Schleifendurchläufe: Aufgabe: Bestimme auch die Anzahl der Schleifendurchläufe beim schnellen Potenzieren.
75
Übung Aufgabe: Untersuche das Laufzeitverhalten einer Implementierung des folgenden Algorithmus. Wie ändert sich die Laufzeit, wenn man folgende Primzahlen testet: 11, 101, 1009, 10007, 100003, , , , , , , , , , , , , , ...
76
Übung Aufgabe: Betrachte den folgenden Algorithmus zum Primzahltestproblem. Wie könnte man ihn effizienter gestalten?
77
Rekursive Algorithmen
Teil 5 Rekursive Algorithmen
78
Begrüßungsproblem Kira und Karim werden demnächst 18 Jahre alt. Ihre Freunde sind zu einer riesigen Fete eingeladen. Damit alle sich kennenlernen, soll jeder jeden erst einmal begrüßen. Wenn alle eingeladenen Gäste zur Fete kommen, dann sind das - zusammen mit Kira und Karim Personen. Wie viele Begrüßungen werden dann stattfinden, wenn tatsächlich jeder jeden begrüßt? Ziel ist es, ein Berechnungsverfahren für die Funktion anzahlBegruessungen zu entwickeln. Bei Übergabe der Anzahl der Personen soll diese Funktion die Anzahl der erforderlichen Begrüßungen bestimmen und zurückgeben.
79
Ein Berechnungsverfahren
anzahlBegruessungen(1) = 0 anzahlBegruessungen(2) = anzahlBegruessungen(1) + 1 = = 1 anzahlBegruessungen(3) = anzahlBegruessungen(2) + 2 = = 3 anzahlBegruessungen(4) = anzahlBegruessungen(3) + 3 = = 6
80
Ein Berechnungsverfahren
anzahlBegruessungen(4) = anzahlBegruessungen(3) + 3 = = 6 5 Personen: anzahlBegruessungen(5) = … … Personen: anzahlBegruessungen(anzahlPersonen) = … Aufgabe: Ergänze die Berechnungsformeln.
81
Implementierung def anzahlBegruessungen(anzahlPersonen):
if anzahlPersonen < 2: ergebnis = 0 else: ergebnis = anzahlBegruessungen(anzahlPersonen-1) + (anzahlPersonen-1) return ergebnis >>> anzahlBegruessungen(4) 6 >>> anzahlBegruessungen(113) ... Aufgaben: Teste die Funktion mit verschiedenen Funktionsaufrufen. Bestimme auch die gesuchte Anzahl bei 113 Personen. In der Funktionsdefinition der Funktion anzahlBegruessungen kommt keine Wiederholeanweisung vor. Trotzdem wird hier eine Berechnung wiederholt durchgeführt. Wie wird diese wiederholte Berechnung hier beschrieben? In der Funktionsdefinition der Funktion anzahlBegruessungen kommt eine Fallunterscheidung vor. Wozu wird diese Fallunterscheidung benötigt?
82
Implementierung def anzahlBegruessungen(anzahlPersonen):
print('berechne anzahlPersonen('+str(anzahlPersonen)+')') if anzahlPersonen < 2: ergebnis = 0 else: ergebnis = anzahlBegruessungen(anzahlPersonen-1) + (anzahlPersonen-1) print('liefere '+str(ergebnis)) return ergebnis >>> anzahlBegruessungen(4) berechne anzahlPersonen(4) berechne anzahlPersonen(3) berechne anzahlPersonen(2) berechne anzahlPersonen(1) liefere 0 liefere 1 liefere 3 liefere 6 6 Aufgabe: Erkläre, wie die Ausgaben bei der Berechnung von Funktionswerten hier zustande kommen.
83
Rekursive Funktionsdefinition
Problem: Berechnung der Summe aufeinander folgender natürlicher Zahlen Beispiel: summe(5) = = 15 summe(4) -> summe(3) + 4 summe(0) -> def summe(n): if n == 0: ergebnis = 0 else: ergebnis = summe(n-1) + n return ergebnis (rekursive) Reduktionsschritte rekursive Funktionsdefinition Rekursive Problemreduktion: Reduziere des Problems auf ein entsprechendes, aber „verkleinertes“ Problem. Eine rekursive Funktionsdefinition ruft sich (eventuell über Umwege) selbst auf und nutzt sich so selbst zur Definition der Verarbeitung.
84
Rekursive Funktionsdefinition
Problem: Berechnung der Summe aufeinander folgender natürlicher Zahlen Beispiel: summe(5) = = 15 summe(4) -> summe(3) + 4 -> (summe(2) + 3) + 4 -> ((summe(1) + 2) + 3) + 4 -> (((summe(0) + 1) + 2) + 3) + 4 -> (((0 + 1) + 2) + 3) + 4 -> ((1 + 2) + 3) + 4 -> (3 + 3) + 4 -> > 10 def summe(n): if n == 0: ergebnis = 0 else: ergebnis = summe(n-1) + n return ergebnis Reduktionsanfang Reduktionsschritt >>> summe(4) 10 Reduktionskette
85
Übungen Aufgabe: Flummi
Ein Ball werde aus einer Höhe von 2 m fallen gelassen. Nach jedem Aufprall erreicht der Ball wieder das 0,8-fache der vorherigen Höhe. Die Funktion hoeheBall soll die Höhe des Balls nach dem n-ten Aufprall berechnen. Wichtige Gebrauchshinweise: Nehmen Sie jeden Morgen eine Tablette mit viel Wasser ein. Jede Tablette enthält 5mg des Wirkstoffs Plazebotin. Der Körper baut im Laufe des Tages 40% dieses Wirkstoffs ab. Achtung: Befinden sich 20 mg des Wirkstoffs im Körper, so muss das Medikament sofort abgesetzt werden. Aufgabe: Medikamenteneinnahme Ein Patient nimmt jeden Morgen eine feste Menge eines Medikaments ein. Im Laufe des Tages wird ein bestimmter Prozentsatz von dem gesamten, im Körper befindlichen Medikament abgebaut. Entwickle eine Funktion, die die Medikamentenmenge im Körper am n-ten Tag morgens direkt nach der Einnahme des Medikaments berechnet.
86
Übungen Aufgabe: Quadratpflanze
Ein Quadrat mit der Seitenlänge a wächst, indem täglich eine neue Generation an Quadraten hinzukommt (siehe Abbildung), deren Seitenlänge nur noch 1/3 der Seitenlänge der vorangegangenen Generation beträgt. Entwickle Funktionen zur Berchnung des Flächeninhalts und des Umfangs der Quadratpfanze der n-ten Generation.
87
Übungen Aufgabe: Wege im Galton-Brett
Wie viele Wege gibt es im Galton-Brett bis zum Stab (m, n)? Bestimme für alle Stäbe erst einmal die jeweilige Anzahl. Zur Kontrolle: Bis zum Stab (5, 3) gibt es 10 Wege. Die Funktion galton(m, n) beschreibe die Anzahl der Wege im Galton-Brett bis zum Stab (m, n). Begründe folgende Eigenschaften dieser Funktion: galton(n, 0) = 1 galton(n, n) = 1 galton(m, n) = galton(m-1, n-1) + galton(m-1, n), falls m > 0 und 0 < n < m gilt. Implementiere und teste die Funktion.
88
Übungen Aufgabe: Fibonacci-Folge
Ein Kaninchenpaar wirft vom zweiten Monat an in jedem Monat genau ein junges Kaninchenpaar. Dieses und alle Nachkommen verhalten sich ebenso. Wieviele Kaninchenpaare sind nach einem Jahr / n Monaten vorhanden, wenn kein Kaninchen stirbt oder aus dem Stall entflieht? Entwickle eine rekursive Funktionsdefinition zur Berechnung der Anzahl der Kaninichen nach n Monaten. Quelle:
89
Türme von Hanoi Einer Geschichte zufolge soll im Tempel zu Benares - das ist eine "heilige Stadt" in Indien - ein Turm aus 64 goldenen, der Größe nach geordneten Scheiben stehen. Die Mönche des Tempels erhalten die Aufgabe, die Scheiben an einen anderen Ort zu bringen. Dabei müssen sie einige Regeln beachten: Es darf immer nur eine Scheibe transportiert werden. Scheiben können auf einem (einzigen) Hilfsstapel zwischenzeitlich abgelegt werden. Auch auf dem (teilweise abgebauten) Ausgangsturm können Scheiben zwischenzeitlich abgelegt werden. Es darf aber nie eine größere Scheibe auf eine kleinere gelegt werden. Wenn der neue Turm fertig ist, dann ist das Ende der Zeit erreicht.
90
Türme von Hanoi Aufgabe: Versuche, einen Turm mit 5 Scheiben nach den vorgegebenen Regeln umzustapeln. Wenn das nicht klappt, dann versuche erst einmal, Türme mit 3 bzw. 4 Scheiben umzustapeln. Ausgangszustand Zielzustand Benutze hierzu Münzen unterschiedlicher Größe oder ein Simulationsprogramm. z. B.:
91
Türme von Hanoi Aufgabe: Überlege dir auch eine Strategie, mit der man Türme mit 6, 7, ... Scheiben umstapeln kann. Ausgangszustand Zielzustand
92
Lösungsidee transportiere einen 5-Scheiben-Turm von A über B nach C
Ausgangszustand transportiere einen 4-Scheiben-Turm von A über C nach B Zwischenzustand transportiere eine Scheibe von A nach C Zwischenzustand transportiere einen 4-Scheiben-Turm von B über A nach C Zielzustand
93
Verallgemeinerung transportiere einen n-Scheiben-Turm von X über Y nach Z Ausgangszustand transportiere einen (n-1)-Scheiben-Turm von X über Z nach Y Zwischenzustand transportiere eine Scheibe von X nach Z Zwischenzustand transportiere einen (n-1)-Scheiben-Turm von Y über X nach Z Zielzustand
94
Algorithmus Algorithmus: transportiere einen n-Scheiben-Turm von X über Y nach Z wenn n > 1: transportiere einen (n-1)-Scheiben-Turm von X über Z nach Y transportiere eine Scheibe von X nach Z transportiere einen (n-1)-Scheiben-Turm von Y über X nach Z sonst:
95
Rekursive Problemreduktion
Rekursive Problemreduktion ist eine Problemlösestrategie, bei der ein Problem auf ein strukturgleiches Problem (in verkleinerter Form) zurückgeführt wird. Algorithmus: transportiere einen n-Scheiben-Turm von X über Y nach Z wenn n > 1: transportiere einen (n-1)-Scheiben-Turm von X über Z nach Y transportiere eine Scheibe von X nach Z transportiere einen (n-1)-Scheiben-Turm von Y über X nach Z sonst: Ein rekursiver Algorithmus ruft sich (eventuell über Umwege) selbst auf und nutzt sich so selbst zur Beschreibung der Lösung des gegebenen Problems. Um Rekursion als Problemlösestrategie nutzen zu können, benötigt man ein Ausführsystem, das in der Lage ist, rekursive Algorithmen wiederholt aufzurufen und auf diese Weise die eigentliche Lösung zu generieren.
96
Ausführung des Algorithmus
Algorithmus: transportiere einen n-Scheiben-Turm von X über Y nach Z wenn n > 1: transportiere einen (n-1)-Scheiben-Turm von X über Z nach Y transportiere eine Scheibe von X nach Z transportiere einen (n-1)-Scheiben-Turm von Y über X nach Z sonst: Ausführungstiefe: 1 transportiere einen 3-Scheiben-Turm von A über B nach C: transportiere einen 2-Scheiben-Turm von A über C nach B transportiere eine Scheibe von A nach C transportiere einen 2-Scheiben-Turm von B über A nach C
97
Ausführung des Algorithmus
Algorithmus: transportiere einen n-Scheiben-Turm von X über Y nach Z wenn n > 1: transportiere einen (n-1)-Scheiben-Turm von X über Z nach Y transportiere eine Scheibe von X nach Z transportiere einen (n-1)-Scheiben-Turm von Y über X nach Z sonst: Ausführungstiefe: 2 transportiere einen 3-Scheiben-Turm von A über B nach C: transportiere einen 2-Scheiben-Turm von A über C nach B: transportiere einen 1-Scheiben-Turm von A über B nach C transportiere eine Scheibe von A nach B transportiere einen 1-Scheiben-Turm von C über A nach B transportiere eine Scheibe von A nach C transportiere einen 2-Scheiben-Turm von B über A nach C: transportiere einen 1-Scheiben-Turm von B über C nach A transportiere eine Scheibe von B nach C
98
Ausführung des Algorithmus
Algorithmus: transportiere einen n-Scheiben-Turm von X über Y nach Z wenn n > 1: transportiere einen (n-1)-Scheiben-Turm von X über Z nach Y transportiere eine Scheibe von X nach Z transportiere einen (n-1)-Scheiben-Turm von Y über X nach Z sonst: Ausführungstiefe: 3 transportiere einen 3-Scheiben-Turm von A über B nach C: transportiere einen 2-Scheiben-Turm von A über C nach B: transportiere einen 1-Scheiben-Turm von A über B nach C: transportiere eine Scheibe von A nach C transportiere eine Scheibe von A nach B transportiere einen 1-Scheiben-Turm von C über A nach B: transportiere eine Scheibe von C nach B transportiere einen 2-Scheiben-Turm von B über A nach C: transportiere einen 1-Scheiben-Turm von B über C nach A: transportiere eine Scheibe von B nach A transportiere eine Scheibe von B nach C
99
Ausführung des Algorithmus
transportiere einen 3-Scheiben-Turm von A über B nach C: transportiere einen 2-Scheiben-Turm von A über C nach B: transportiere einen 1-Scheiben-Turm von A über B nach C: transportiere eine Scheibe von A nach C transportiere eine Scheibe von A nach B transportiere einen 1-Scheiben-Turm von C über A nach B: transportiere eine Scheibe von C nach B transportiere einen 2-Scheiben-Turm von B über A nach C: transportiere einen 1-Scheiben-Turm von B über C nach A: transportiere eine Scheibe von B nach A transportiere eine Scheibe von B nach C Basisaktionen
100
Implementierung in Python
Algorithmus: transportiere einen n-Scheiben-Turm von X über Y nach Z wenn n > 1: transportiere einen (n-1)-Scheiben-Turm von X über Z nach Y transportiere eine Scheibe von X nach Z transportiere einen (n-1)-Scheiben-Turm von Y über X nach Z sonst: Algorithmus def transportiereTurm(n, x, y, z): if n > 1: transportiereTurm(n-1, x, z, y) print("transportiere eine Scheibe von ", x, " nach ", z) transportiereTurm(n-1, y, x, z) else: Python-Programm Aufgabe: Teste die Implementierung des Algorithmus "Türme von Hanoi" mit verschiedenen n-Werten.
101
Implementierung in Python
Aufgabe: Die Prozedur aus Aufgabe 1 ist um eine print-Anweisung erweitert worden. Kannst du ohne es auspobiert zu haben vorhersagen, welche Ausgaben die Prozedur beim Aufruf transportiereTurm(3, 'A', 'B', 'C') auf dem Bildschirm macht? Überprüfe dein Ergebnis. def transportiereTurm(n, x, y, z): print("transportiere einen ", n, " -Scheiben-Turm von ", x, " nach ", z) if n > 1: transportiereTurm(n-1, x, z, y) print("transportiere eine Scheibe von ", x, " nach ", z) transportiereTurm(n-1, y, x, z) else:
102
Anwendung - Selbstähnliche Figur
Eine Figur ist selbstähnlich, wenn sie sich in Teile zerlegen lässt, die zur ihr ähnlich sind.
103
Anwendung - Selbstähnliche Figuren
Eine Figur ist selbstähnlich, wenn sie sich in Teile zerlegen lässt, die zur ihr ähnlich sind. zeichne_Baum(200): gehe_vorwaerts(200) drehe_dich_nach_rechts(45) zeichne_Baum(100) drehe_dich_nach_links(90) gehe_rueckwaerts(200) ALG zeichne_Baum(x): wenn x >= 2: gehe_vorwaerts(x) drehe_dich_nach_rechts(45) zeichne_Baum(x/2) drehe_dich_nach_links(90) gehe_rueckwaerts(x) rekursive Problemreduktion rekursiver Algorithmus
104
Exkurs - Turtle-Grafik
Turtle-Grafik basiert auf der Vorstellung, dass eine Schildkröte mit bestimmten Anweisungen auf einer Zeichenfläche bewegt wird und dass die Schildkröte dabei eine Spur hinterlässt. vorwaerts(100) Turtle-Befehle zeichne_Quadrat(laenge): wiederhole 4 mal: gehe_vorwaerts(laenge) drehe_dich_nach_links(90) stift_hoch stift_runter gehe_vorwaerts(betrag) gehe_rueckwaerts(betrag) drehe_dich_nach_links(winkel) drehe_dich_nach_rechts(winkel) gehe_zu_punkt(punkt) ... Turtle-Algorithmus
105
Exkurs - Turtle-Grafik in Python
Turtle-Grafik basiert auf der Vorstellung, dass eine Schildkröte mit bestimmten Anweisungen auf einer Zeichenfläche bewegt wird und dass die Schildkröte dabei eine Spur hinterlässt. zeichne_Quadrat(laenge): wiederhole 4 mal: gehe_vorwaerts(laenge) drehe_dich_nach_links(90) stift_hoch stift_runter gehe_vorwaerts(betrag) gehe_rueckwaerts(betrag) drehe_dich_nach_links(winkel) drehe_dich_nach_rechts(winkel) gehe_zu_punkt(punkt) ... Turtle-Programm from turtle import * # Deklaration einer Zeichenprozedur def quadrat(laenge): for i in range(4): forward(laenge) left(90) # Test der Zeichenprozedur quadrat(100) Turtle-Klasse >>> from turtle import * >>> forward(100) >>> bye() t.forward(100)
106
Exkurs - Turtle-Grafik in Python
from turtle import * # Deklaration einer Zeichenprozedur def baum(stamm): if stamm >= 2: forward(stamm) right(45) baum(stamm/2) left(90) backward(stamm) # Test der Zeichenprozedur baum(200) ALG zeichne_Baum(x): wenn x >= 2: gehe_vorwaerts(x) drehe_dich_nach_rechts(45) zeichne_Baum(x/2) drehe_dich_nach_links(90) gehe_rueckwaerts(x)
107
Übungen Wählen Sie eine der folgenden selbstähnlichen Figuren aus. Entwickeln Sie mit Hilfe einer rekursive Problemreduktion einen rekursiven Algorithmus zum Zeichnen der Figur. Testen Sie den Algorithmus mit einer Python-Implementierung.
108
Übungen Wählen Sie eine der folgenden selbstähnlichen Figuren aus. Entwickeln Sie mit Hilfe einer rekursive Problemreduktion einen rekursiven Algorithmus zum Zeichnen der Figur. Testen Sie den Algorithmus mit einer Python-Implementierung.
109
Übungen Wählen Sie eine der folgenden selbstähnlichen Figuren aus. Entwickeln Sie mit Hilfe einer rekursive Problemreduktion einen rekursiven Algorithmus zum Zeichnen der Figur. Testen Sie den Algorithmus mit einer Python-Implementierung.
110
Übungen Wählen Sie eine der folgenden selbstähnlichen Figuren aus. Entwickeln Sie mit Hilfe einer rekursive Problemreduktion einen rekursiven Algorithmus zum Zeichnen der Figur. Testen Sie den Algorithmus mit einer Python-Implementierung.
111
Übungen Wählen Sie eine der folgenden selbstähnlichen Figuren aus. Entwickeln Sie mit Hilfe einer rekursive Problemreduktion einen rekursiven Algorithmus zum Zeichnen der Figur. Testen Sie den Algorithmus mit einer Python-Implementierung.
112
Übungen Wählen Sie eine der folgenden selbstähnlichen Figuren aus. Entwickeln Sie mit Hilfe einer rekursive Problemreduktion einen rekursiven Algorithmus zum Zeichnen der Figur. Testen Sie den Algorithmus mit einer Python-Implementierung.
Ähnliche Präsentationen
© 2025 SlidePlayer.org Inc.
All rights reserved.