große Halb

Werbung
Rekursion
IFB Weiterbildungslehrgang X Informatik
Kurs 2: Thema „Rekursion“
2. 12. 2005
Tobias Selinger
2
Einleitung
Was macht man mit einem großen Problem?
Rekursion
Flugzeugsimulator-Programm
?
TS
3
Modularisierung - „Teile und herrsche“
Was macht man mit einem großen Problem?
Rekursion
Flugzeugsimulator-Programm
in Teilprobleme
BenutzerOberfläche
Level-Editor
TS
zerlegen
SpielSteuerung
Kartendatenbank
3D-System
Landschaftsgenerator
Zerlegung in Teilprobleme?
4
4! =
4• 3•2•1 =
24
Rekursion
5 ! = 5 • 4 • 3 • 2 • 1 = 120
TS
Definition: rekursiv lösbar
5
Ein Problem ist rekursiv lösbar,
falls man es in Teilprobleme zerlegen kann, die alle
• „ähnlich“ zum Gesamtproblem sind
• „kleiner“ als das Gesamtproblem sind
Rekursion
• irgendwann „direkt lösbar“ sind
Beispiel:
Zeichne diesen Busch!
Ähnliche Teilprobleme ?
TS
Busch: Teilprobleme
6
Ein Problem ist rekursiv lösbar,
falls man es in Teilprobleme zerlegen kann, die alle
• „ähnlich“ zum Gesamtproblem sind
• „kleiner“ als das Gesamtproblem sind
Rekursion
• irgendwann „direkt lösbar“ sind
Beispiel 1:
Zeichne diesen Busch!
linker
Teilbusch
rechter
Teilbusch
Ähnliche Teilprobleme:
Zeichne Teilbüsche !
Wie ???
TS
Level 1
Busch: Teilprobleme
7
Ein Problem ist rekursiv lösbar,
falls man es in Teilprobleme zerlegen kann, die alle
• „ähnlich“ zum Gesamtproblem sind
• „kleiner“ als das Gesamtproblem sind
Rekursion
• irgendwann „direkt lösbar“ sind
Beispiel 1:
Zeichne diesen Busch!
TeilTeilbusch busch
Teilbusch
Teilbusch
Level 2
Ähnliche Teilprobleme:
Zeichne Teilbüsche !
Wie ??? Ebenso... !
TS
Level 1
Busch: Bildungsgesetz
8
Ein Problem ist rekursiv lösbar,
falls man es in Teilprobleme zerlegen kann, die alle
• „ähnlich“ zum Gesamtproblem sind
• „kleiner“ als das Gesamtproblem sind
Rekursion
• irgendwann „direkt lösbar“ sind
Das rekursive Bildungsgesetz
für einen Busch lautet also:
Busch = ???
linker
(Teil-)Busch
Zweig nach
links
TS
rechter
(Teil-)Busch
Zweig nach
rechts
Busch: Bildungsgesetz
9
Ein Problem ist rekursiv lösbar,
falls man es in Teilprobleme zerlegen kann, die alle
• „ähnlich“ zum Gesamtproblem sind
• „kleiner“ als das Gesamtproblem sind
Rekursion
• irgendwann „direkt lösbar“ sind
Das rekursive Bildungsgesetz
für einen Busch lautet also:
Busch = rechter Zweig +
rechter (Teil)-Busch +
linker Zweig +
linker (Teil)-Busch
Beachte:
TS
Endlos-Rekursion???
linker
(Teil-)Busch
Zweig nach
links
rechter
(Teil-)Busch
Zweig nach
rechts
Busch: Bildungsgesetz
10
Ein Problem ist rekursiv lösbar,
falls man es in Teilprobleme zerlegen kann, die alle
• „ähnlich“ zum Gesamtproblem sind
• „kleiner“ als das Gesamtproblem sind
Rekursion
• irgendwann „direkt lösbar“ sind
Das rekursive Bildungsgesetz
für einen Busch lautet also:
Busch = rechter Zweig +
rechter (Teil)-Busch +
linker Zweig +
linker (Teil)-Busch
Beachte:
TS
linker
(Teil-)Busch
Zweig nach
links
rechter
(Teil-)Busch
Zweig nach
rechts
Wenn ein Teilbusch „klein genug“ ist,
gilt er als „abgeschlossen“ (ohne weitere Folgearbeit) !
Ansonsten müsste man endlos weiterzeichnen...
Busch: Programmierung
11
Programmierung der
Grundstruktur:
Rekursion
linker
(Teil-)Busch
procedure busch(laenge: real);
begin
Eintrittsbedingung
if laenge > 10 then
with Form1.Turtle1 do begin
turnright(20);
???
forwd(laenge);
back(laenge);
turnleft(40);
forwd(laenge);
TS
back(laenge);
turnright(20);
end;
end;
???
???
Zweig nach
links
rechter
(Teil-)Busch
Zweig nach
rechts
Busch: Programmierung
12
Programmierung der
Grundstruktur:
Rekursion
linker
(Teil-)Busch
procedure busch(laenge: real);
begin
Eintrittsbedingung
Zweig nach
if laenge > 10 then
links
with Form1.Turtle1 do begin
turnright(20);
rechten Zweig zeichnen
forwd(laenge);
back(laenge);
turnleft(40);
forwd(laenge);
TS
back(laenge);
turnright(20);
end;
end;
rechter
(Teil-)Busch
Zweig nach
rechts
zurück und
linken Zweig zeichnen
zurück und geradeaus drehen
(in Ausgangsposition!)
Busch: Programmierung
13
Programmierung der
Grundstruktur:
Rekursion
Ergänzung der
rekursiven Aufrufe:
TS
linker
(Teil-)Busch
rechter
(Teil-)Busch
procedure busch(laenge: real);
begin
Zweig nach
Zweig nach
if laenge > 10 then
links
rechts
with Form1.Turtle1 do begin
turnright(20);
rechten Zweig zeichnen
forwd(laenge);
rechten Teilbusch zeichnen?
???
back(laenge);
zurück und
turnleft(40);
linken Zweig zeichnen
forwd(laenge);
???
linken Teilbusch zeichnen?
back(laenge);
zurück und geradeaus drehen
turnright(20);
end;
end;
Busch: Programmierung
14
Programmierung der
Grundstruktur:
Rekursion
Ergänzung der
rekursiven Aufrufe:
TS
linker
(Teil-)Busch
rechter
(Teil-)Busch
procedure busch(laenge: real);
begin
Zweig nach
Zweig nach
if laenge > 10 then
links
rechts
with Form1.Turtle1 do begin
turnright(20);
rechten Zweig zeichnen
forwd(laenge);
rechten Teilbusch zeichnen
busch(...................);
back(laenge);
zurück und
turnleft(40);
linken Zweig zeichnen
forwd(laenge);
busch(...................);
linken Teilbusch zeichnen
back(laenge);
zurück und geradeaus drehen
turnright(20);
end;
end;
Busch: Programmierung
15
Programmierung der
Grundstruktur:
Rekursion
Ergänzung der
rekursiven Aufrufe:
TS
linker
(Teil-)Busch
rechter
(Teil-)Busch
procedure busch(laenge: real);
begin
Zweig nach
Zweig nach
if laenge > 10 then
links
rechts
with Form1.Turtle1 do begin
turnright(20);
rechten Zweig zeichnen
forwd(laenge);
rechten Teilbusch zeichnen
busch(laenge * 0.7);
back(laenge);
zurück und
turnleft(40);
linken Zweig zeichnen
forwd(laenge);
busch(laenge * 0.7);
linken Teilbusch zeichnen
back(laenge);
zurück und geradeaus drehen
turnright(20);
end;
Programmend;
Demo!
Busch: Aufbau der „Levels“
Rekursion
16
Level 1
TS
Busch: Aufbau der „Levels“
Rekursion
17
Level 2
TS
Busch: Aufbau der „Levels“
Rekursion
18
Level 3
TS
Busch: Aufbau der „Levels“
Rekursion
19
ProgrammDemo!
Level ?
TS
Übungen!
20
Übungen: Spirale und Baum
Rekursion
Übungen: Entwickeln Sie zunächst das Grundmuster,
danach die Einstiegspunkte für rekursive Aufrufe.
Vergessen Sie nie die Eintritts-/Abbruchbedingung!
Kopieren Sie das Delphi-Projekt „Rekursion graphisch“
und bauen Sie Ihre Prozeduren dort ein! Testen Sie!
a) spirale(laenge) erzeugt eine „Spirale“ als geknickte Linie
(Winkel jeweils 30°), deren Linienstücke immer kürzer werden.
b) baum(laenge) ähnelt dem Busch,
hat aber als Grundmuster
einen Stamm mit zwei „Knospen“.
TS
21
Übungen: Kochkurve und Hutschnur
Rekursion
c) koch(laenge) erzeugt die berühmte Kochkurve:
Das mittlere Drittel einer Strecke wird durch zwei ebenso lange
Dreieckseiten ersetzt, dies wird dann
auf allen vier Teilstrecken
durchgeführt, und wiederum
auf deren Teilstrecken...
TS
d) hutschnur(laenge) ähnelt der Kochkurve,
ersetzt das mittlere Drittel aber
durch drei Quadratseiten,
und setzt dieses Verfahren
auf allen Teilstrecken fort.
22
Übungen für Spezialisten: Sierpinski und Drachenkurve
Rekursion
e) sierpinski(laenge) erzeugt ein gleichseitiges Dreieck, in dessen
Ecken halb so große Dreiecke sitzen, in deren Ecken wiederum...
TS
f) drache(laenge) erzeugt die berühmte Drachenkurve, die sich aus
einem geknickten Papierstreifen ergibt:
Einen langen Streifen durch Knicken sorgfältig halbieren,
die beiden übereinanderliegenden Teilstreifen wieder Knicken ...
... und am Schluss den gesamten Streifen jeweils mit 90°-Knicks
auseinanderfalten. Am besten macht man es einmal vor!
(Tipp: Verwenden Sie zwei Parameter: drache(laenge, winkel) ,
wobei der winkel die gewünschte Knickrichtung +/- 90° angibt!)
Numerischer Einstieg: Fakultätsfunktion
23
Beispiel 2:
Die Fakultät einer Zahl:
4! = 4• 3•2•1
Rekursion
Rekursion??
TS
=
24
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Test:
3!=?
1!=?
Fakultät: Bildungsgesetz
24
Beispiel 2:
Die Fakultät einer Zahl:
4! = 4• 3•2•1
=
24
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
Rekursion:
TS
5! = 5•
Rekursive Formel: n ! =
4!
???
Test:
3!=6
1!=1
Fakultät: Bildungsgesetz
25
Beispiel 2:
Die Fakultät einer Zahl:
4! = 4• 3•2•1
=
24
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
Rekursion:
TS
5! = 5•
Rekursive Formel: n ! = n •
4!
(n-1) !
Rekursionsschritt
Problem: Was ist 1 ! = ?
Test:
3!=6
1!=1
Fakultät: Bildungsgesetz
26
Beispiel 2:
Die Fakultät einer Zahl:
4! = 4• 3•2•1
=
24
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
Rekursion:
5! = 5•
Rekursive Formel: n ! = n •
4!
(n-1) ! , falls n > 1 ist
Rekursionsschritt
Problem:
Test:
3!=6
1!=1
Rekursionbedingung
1! = 1
Start-/Endwert
Lösung:
Für den Sonderfall n = 1 ist das Teilproblem direkt lösbar,
d.h. bei n = 1 erfolgt kein rekursiver Aufruf mehr!
Beachte: Jeder rekursive Prozess benötigt eine Rekursionbedingung
und einen solchen Start- bzw. Endwert,
sonst gingen die rekursiven Aufrufe ins Endlose!
TS
Rollenspiel!
Fakultät: Berechnung mit rekursivem Abstieg...
27
Beispiel 2:
Die Fakultät einer Zahl:
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
5! = 5• 4!
TS
Phase des
rekursiven
„Abstiegs“
(rekursive Aufrufe)
4 ! = ???
Fakultät: Berechnung mit rekursivem Abstieg...
28
Beispiel 2:
Die Fakultät einer Zahl:
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
5! = 5• 4!
TS
Phase des
rekursiven
„Abstiegs“
(rekursive Aufrufe)
4! = 4• 3!
3! = 3• 2!
2! = 2• 1!
1 ! = .....
Fakultät: Berechnung mit rekursivem Abstieg...
29
Beispiel 2:
Die Fakultät einer Zahl:
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
5! = 5• 4!
TS
Phase des
rekursiven
„Abstiegs“
(rekursive Aufrufe)
4! = 4• 3!
3! = 3• 2!
2! = 2• 1!
1!=1
Fakultät: ... und Aufstieg
30
Beispiel 2:
Die Fakultät einer Zahl:
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
5! = 5• 4!
Phase des
rekursiven
„Abstiegs“
(rekursive Aufrufe)
3! = 3• 2!
2! = 2• 1!
1!=1
Phase des
rekursiven
„Aufstiegs“
(Zusammenbau)
TS
4! = 4• 3!
1
2
Fakultät: ... und Aufstieg
31
Beispiel 2:
Die Fakultät einer Zahl:
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
5! = 5• 4!
Phase des
rekursiven
„Abstiegs“
(rekursive Aufrufe)
4! = 4• 3!
3! = 3• 2!
2! = 2• 1!
1!=1
1
Phase des
rekursiven
„Aufstiegs“
(Zusammenbau)
TS
2
6
Fakultät: ... und Aufstieg
32
Beispiel 2:
Die Fakultät einer Zahl:
5 ! = 5 • 4 • 3 • 2 • 1 = 120
Rekursion
5! = 5• 4!
Phase des
rekursiven
„Abstiegs“
4! = 4• 3!
3! = 3• 2!
2! = 2• 1!
(rekursive Aufrufe)
1!=1
1
Phase des
rekursiven
„Aufstiegs“
2
6
(Zusammenbau)
24
120
TS
Fakultät: Ab- und Aufstieg
33
Beispiel 2:
Die Fakultät einer Zahl:
5 ! = 5 • 4 • 3 • 2 • 1 = 120
5!
= 5 • 4!
Rekursion
= 5 • (4 • 3!)
= 5 • (4 • (3 • 2!))
= 5 • (4 • (3 • (2 • 1!)))
= 5 • (4 • (3 • (2 • (1))))
= 5 • (4 • (3 • (2)))
= 5 • (4 • (6))
= 5 • (24)
= 120
TS
Phase des
rekursiven
„Abstiegs“
(rekursive Aufrufe)
Phase des
rekursiven
„Aufstiegs“
(Rückgabe und
Zusammenbau der
Ergebnisse)
Fibonacci (Bildungsgesetz?)
34
Rekursion
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
TS
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Fibonacci (Bildungsgesetz?)
35
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
TS
fib(2) = 1
fib(3) = 2
fib(...) =
...................
Fibonacci (Bildungsgesetz?)
36
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
TS
fib(2) = 1
fib(3) = 2
fib(6) = 5 + 3 = 8
= fib(5) + fib(4)
Fibonacci (Startproblem!)
37
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
fib(2) = 1
fib(3) = 2
Bildungsgesetz:
TS
fib(6) = 5 + 3 = 8
= fib(5) + fib(4)
aktuelle Zahl = ???
Fibonacci (Startproblem!)
38
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
fib(2) = 1
fib(3) = 2
Bildungsgesetz:
TS
fib(6) = 5 + 3 = 8
= fib(5) + fib(4)
aktuelle Zahl = letzte Zahl + vorletzte Zahl
Fibonacci (Startproblem!)
39
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
fib(2) = 1
fib(3) = 2
Bildungsgesetz:
Rekursive Formel:
TS
fib(6) = 5 + 3 = 8
= fib(5) + fib(4)
aktuelle Zahl = letzte Zahl + vorletzte Zahl
fib(n)
=
fib( ... ) +
fib( ... )
Fibonacci (Startproblem!)
40
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
fib(2) = 1
fib(3) = 2
= fib(5) + fib(4)
Rekursions
-Schritt
Bildungsgesetz:
Rekursive Formel:
TS
fib(6) = 5 + 3 = 8
aktuelle Zahl = letzte Zahl + vorletzte Zahl
fib(n)
=
fib(n-1) +
fib(n-2)
Fibonacci (Startproblem!)
41
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
fib(2) = 1
fib(3) = 2
= fib(5) + fib(4)
Rekursions
-Schritt
Bildungsgesetz:
TS
fib(6) = 5 + 3 = 8
aktuelle Zahl = letzte Zahl + vorletzte Zahl
Rekursive Formel:
fib(n)
=
fib(n-1) +
fib(n-2)
Beachte Problemfall:
fib(1)
=
fib(...)
fib(...) ???
+
Fibonacci (Startproblem!)
42
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
fib(2) = 1
fib(6) = 5 + 3 = 8
fib(3) = 2
= fib(5) + fib(4)
Rekursions
-Schritt
Bildungsgesetz:
aktuelle Zahl = letzte Zahl + vorletzte Zahl
Rekursive Formel:
fib(n)
=
fib(n-1) +
fib(n-2)
Beachte Problemfall:
fib(1)
=
fib(0)
fib(-1) ???
+
 Endlos-Rekursion? Undefiniert? Abhilfe?
TS
Fibonacci (rekursive Formel)
43
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursion
fib(1) = 1
fib(2) = 1
fib(3) = 2
= fib(5) + fib(4)
Rekursions
-Schritt
Bildungsgesetz:
TS
fib(6) = 5 + 3 = 8
aktuelle Zahl = letzte Zahl + vorletzte Zahl
Rekursive Formel:
fib(n)
=
fib(n-1) +
Ausnahme: für n < 3 ist:
fib(n)
=
1
fib(n-2)
Rekursions-Start
bzw. -Ende
Fibonacci (Funktions-Aufbau)
44
Rekursion
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursive Formel:
fib(n)
=
fib(n-1) +
Ausnahme: für n < 3 ist:
fib(n)
=
1
Aufgabe:
Programmiere eine Funktion namens fib, die
zur Eingabe n die zugehörige Fibonacci-Zahl liefert!
Aufbau der
Funktion:
TS
fib(n-2)
Zuweisung des
Rückgabewerts
an den
Funktionsnamen
Funktions- EingabeName parameter
Typ des
Rückgabewerts
function fib(n: integer): integer;
begin
...
fib := ...
...
end;
Fibonacci (Programmierung)
45
Rekursion
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursive Formel:
fib(n)
=
fib(n-1) +
Ausnahme: für n < 3 ist:
fib(n)
=
1
Aufgabe:
Programmiere eine Funktion namens fib, die
zur Eingabe n die zugehörige Fibonacci-Zahl liefert!
RekursionsBedingung
Rekursions
-Schritt
TS
RekursionsAnfang bzw. Ende
fib(n-2)
function fib(n: integer): integer;
begin
if ..... then
.........
else
.........
end;
Fibonacci (Programmierung)
46
Rekursion
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursive Formel:
fib(n)
=
fib(n-1) +
Ausnahme: für n < 3 ist:
fib(n)
=
1
Aufgabe:
Programmiere eine Funktion namens fib, die
zur Eingabe n die zugehörige Fibonacci-Zahl liefert!
RekursionsBedingung
Rekursions
-Schritt
TS
RekursionsAnfang bzw. Ende
fib(n-2)
function fib(n: integer): integer;
begin
if ..... then
fib := fib(n-1) + fib(n-2)
else
.........
end;
Rekursions
rekursive
-Schritt
Aufrufe
Fibonacci (Programmierung)
47
Rekursion
Beispiel 3: Die Fibonacci-Folge beginnt mit den Zahlen
1.
2.
3.
4.
5.
6.
7.
8.
1
1
2
3
5
...
...
...
Rekursive Formel:
fib(n)
=
fib(n-1) +
Ausnahme: für n < 3 ist:
fib(n)
=
1
Aufgabe:
Programmiere eine Funktion namens fib, die
zur Eingabe n die zugehörige Fibonacci-Zahl liefert!
RekursionsBedingung
Rekursions
-Schritt
TS
RekursionsAnfang bzw. Ende
fib(n-2)
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Rekursions
rekursive
-Schritt
Aufrufe
48
Fibonacci (Aufrufstruktur)
Aufruf der Fibonacci-Funktion:
a := fib(6)
Rekursion
fib(5) + fib(4)
TS
........???........
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
49
Aufruf der Fibonacci-Funktion:
a := fib(6)
Rekursion
fib(5) + fib(4)
TS
fib(4) + fib(3)
.................
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
50
Aufruf der Fibonacci-Funktion:
a := fib(6)
Rekursion
fib(5) + fib(4)
fib(4) + fib(3)
fib(3)+fib(2)
.................
TS
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
51
Aufruf der Fibonacci-Funktion:
a := fib(6)
Rekursion
fib(5) + fib(4)
fib(4) + fib(3)
fib(3)+fib(2)
fib(2)+fib(1)
......
TS
......
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
52
Aufruf der Fibonacci-Funktion:
a := fib(6)
Rekursion
fib(5) + fib(4)
fib(4) + fib(3)
fib(3)+fib(2)
fib(2)+fib(1)
1
TS
......
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
53
Aufruf der Fibonacci-Funktion:
a := fib(6)
Rekursion
fib(5) + fib(4)
fib(4) + fib(3)
fib(3)+fib(2)
2
fib(2)+fib(1)
1
TS
1
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
54
Aufruf der Fibonacci-Funktion:
a := fib(6)
Rekursion
fib(5) + fib(4)
fib(4) + fib(3)
3
fib(3)+fib(2)
2
fib(2)+fib(1) 1
1
TS
1
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
55
Aufruf der Fibonacci-Funktion:
a := fib(6)
Rekursion
fib(5) + fib(4)
fib(4) + fib(3)
2
3
fib(3)+fib(2) fib(2)+fib(1)
2
fib(2)+fib(1) 1
1
TS
1
1
1
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
56
Aufruf der Fibonacci-Funktion:
a := fib(6)
fib(5) + fib(4)
Rekursion
5
fib(4) + fib(3)
2
3
fib(3)+fib(2) fib(2)+fib(1)
2
fib(2)+fib(1) 1
1
TS
1
1
1
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Fibonacci (Aufrufstruktur)
57
Aufruf der Fibonacci-Funktion:
a := fib(6)
fib(5) + fib(4)
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Rekursion
5
................
fib(4) + fib(3)
2
3
fib(3)+fib(2) fib(2)+fib(1)
2
fib(2)+fib(1) 1
1
TS
1
1
1
Fibonacci (Aufrufstruktur)
58
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1) + fib(n-2)
else
fib := 1
end;
Aufruf der Fibonacci-Funktion:
a := fib(6)
fib(5) + fib(4)
Rekursion
5
Beachte:
3
fib(4) + fib(3)
2
3
Verzweigungsfaktor?
2
fib(3)+fib(2) fib(2)+fib(1)
fib(2)+fib(1)
2
fib(2)+fib(1) 1
1
TS
1
1
Aufrufstruktur?
fib(3) + fib(2)
1
1
1
1
Komplexität?
Fibonacci (Aufrufstruktur)
59
function fib(n: integer): integer;
begin
if n > 2 then
fib := fib(n-1)+ fib(n-2)
else
fib := 1
end;
Aufruf der Fibonacci-Funktion:
a := fib(6)
fib(5) + fib(4)
Rekursion
5
Beachte:
3
fib(3) + fib(2)
fib(4) + fib(3)
2
3
2
fib(3)+fib(2) fib(2)+fib(1)
fib(2)+fib(1)
2
fib(2)+fib(1) 1
1
1
1
1
1
1
1
Durch den zweifachen
rekursiven Aufruf
von fib entsteht
eine (unvollständige)
Baumstruktur mit
2-facher Verzweigung!
Eine Vergrößerung von n
bedeutet daher fast
doppelten Aufwand,
d.h. die Komplexität
n
liegt bei etwa 2 .
n
(asymptotisch: 1,618 )
TS
60
Aufgaben (numerisch)
Aufgaben: Entwickeln und testen Sie Funktionen:
a) fak zur rekursiven Berechnung der Fakultät einer Zahl
Rekursion
b) summe_1_bis_n zur Berechnung von 1+2+3+...+n
(Tipp: Kopieren und ändern Sie fak entsprechend!)
c) fib zur rekursiven Berechnung der Fibonaccizahl
d) Bauen Sie bei fib einen Aufrufzähler (globale Variable! warum?)
ein, der bei jedem Aufruf von fib inkrementiert wird!
e) Zum Vergleich: Programmieren Sie fakiter und fibiter zur iterativen
Berechnung von fak und fib, d.h. mit Schleifen anstatt Rekursion!
TS
61
Aufgabe: Binomialkoeffizienten
f) Eine Funktion mit zwei Eingabewerten:
n
Rekursion
bin(n,k) dient zur Berechnung von Binomialkoeffizienten ( k )
anhand des Pascalschen Dreiecks:
???
???
TS
62
Aufgabe: Binomialkoeffizienten
f) Eine Funktion mit zwei Eingabewerten:
n
Rekursion
bin(n,k) dient zur Berechnung von Binomialkoeffizienten ( k )
anhand des Pascalschen Dreiecks:
TS
Aufgabe: Permutationen
63
g) Buchstabenrätsel: ZUES = ???
Eine Prozedur soll systematisch alle Permutationen erzeugen!
Strategie:
Rekursion
Z+
perm(UES)
U+
perm(ZES)
E+
perm(ZUS)
S+
perm(ZUE)
...
...
...
ZU +
perm(ES)
ZUE +
perm(S)
ZUES
TS
perm(ZUES)
ZE +
perm(US)
ZUS +
perm(E)
ZUSE
ZEU +
perm(S)
ZEUS
ZS +
perm(UE)
ZES +
perm(U)
ZESU
ZSU +
perm(E)
ZSUE
ZSE +
perm(U)
ZSEU
Tipp: Verwenden Sie zwei Parameter : perm(kopf,rest : string)
und den Startaufruf perm(‘‘ , ‘ZUES‘).
restlicher Teil
bereits permutierter Teil
Aufgabe: Ackermann-Funktion
64
h) Ein Beispiel für verschachtelte Rekursion:
Rekursion
Die Ackermann-Funktion hat 2 Eingabewerte x und y,
und wächst extrem schnell!
a(x,y) =
y+1
, falls x = 0
a(x-1,1)
, falls x  0 und y = 0
a(x-1, a(x, y-1)) , sonst
Berechne „per Hand“ a(1,1) und a(2, 2) .
Programmiere und teste a !
(Für theoretische Informatiker: Die Ackermann-Funktion ist zwar
berechenbar, aber nicht primitiv-rekursiv... )
TS
Aufgabe: universelle Funktion
65
i) Die universelle Funktion f (x, y, a) kann verschiedene
Funktionen berechnen.
Rekursion
x und y sind die beiden Eingabewerte, und mit a bestimmt man:
a = 1:
a = 2:
a = 3:
a > 3:
Addieren
Multiplizieren
Potenzieren
???
x + y , falls a = 1
f (x,y,a) =
x,
falls a  1 und y = 1
f (x, f (x, y-1, a), a-1) , sonst
Berechne „per Hand“ f(4, 3, 2) und f( 2, 3, 3) .
Programmiere und teste f !
TS
Aufgabe: Türme von Hanoi
66
Rekursion
j) Bei den „Türmen von Hanoi“ muss ein Stapel von goldenen
Scheiben von einem Startplatz auf einen Zielplatz bewegt werden.
Zum Manövrieren gibt es noch einen Ablageplatz, denn es darf
niemals eine größere auf eine kleinere Scheibe gelegt werden.
Start (1)
Ablage (2)
Ziel (3)
Suchen Sie zunächst das rekursive Prinzip, um das Problem
„Bewege einen Turm der Höhe n“ auf ein kleineres Problem zu
reduzieren!
Entwickeln Sie dann eine rekursive Prozedur
hanoi(hoehe, von, nach: integer) ,
die eine Ausgabe wie z.B. nebenstehend erzeugt!
TS
(Ein praktischer Trick: 1+2+3 = 6, d.h. die Formel für eine Platznummer
lautet immer: „6 – die beiden anderen Platznummern“ . Hilft das ?!)
Sammlung rekursiver Probleme
67
Rekursion
Eine kleine Sammlung rekursiv lösbarer Probleme:
Numerisch:
Fakultät, Summe-1-bis-n, Potenz, Fibonacci,
Binomialkoeffizienten (Pascalsches Dreieck),
universelle Funktion, Ackermann
Graphisch:
Spirale, Busch, Baum, Kochkurve (Schneeflocke),
Hutschnur, Drachenkurve (Papierfaltung),
Sierpinski-Dreieck/-Quadrat, Peano-Kurve,
Cantor-Staub (zerstückelte Strecke)
Textuell:
Spiegelung,
Permutationen (Buchstabenrätsel),
Formale Sprache (Erzeugung anhand Grammatik)
Spiel:
Zahlenraten, Türme von Hanoi
Backtracking:
Labyrinth, Acht-Damen- / Springer-Problem,
Solitaire (Nimm-Spiel), Spielstrategien
Suchen und Sortieren: binäre Suche, Quicksort, Mergesort
TS
Methodische Zugänge
68
• Problemanalyse: Zerlegung in ähnliche Teilaufgaben
• Code-orientiert: a) „Was tut dieses Programm?“
b) Code mit „Auskunftsfunktion“: bei jedem Aufruf
wird dieser inkl. aktueller Parameter ausgegeben
Rekursion
c) Einbau eines Aufruf-Zählers (globale Variable)
• Gegenständlich: verschachtelte Kartons oder Matrioschkas
(im Innern liegt ein Schatz: nacheinander alle
öffnen und danach alle wieder schließen),
Papierstreifen falten (Faltrichtung beachten!)
• Rollenspiel:
Für jeden Aufruf kommt ein weiterer Spieler
auf die Bühne, der „seine“ Arbeit demonstriert
und ggf. weitere Spieler aufruft. Evtl. Tafelprotokoll.
Hilfe: Vorbereitete Aufruf-/Aufgabenzettel.
• Visualisierungen: a) Aufrufstruktur mit rekursivem Ab- und Aufstieg
TS
b) Entwicklung des Aufruf-Stapels („stacks“):
Aufbau und Abbau (dynamisches Tafelbild)
69
Rekursion versus Iteration: Bsp. Fakultät
Rekursion
rekursiv
function fak(n: integer): integer;
begin
if n > 1 then
fak := n  fak(n-1)
else
fak := 1;
end;
Benötigt wird intern ein Stack,
um die „unfertigen“ Aufrufe
zu speichern.
iterativ
function fak(n: integer): integer;
var f, i: integer;
begin
f := 1;
for i := 2 to n do
f := f  i;
fak := f;
end;
Benötigt werden hier zwei Variablen:
i als Laufvariable für die Schleife, und
f als Variable für das Zwischenergebnis,
da die „Funktionsvariable“ fak
nur auf der linken Seite einer Zuweisung
benutzt werden darf!
(rechts: rekursiver Aufruf!!)
TS
70
Vor- und Nachteile von Rekursion
Rekursion
Rekursion – pro und contra:
+ mächtige Methode der Problemzerlegung
+ elegante „deklarative“ Formulierung der Lösung
+ flexibel bezüglich der Problemgröße
(keine festgelegten Schleifenanzahlen, z.B. bei Permutationen, n-Damen)
- nicht sofort zu durchschauen
- evtl. unnötig hoher Zeitbedarf
(exponentielle Komplexität bei Mehrfachrekursion)
(wiederholtes Berechnen von Zwischenergebnissen, z.B. bei fib )
(interner Verwaltungsaufwand: Stack mit begrenzter Größe)
TS
Literaturverzeichnis und Links
71
Quicksort:
Baumann: Informatik für die Sekundarstufe II, Band 2
MUI-Sprache (MU-Problem): Hofstadter: Gödel, Escher, Bach (dtv 1991)
Rekursion ETH:
http://www.ite.ethz.ch/education/id1/vortraege/rekursion.pdf
Downloads (Word, PDF) zu
"Rekursives Programmieren": http://educeth.ethz.ch/informatik/leitprog/rekursion
http://educeth.ethz.ch/informatik/vortraege/backtracking
Rekursion
Backtracking anschaulich:
Über Fragen, Hinweise, Korrekturen würde ich mich freuen:
[email protected]
TS
Herunterladen