Einführung in die Rekursion - Chair of Software Engineering

Werbung
1
4
Einführung in die Programmierung
Chiang
Mai
Bertrand Meyer
Letzte Aktualisierung: 15. Dezember 2003
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
Intro – Lecture 16
2
5
Vorlesung 16:
Einführung in die Rekursion
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
Intro – Lecture 16
3
Chair of Software Engineering
Intro – Lecture 16
6
Chair of Software Engineering
Intro – Lecture 16
1
7
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
APSEC 2003
10
Intro – Lecture 16
8
11
Asia-Pacific Software Engineering Conference
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
Intro – Lecture 16
9
12
Vorlesung 16:
Einführung in die Rekursion
Chair of Software Engineering
Intro – Lecture 16
Chair of Software Engineering
Intro – Lecture 16
2
Die Geschichte des Universums*
13
*Gemäss Édouard Lucas, Récréations mathématiques, Paris, 1883
Dans le grand temple de Bénarès, sous le dôme qui marque le
centre du monde, repose un socle de cuivre équipé de trois
aiguilles verticales en diamant de 50 cm de haut.
A la création, Dieu enfila 64 plateaux en or pur sur une des
aiguilles, le plus grand en bas et les autres de plus en plus petits.
C'est la tour de Brahmâ.
Les moines doivent continûment déplacer les disques de manière
que ceux-ci se retrouvent dans la même configuration sur une
autre aiguille.
La règle de Brahmâ est simple: un seul disque à la fois et jamais
un grand plateau sur un plus petit.
Daraus resultiert ein Algorithmus
16
move (n: INTEGER;
source, target, other: CHARACTER) is
-- Move n disks from needle source to target,
-- using other as storage.
do
if n > 0 then
move (n−1, source, other, target)
transfer (source, target)
move (n−1, other, target, source)
end
end
Arrivé à ce résultat, le monde tombera en poussière et disparaîtra.
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
Die Geschichte des Universums*
14
Intro – Lecture 16
Der Begriff “Rekursion”
17
*Gemäss Édouard Lucas, Récréations mathématiques, Paris, 1883
In the great temple of Benares, under the dome that marks the
center of the world, three diamond needles, a foot and a half high,
stand on a copper base.
God on creation strung 64 plates of pure gold on one of the
needles, the largest plate at the bottom and the others ever
smaller on top of each other. That is the tower of Brahmâ.
The monks must continuously move the plates until they will be
set in the same configuration on another needle.
Eine Definition für ein Konzept ist rekursiv,
wenn sie eine Instanz des Konzeptes selbst
beinhaltet.
Bemerkungen:
The rule of Brahmâ is simple: only one plate at a time, and never
a larger plate on a smaller one.
• Die Definition kann mehr als eine “Instanz des
Konzeptes selbst” benutzen.
When they reach that goal, the world will crumble into dust and
disappear.
• Rekursion ist die Benutzung einer rekursiven
Definition.
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
Wie viele Schritte?
15
Intro – Lecture 16
Beispiele
18
Beispiel: n Scheiben (n ≥ 0); drei Nadeln mit source, target und
other bezeichnet.
ƒ Rekursive Routinen
Die grösste Scheibe kann nur dann von source nach target bewegt
werden, wenn target leer ist; deshalb müssen alle anderen
Scheiben auf other liegen.
ƒ Rekursive Grammatiken
Deshalb ist die minimale Anzahl der Bewegungen für jede Lösung:
Move n−1 from
source to other
Move largest from
source to target
Hn = Hn−1 + 1 + Hn−1
= 2 * Hn−1 + 1
Chair of Software Engineering
Move n−1 from
other to target
ƒ Rekursiv definierte Programm-Konzepte
ƒ Rekursive Datenstrukturen
Da Hn = 1, impliziert dies:
Hn = 2n − 1
Intro – Lecture 16
Chair of Software Engineering
Intro – Lecture 16
3
19
Rekursive Grammatik
22
Instruction = Assignment | Conditional | Compound | ...
Conditional =
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
Rekursive Routine
20
ƒ Direkte Rekursion: Rumpf beinhaltet einen Aufruf
der Routine selbst.
Lexikographische Ordnung definieren
23
Konventionen:
ƒ Ein Wort ist eine Sequenz von Null oder mehreren
Buchstaben.
ƒ Ein Buchstabe ist eines von:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ƒ Für beliebige zwei Buchstaben ist bekannt, welcher der
beiden “kleiner” ist; die Ordnung ist die der vorherigen
Liste.
Chair of Software Engineering
Intro – Lecture 16
Rekursion kann indirekt sein
Intro – Lecture 16
Problem: Definiere, dass das Wort w1 “vor” dem
Wort w2 ist, gemäss der lexikographischen Ordnung.
ƒ Beispiel: Routine move der vorherigen Lösung des
Problems “Türme von Hanoi”.
Chair of Software Engineering
if Expression then Instruction
else Instruction end
21
Intro – Lecture 16
Beispiele
ƒ Routine r beinhaltet einen Aufruf der Routine s
ƒ ABC vor DEF
ƒ s beinhaltet einen Aufruf von r
ƒ AB vor DEF
ƒ Allgemein: r1 ruft r2 ruft ... ruft rn ruft r1.
ƒ Leeres Wort vor ABC
24
ƒ A vor AB
ƒ A vor ABC
Chair of Software Engineering
Intro – Lecture 16
Chair of Software Engineering
Intro – Lecture 16
4
Eine rekursive Definition
Das Wort w1 ist nur dann “vor” dem Wort w2, wenn
eine der folgenden Bedingungen zutrifft:
Ein binärer Baum über einer
sortierte Menge G ist ein binärer
Suchbaum, wenn für jeder Knoten
n gilt:
ƒ Für jeden Knoten x des linken
Teilbaums n, x.item ≤ n.item
ƒ Weder w1 noch w2 sind leer, und der erste
Buchstabe von w1 ist kleiner als der erste
Buchstabe von w2 .
ƒ Weder w1 noch w2 sind leer, die ersten
Buchstaben sind die gleichen, und das Wort, das
durch Entfernen des ersten Buchstabens von w1
entsteht, ist (rekursiv) vor dem Wort, das durch
Entfernen des ersten Buchstabens von w2
entsteht.
sort is
do
11
51
left
29
-- Print element values in order
if left /= Void then left.sort end
if right /= Void then right.sort end
end
59
end
Chair of Software Engineering
Intro – Lecture 16
class BINARY_TREE [G] feature
item: G
Intro – Lecture 16
Suchen in einem binären Suchbaum
27
30
class BINARY_SEARCH_TREE [G ...] feature
item: G
left, right: BINARY_SEARCH_TREE [G]
right: BINARY_SEARCH_TREE [G]
left: BINARY_TREE [G]
right: BINARY_TREE [G]
... Insertion and deletion features ...
end
end
Intro – Lecture 16
Intro – Lecture 16
print (item)
Binärer Baum Klassen-Skelett
Chair of Software Engineering
59
68
Right
Chair of Software Engineering
51
class BINARY_SEARCH_TREE [G ...] feature
item: G
left, right: BINARY_SEARCH_TREE [G]
right: BINARY_SEARCH_TREE [G]
72
20
11
Ausdrucken von Elementen in
Reihenfolge
26
32
Ein binärer Baum über G ist entweder:
ƒ Leer
oder
ƒ Ein Knoten, bestehend aus drei
Elementen:
ƒ Wert von Typ G
ƒ Binärer Baum über G,
genannt linkes Kind
des Knotens
ƒ Binärer Baum über G,
genannt rechtes Kind
des Knotens
72
20
68
Chair of Software Engineering
G ist ein beliebiger Typ.
32
ƒ Für jeden Knoten x des
rechten Teilbaums n,
x.item ≥ n.item
Intro – Lecture 16
Rekursive Datenstrukturen
28
Ein binärer Baum hat einen linken
Teilbaum und einen rechten
Teilbaum.
ƒ w1 ist leer und w2 ist nicht leer.
Chair of Software Engineering
Binäre Suchbäume
25
has (x: G): BOOLEAN is
-- Does a node in this subtree have value x?
do
if x < item then
Result := ((left /= Void) and then left.has (x))
elseif x > item then
Result := (right /= Void) and then right.has (x)
else
Result := True
end
end
Chair of Software Engineering
Intro – Lecture 16
5
Einfügen in einen binären Suchbaum
ƒ Lösen sie dies als Übung!
Chair of Software Engineering
34
move (n: INTEGER;
source, target, other: CHARACTER) is
-- Move n disks from needle source to target,
-- using other as storage.
do
if n > 0 then
move (n−1, source, other, target)
transfer (source, target)
move (n−1, other, target, source)
end
end
Chair of Software Engineering
Intro – Lecture 16
Warum binäre Suchbäume?
Hanoi: Was ist die Variante?
31
Intro – Lecture 16
Ausdrucken: Was ist die Variante?
32
35
class BINARY_SEARCH_TREE [G ...] feature
item: G
left, right: BINARY_SEARCH_TREE [G]
right: BINARY_SEARCH_TREE [G]
ƒ Lineare Strukturen: Einfügen, Suchen und
Löschen sind O (n).
ƒ Binäre Suchbäume: Durchschnittliches
Verhalten für Einfügen, Suchen und Löschen ist
O (log (n)).
sort is
do
ƒ Aber: Worst-time Verhalten ist O (n)!
-- Print element values in order
if left /= Void then left.sort end
print (item)
Beachte die Messung der Komplexität: best case,
average, worst case.
if right /= Void then right.sort end
end
end
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
Generelle Zuverlässigkeitseigenschaften
Damit eine rekursive Definition Sinn macht:
33
Intro – Lecture 16
McCarthy’s 91 Funktion
M (n) =
ƒ Es muss einen nicht-rekursiven Zweig geben!
ƒ n − 10
if n > 100
ƒ Eine nicht-negative Zahl — die Variante der
Rekursion — muss bei jedem Aufruf niedriger
werden.
ƒ M (M (n + 11))
if n ≤ 100
Chair of Software Engineering
Intro – Lecture 16
36
Chair of Software Engineering
Intro – Lecture 16
6
Eine andere Funktion
37
bizarre (n) =
ƒ 1
if n = 1
ƒ bizarre (n / 2)
Unser Original-Beispiel für eine Schleife
if n is even
ƒ bizarre ((3 ∗ n + 1) / 2) if n > 1 and n is odd
1
count
start
Chair of Software Engineering
Chair of Software Engineering
Intro – Lecture 16
Fibonacci Zahlen
38
ƒ fib (1) = 0
ƒ fib (2) = 1
ƒ fib (n) = fib (n−2) + fib (n−1)
Chair of Software Engineering
ƒ n! = n * (n − 1)!
for n > 0
Die Rekursive Definition ist nur für Demonstrationszwecke interessant; praktische Implementationen
werden Schleifen (oder Tabellen) anwenden.
Intro – Lecture 16
Ein rekursives Equivalent
Chair of Software Engineering
Intro – Lecture 16
ƒ 0! = 1
forth
41
highest_name: STRING is
-- Alphabetically greatest station name
-- of line f
require
not f.is_empty
do
f.start
Result := f.highest_from_cursor
end
for n > 2
Fakultätsfunktion
40
highest_name: STRING is
-- Alphabetically greatest station name of line f
do
from
f.start ; Result := ""
until
f.after
loop
Result := greater (Result, f.item.name)
f.forth
before
after
end
item
end
39
Intro – Lecture 16
Hilfsfunktion für Rekursion
highest_from_cursor: STRING is
-- Alphabetically greatest name of stations of
-- line f starting at current cursor position
require
f /= Void; not f.off
do
Result := f.item.name
f.forth
if not f.after then
Result := greater (Result, highest_from_cursor)
end
item
end
1
42
after
count
forth
Chair of Software Engineering
Intro – Lecture 16
Chair of Software Engineering
Intro – Lecture 16
7
Schleifen-Version mit Argumenten
43
maximum (a: ARRAY [STRING]): STRING is
-- Alphabetically greatest item in a
require
a.count >= 1
local
i: INTEGER
do
from
i := a.lower + 1; Result := a.item (a.lower)
invariant
i > a.lower ; i <= a.upper + 1
-- Result is the maximum element of a [a.lower .. i−1]
until
i > a.upper
loop
if a.item (i) > Result then Result := a.item (i) end
i := i + 1
end
end
Chair of Software Engineering
x := x’
goto start_of_r
... Some instructions ...
r (x’)
... More instructions ...
Nach Aufruf Zurückgreifen auf vorherige Werte der
Argumente und andere Kontextinformationen
notwendig.
Chair of Software Engineering
44
Intro – Lecture 16
Verwendung eines Stapels
Abfragen:
ƒ Ist der Stapel leer? is_empty
ƒ Oberstes Element, wenn eines:
item
max_sub_array (a: ARRAY [STRING]; i: INTEGER): STRING is
-- Alphabetically greatest item in a starting from index i
require
i >= a.lower ; i <= a.upper
do
Result := a.item (i)
if i < a.upper then
Result := greater (Result, max_sub_array (a, i + 1))
end
end
Kommandos:
ƒ Lege ein Element an die Spitze:
put
ƒ Greife oberstes Element, wenn
überhaupt eines: remove
Chair of Software Engineering
Intro – Lecture 16
Rekursions-Elimination
ƒ Rekursive Aufrufe verursachen (in einer DefaultImplementation ohne Optimierung) eine LaufzeitEinbusse: Verwaltung eines Stapels für die
aufbewahrten Werte notwendig.
ƒ Verschiedene Optimierungen sind möglich.
-- e.g. r (x–1)
end
maxrec (a: ARRAY [STRING]): STRING is
-- Alphabetically greatest item in a
require
a.count >= 1
do
Result := max_sub_array (a, a.lower)
end
Chair of Software Engineering
46
r (x) is
do
May need x!
Intro – Lecture 16
Rekursive Version
Rekursions-Elimination
45
47
“Top” position
Intro – Lecture 16
Rekursion als eine Problem lösende
Technik
48
ƒ Anwendbar — wenn man eine Möglichkeit
hat, eine Lösung für ein Problem zu
konstruieren — auf eine gewisse
Inputmenge von Lösungen für eine oder
mehrere kleinere Inputmengen.
ƒ Manchmal kann eine Rekursion durch eine Schleife
ersetzt werden; dies wird als Rekursions-Elimination
bezeichnet.
ƒ
“Tail recursion” (letzte Anweisung einer Routine ist ein
rekursiver Aufruf) kann gewöhnlich eliminiert werden.
Chair of Software Engineering
Intro – Lecture 16
Chair of Software Engineering
Intro – Lecture 16
8
Dank an...
49
ƒ Fromageries Bel (La Vache qui rit)
ƒ Yao Volksstamm
ƒ Swiss
ƒ Verschiedene andere Elefanten
ƒ Thailändische Regierung
Chair of Software Engineering
Intro – Lecture 16
50
Ende Vorlesung 16
Chair of Software Engineering
Intro – Lecture 16
9
Herunterladen