Algorithmen und Datenstrukturen Tafelübung 4 Jens Wetzl 15. November 2011
Folien Keine Garantie für Vollständigkeit und/oder Richtigkeit Keine offizielle Informationsquelle LS2-Webseite Abrufbar unter: http://wwwcip.cs.fau.de/~sijewetz/aud_ws11 Hinweis zu Aufgabe 4.4: Rekursive Kunst Im CIP-Pool läuft der process checker, der Programme abschießt, die lange mit hoher CPU-Auslastung laufen Große rekursive Kunstwerke auf dem eigenen Rechner! 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 2 / 19
Was machen wir heute? Rekursion Theorie Beispiele Rekursionsarten Live-Programmierung: Türme von Hanoi Induktionsbeweise Backtracking Vorgehensweise Live-Programmierung: Monopoly Klausuraufgabe zu Rekursion 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 3 / 19
Rekursion Theorie Beispiele Rekursionsarten
Theorie Rekursiver Gedanke: Wir wollen ein Problem so in ein oder mehrere (kleinere) Teilprobleme zerlegen, dass 1. bei fortgesetzter Zerlegung die Teilprobleme irgendwann so klein sind, dass sie trivial gelöst werden können 2. aus den Lösungen der kleineren Teilprobleme leicht die Lösung des größeren Problems zusammengestellt werden kann Eine rekursive Methode sieht häufig so aus: static int recursive(int arg1, int arg2,...) { // Basisfall / Basisfaelle: if (arg1 == 0 arg2 == 0) return 1; // Teilprobleme durch Rekursion loesen: int a = recursive(arg1-1, arg2); int b = recursive(arg1, arg2-1); // Zusammensetzen der Loesung aus den Teilloesungen: return a * b; 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 5 / 19
Theorie Rekursiver Gedanke: Wir wollen ein Problem so in ein oder mehrere (kleinere) Teilprobleme zerlegen, dass 1. bei fortgesetzter Zerlegung die Teilprobleme irgendwann so klein sind, dass sie trivial gelöst werden können 2. aus den Lösungen der kleineren Teilprobleme leicht die Lösung des größeren Problems zusammengestellt werden kann Eine rekursive Methode sieht häufig so aus: static int recursive(int arg1, int arg2,...) { // Basisfall / Basisfaelle: if (arg1 == 0 arg2 == 0) return 1; // Teilprobleme durch Rekursion loesen: int a = recursive(arg1-1, arg2); int b = recursive(arg1, arg2-1); // Zusammensetzen der Loesung aus den Teilloesungen: return a * b; 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 5 / 19
Theorie Rekursiver Gedanke: Wir wollen ein Problem so in ein oder mehrere (kleinere) Teilprobleme zerlegen, dass 1. bei fortgesetzter Zerlegung die Teilprobleme irgendwann so klein sind, dass sie trivial gelöst werden können 2. aus den Lösungen der kleineren Teilprobleme leicht die Lösung des größeren Problems zusammengestellt werden kann Eine rekursive Methode sieht häufig so aus: static int recursive(int arg1, int arg2,...) { // Basisfall / Basisfaelle: if (arg1 == 0 arg2 == 0) return 1; // Teilprobleme durch Rekursion loesen: int a = recursive(arg1-1, arg2); int b = recursive(arg1, arg2-1); // Zusammensetzen der Loesung aus den Teilloesungen: return a * b; 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 5 / 19
Theorie Rekursiver Gedanke: Wir wollen ein Problem so in ein oder mehrere (kleinere) Teilprobleme zerlegen, dass 1. bei fortgesetzter Zerlegung die Teilprobleme irgendwann so klein sind, dass sie trivial gelöst werden können 2. aus den Lösungen der kleineren Teilprobleme leicht die Lösung des größeren Problems zusammengestellt werden kann Eine rekursive Methode sieht häufig so aus: static int recursive(int arg1, int arg2,...) { // Basisfall / Basisfaelle: if (arg1 == 0 arg2 == 0) return 1; // Teilprobleme durch Rekursion loesen: int a = recursive(arg1-1, arg2); int b = recursive(arg1, arg2-1); // Zusammensetzen der Loesung aus den Teilloesungen: return a * b; 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 5 / 19
Beispiele f (n) = n i=1 i, n > 0 g(n): Abstand der Zahl n von 5 fib(n) = fib(n 1) + fib(n 2): Was muss man hier im Gegensatz zu den Funktionen oben beachten? Pseudocode für Listenlänge: x0, xrest = split(x) spaltet x in 1. Element und Restliste auf, empty(x) prüft, ob Liste x leer ist Stammbaum: void drawfamilytree(person p) { write(p.getname()); if (p.haschildren()) { for (Person child: p.getchildren()) { drawfamilytree(child); drawlink(person, child); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 6 / 19
Beispiele f (n) = n i=1 i, n > 0 g(n): Abstand der Zahl n von 5 fib(n) = fib(n 1) + fib(n 2): Was muss man hier im Gegensatz zu den Funktionen oben beachten? Pseudocode für Listenlänge: x0, xrest = split(x) spaltet x in 1. Element und Restliste auf, empty(x) prüft, ob Liste x leer ist Stammbaum: void drawfamilytree(person p) { write(p.getname()); if (p.haschildren()) { for (Person child: p.getchildren()) { drawfamilytree(child); drawlink(person, child); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 6 / 19
Beispiele f (n) = n i=1 i, n > 0 g(n): Abstand der Zahl n von 5 fib(n) = fib(n 1) + fib(n 2): Was muss man hier im Gegensatz zu den Funktionen oben beachten? Pseudocode für Listenlänge: x0, xrest = split(x) spaltet x in 1. Element und Restliste auf, empty(x) prüft, ob Liste x leer ist Stammbaum: void drawfamilytree(person p) { write(p.getname()); if (p.haschildren()) { for (Person child: p.getchildren()) { drawfamilytree(child); drawlink(person, child); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 6 / 19
Beispiele f (n) = n i=1 i, n > 0 g(n): Abstand der Zahl n von 5 fib(n) = fib(n 1) + fib(n 2): Was muss man hier im Gegensatz zu den Funktionen oben beachten? Pseudocode für Listenlänge: x0, xrest = split(x) spaltet x in 1. Element und Restliste auf, empty(x) prüft, ob Liste x leer ist Stammbaum: void drawfamilytree(person p) { write(p.getname()); if (p.haschildren()) { for (Person child: p.getchildren()) { drawfamilytree(child); drawlink(person, child); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 6 / 19
Beispiele f (n) = n i=1 i, n > 0 g(n): Abstand der Zahl n von 5 fib(n) = fib(n 1) + fib(n 2): Was muss man hier im Gegensatz zu den Funktionen oben beachten? Pseudocode für Listenlänge: x0, xrest = split(x) spaltet x in 1. Element und Restliste auf, empty(x) prüft, ob Liste x leer ist Stammbaum: void drawfamilytree(person p) { write(p.getname()); if (p.haschildren()) { for (Person child: p.getchildren()) { drawfamilytree(child); drawlink(person, child); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 6 / 19
Rekursionsarten Lineare Rekursion Maximal ein rekursiver Aufruf pro Methodenaufruf (verschieden Aufrufe in verschiedenen Zweigen möglich) Endrekursion Rekursiver Funktionsaufruf ist letzte Aktion zur Berechnung der Methode (was ist der Vorteil? Beispiel?) Kaskadenartige Rekursion Zwei oder mehr rekursive Aufrufe pro Methodenaufruf (was heißt das für die Laufzeit? Beispiel?) Verschränkte Rekursion Zwei Funktionen f und g heißen verschränkt rekursiv, wenn f einen Aufruf von g und g einen von f enthält Verschachtelte Rekursion Z.B. Ackermann-Funktion: static int ackermann(int m, int n) { if (m == 0) return n + 1; if (n == 0) return ackermann(m - 1, 1); else return ackermann(m - 1, ackermann(m, n - 1)); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 7 / 19
Rekursionsarten Lineare Rekursion Maximal ein rekursiver Aufruf pro Methodenaufruf (verschieden Aufrufe in verschiedenen Zweigen möglich) Endrekursion Rekursiver Funktionsaufruf ist letzte Aktion zur Berechnung der Methode (was ist der Vorteil? Beispiel?) Kaskadenartige Rekursion Zwei oder mehr rekursive Aufrufe pro Methodenaufruf (was heißt das für die Laufzeit? Beispiel?) Verschränkte Rekursion Zwei Funktionen f und g heißen verschränkt rekursiv, wenn f einen Aufruf von g und g einen von f enthält Verschachtelte Rekursion Z.B. Ackermann-Funktion: static int ackermann(int m, int n) { if (m == 0) return n + 1; if (n == 0) return ackermann(m - 1, 1); else return ackermann(m - 1, ackermann(m, n - 1)); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 7 / 19
Rekursionsarten Lineare Rekursion Maximal ein rekursiver Aufruf pro Methodenaufruf (verschieden Aufrufe in verschiedenen Zweigen möglich) Endrekursion Rekursiver Funktionsaufruf ist letzte Aktion zur Berechnung der Methode (was ist der Vorteil? Beispiel?) Kaskadenartige Rekursion Zwei oder mehr rekursive Aufrufe pro Methodenaufruf (was heißt das für die Laufzeit? Beispiel?) Verschränkte Rekursion Zwei Funktionen f und g heißen verschränkt rekursiv, wenn f einen Aufruf von g und g einen von f enthält Verschachtelte Rekursion Z.B. Ackermann-Funktion: static int ackermann(int m, int n) { if (m == 0) return n + 1; if (n == 0) return ackermann(m - 1, 1); else return ackermann(m - 1, ackermann(m, n - 1)); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 7 / 19
Rekursionsarten Lineare Rekursion Maximal ein rekursiver Aufruf pro Methodenaufruf (verschieden Aufrufe in verschiedenen Zweigen möglich) Endrekursion Rekursiver Funktionsaufruf ist letzte Aktion zur Berechnung der Methode (was ist der Vorteil? Beispiel?) Kaskadenartige Rekursion Zwei oder mehr rekursive Aufrufe pro Methodenaufruf (was heißt das für die Laufzeit? Beispiel?) Verschränkte Rekursion Zwei Funktionen f und g heißen verschränkt rekursiv, wenn f einen Aufruf von g und g einen von f enthält Verschachtelte Rekursion Z.B. Ackermann-Funktion: static int ackermann(int m, int n) { if (m == 0) return n + 1; if (n == 0) return ackermann(m - 1, 1); else return ackermann(m - 1, ackermann(m, n - 1)); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 7 / 19
Rekursionsarten Lineare Rekursion Maximal ein rekursiver Aufruf pro Methodenaufruf (verschieden Aufrufe in verschiedenen Zweigen möglich) Endrekursion Rekursiver Funktionsaufruf ist letzte Aktion zur Berechnung der Methode (was ist der Vorteil? Beispiel?) Kaskadenartige Rekursion Zwei oder mehr rekursive Aufrufe pro Methodenaufruf (was heißt das für die Laufzeit? Beispiel?) Verschränkte Rekursion Zwei Funktionen f und g heißen verschränkt rekursiv, wenn f einen Aufruf von g und g einen von f enthält Verschachtelte Rekursion Z.B. Ackermann-Funktion: static int ackermann(int m, int n) { if (m == 0) return n + 1; if (n == 0) return ackermann(m - 1, 1); else return ackermann(m - 1, ackermann(m, n - 1)); 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 7 / 19
Live-Programmierung: Türme von Hanoi
Türme von Hanoi Quelle: http://goo.gl/h7kos 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 9 / 19
Induktionsbeweise
Induktionsbeweise Beweismethode, um zum Beispiel die Korrektheit einer rekursiven Formulierung zu zeigen Kann auch in der Klausur drankommen! Einfaches Beispiel: zu zeigen ist n k=1 c = n c Induktionsanfang: Für n = 1 ist 1 k=1 c = c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 1 gilt für n = 1: 2 k=1 c = c + 1 k=1 c = c + 1 c = 2 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 2 gilt für n = 3: 3 k=1 c = c + 2 k=1 c = c + 2 c = 3 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 3 gilt für n = 4: 4 k=1 c = c + 3 k=1 c = c + 3 c = 4 c = n c Induktionsschritt allgemein: n n + 1 n+1 k=1 c = c + n k=1 c IV = c + n c = (n + 1) c 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 11 / 19
Induktionsbeweise Beweismethode, um zum Beispiel die Korrektheit einer rekursiven Formulierung zu zeigen Kann auch in der Klausur drankommen! Einfaches Beispiel: zu zeigen ist n k=1 c = n c Induktionsanfang: Für n = 1 ist 1 k=1 c = c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 1 gilt für n = 1: 2 k=1 c = c + 1 k=1 c = c + 1 c = 2 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 2 gilt für n = 3: 3 k=1 c = c + 2 k=1 c = c + 2 c = 3 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 3 gilt für n = 4: 4 k=1 c = c + 3 k=1 c = c + 3 c = 4 c = n c Induktionsschritt allgemein: n n + 1 n+1 k=1 c = c + n k=1 c IV = c + n c = (n + 1) c 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 11 / 19
Induktionsbeweise Beweismethode, um zum Beispiel die Korrektheit einer rekursiven Formulierung zu zeigen Kann auch in der Klausur drankommen! Einfaches Beispiel: zu zeigen ist n k=1 c = n c Induktionsanfang: Für n = 1 ist 1 k=1 c = c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 1 gilt für n = 1: 2 k=1 c = c + 1 k=1 c = c + 1 c = 2 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 2 gilt für n = 3: 3 k=1 c = c + 2 k=1 c = c + 2 c = 3 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 3 gilt für n = 4: 4 k=1 c = c + 3 k=1 c = c + 3 c = 4 c = n c Induktionsschritt allgemein: n n + 1 n+1 k=1 c = c + n k=1 c IV = c + n c = (n + 1) c 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 11 / 19
Induktionsbeweise Beweismethode, um zum Beispiel die Korrektheit einer rekursiven Formulierung zu zeigen Kann auch in der Klausur drankommen! Einfaches Beispiel: zu zeigen ist n k=1 c = n c Induktionsanfang: Für n = 1 ist 1 k=1 c = c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 1 gilt für n = 1: 2 k=1 c = c + 1 k=1 c = c + 1 c = 2 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 2 gilt für n = 3: 3 k=1 c = c + 2 k=1 c = c + 2 c = 3 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 3 gilt für n = 4: 4 k=1 c = c + 3 k=1 c = c + 3 c = 4 c = n c Induktionsschritt allgemein: n n + 1 n+1 k=1 c = c + n k=1 c IV = c + n c = (n + 1) c 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 11 / 19
Induktionsbeweise Beweismethode, um zum Beispiel die Korrektheit einer rekursiven Formulierung zu zeigen Kann auch in der Klausur drankommen! Einfaches Beispiel: zu zeigen ist n k=1 c = n c Induktionsanfang: Für n = 1 ist 1 k=1 c = c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 1 gilt für n = 1: 2 k=1 c = c + 1 k=1 c = c + 1 c = 2 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 2 gilt für n = 3: 3 k=1 c = c + 2 k=1 c = c + 2 c = 3 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 3 gilt für n = 4: 4 k=1 c = c + 3 k=1 c = c + 3 c = 4 c = n c Induktionsschritt allgemein: n n + 1 n+1 k=1 c = c + n k=1 c IV = c + n c = (n + 1) c 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 11 / 19
Induktionsbeweise Beweismethode, um zum Beispiel die Korrektheit einer rekursiven Formulierung zu zeigen Kann auch in der Klausur drankommen! Einfaches Beispiel: zu zeigen ist n k=1 c = n c Induktionsanfang: Für n = 1 ist 1 k=1 c = c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 1 gilt für n = 1: 2 k=1 c = c + 1 k=1 c = c + 1 c = 2 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 2 gilt für n = 3: 3 k=1 c = c + 2 k=1 c = c + 2 c = 3 c = n c Induktionsschritt: Unter Verwendung der Korrektheit der Formel für n = 3 gilt für n = 4: 4 k=1 c = c + 3 k=1 c = c + 3 c = 4 c = n c Induktionsschritt allgemein: n n + 1 n+1 k=1 c = c + n k=1 c IV = c + n c = (n + 1) c 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 11 / 19
Gauß sche Summenformel Zu zeigen: n k = k=1 n (n + 1) 2 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 12 / 19
Gauß sche Summenformel Zu zeigen: n k = k=1 n (n + 1) 2 Induktionsanfang: n = 1: 1 2 1 2 = 1 = k k=1 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 12 / 19
Gauß sche Summenformel Zu zeigen: n k = k=1 n (n + 1) 2 Induktionsanfang: n = 1: 1 2 1 2 = 1 = k k=1 Induktionsschritt: n n + 1 n+1 k = k=1 = = n k + (n + 1) IV = k=1 n (n + 1) 2 (n + 1) (n + 2) 2 n (n + 1) + (n + 1) 2 2 (n + 1) + = 2 n (n + 1) + 2 (n + 1) 2 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 12 / 19
Backtracking Vorgehensweise Live-Programmierung: Monopoly
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 2 3 4 3 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 1 4 2 3 3 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 1 4 2 3 3 1 4 2 3 3 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 1 4 2 3 3 1 2 4 2 3 3 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 1 4 2 3 3 1 2 4 2 3 3 1 2 4? 2 3 3 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 3 4 2 3 3 3 4 2 3 3 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 3 4 2 3 3 3 2 4 2 3 3 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 3 4 2 3 3 3 2 4 2 3 3 3 2 4 2 3 3 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Backtracking: Vorgehensweise Am Beispiel Sudoku: Per Rekursion wird jede Zelle des Sudoku (mehrfach!) besucht, es werden alle möglichen Zahlen für die Zelle bestimmt Die erste mögliche Zahl wird in das Feld geschrieben, dann wird rekursiv nach Lösungen dieses neuen Sudoku gesucht Wird für die erste mögliche Zahl keine Lösung gefunden, wird nacheinander die zweite, dritte, usw. mögliche Zahl eingesetzt und jedes mal rekursiv nach Lösungen gesucht Wichtig: Wird für keine der möglichen Zahlen eine Lösung gefunden, wird das Feld wieder auf leer zurückgesetzt! 3 4 2 3 3 3 2 4 2 3 3 3 2 4 1 4 1 2 3 2 3 1 4 1 4 3 2 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 14 / 19
Live-Programmierung: Monopoly Quelle: http://goo.gl/b1lfd 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 15 / 19
Klausuraufgabe zu Rekursion
Klausur 02/2009: Aufgabe 5 Zum deterministischen Testen von Anwendungen lassen sich Pseudo- Zufallszahlen verwenden. Folgende Berechnungsformel erzeugt für n 0 solche Zahlen: f (n) = n + 1 n < 3 1 + (((f (n 1) f (n 2)) f (n 3)) mod 100) sonst Hinweis: Der Modulo-Operator a mod b ergibt den Rest bei ganzzahliger Division und kann in Java durch % ausgedrückt werden. 1. Implementieren Sie die Funktion f rekursiv in Java. public static int f(int n) { 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 17 / 19
Klausur 02/2009: Aufgabe 5 Zum deterministischen Testen von Anwendungen lassen sich Pseudo- Zufallszahlen verwenden. Folgende Berechnungsformel erzeugt für n 0 solche Zahlen: f (n) = n + 1 n < 3 1 + (((f (n 1) f (n 2)) f (n 3)) mod 100) sonst Hinweis: Der Modulo-Operator a mod b ergibt den Rest bei ganzzahliger Division und kann in Java durch % ausgedrückt werden. 2. Implementieren Sie die Funktion f nun linear-rekursiv mit Durchreichen von Zwischenergebnissen. Gegeben ist die zugehörige Initialisierungsmethode, die Ihre Methode aufruft. public static int f(int n) { return lin(1, 2, 3, n); public static int lin(int a, int b, int c, int steps) { 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 18 / 19
Klausur 02/2009: Aufgabe 5 Zum deterministischen Testen von Anwendungen lassen sich Pseudo- Zufallszahlen verwenden. Folgende Berechnungsformel erzeugt für n 0 solche Zahlen: f (n) = n + 1 n < 3 1 + (((f (n 1) f (n 2)) f (n 3)) mod 100) sonst Hinweis: Der Modulo-Operator a mod b ergibt den Rest bei ganzzahliger Division und kann in Java durch % ausgedrückt werden. 3. Implementieren Sie eine iterative Java-Variante der Funktion f. public static int f(int n) { 15. November 2011 Jens Wetzl (jens.wetzl@cs.fau.de) Tafelübung Algorithmen und Datenstrukturen 19 / 19