Iteration und Rekursion - Das mp3

Werbung
Iteration und Rekursion
Unter einer Iteration versteht man einen Algorithmus mit der Eigenschaft, einen Eingabewert
x (zuerst einen Anfangswertes x(0) ) gemäß einer Funktion f(x) in einen Ausgabewert y
umzuwandeln und diesen stets wieder als nächsten input einzugeben.
Mit Bezug auf die Abbildung könnte man also ganz einfach sagen: Alles, was aus dem
(gelben) Block als output herauskommt, wird sogleich wieder als nächster input in ihn
eingegeben. Für x kann man deshalb auch x(n) schreiben und für y jeweils x(n+1). Die
einzelnen Schritte dieses Prozesses nennt man gleichfalls Iterationen. So würde etwa bei der
fünften Iteration der Eingabewert x(5) in den Ausgabewert x(5+1) umgewandelt, der dann als
x(6) wieder eingegeben wird. Der Iterationsprozess kann entweder unendlich weiter laufen
oder beendet werden, entweder wenn eine vorgegebene Schrittzahl n bzw. ein vorgegebener
Wert x(max) erreicht wurde oder wenn die Funktion f nicht mehr ausgeführt werden kann
(zum Beispiel weil dies eine Division durch Null bedeutet würde).
Rekursion ist demgegenüber etwa ganz anderes. Eine Funktion F (oder ein entsprechender
Algorithmus) heißt rekursiv, wenn sie sich zu ihrer Durchführung ein Mal oder mehrfach
selbst aufruft. Das klingt kompliziert, ist aber nicht allzu schwer zu verstehen.
Wenn man zum Beispiel ein Computerprogramm für einen Algorithmus schreiben will, der
eine eingegebene Zahl Z auf Primeigenschaft prüft (also entscheidet, ob die Eingabezahl Z
eine Primzahl ist oder nicht), so kann man den Rechner natürlich anweisen, der Reihe nach
für jede natürliche Zahl N – angefangen mit 2 bis hin zur Hälfte von Z – zu prüfen, ob Z
durch das jeweilige N teilbar ist. Aber dies wäre viel zu umständlich und würde unnötig lange
dauern, denn wenn zum Beispiel Z nicht durch 2 teilbar war, dann brauchte das Programm
nicht mehr zu prüfen, ob Z durch irgendeine andere gerade Zahl teilbar ist. Hat es festgestellt,
dass Z nicht ohne Rest durch 3 teilbar ist, dann steht damit auch fest, dass Z auch nicht durch
irgendeine Zahl N, die ein Vielfaches von 3 ist, geteilt werden kann. Eine erhebliche
Vereinfachung des Programms liefe also darauf hinaus, nur die Teilbarkeit von Z durch
Zahlen zu prüfen, die selber Primzahlen sind. Also müsste der Algorithmus, der ja eine Zahl
auf Primeigenschaft prüfen soll, jeden in Betracht gezogenen Teiler selbst erst auf
Primeigenschaft prüfen, das heißt sich selbst – rekursiv – darauf anwenden.
Bei den Fibonacci-Zahlen (siehe Materialien zur 1. Vorlesung) verhält es sich ganz ähnlich:
In der nachstehenden Abbildung sieht man zwei Grundmuster (oder Diagramme), bezeichnet
als (a) und (c): ein Algorithmus, der ein geometrisches Muster wie (a) mit den entsprechenden
Linien und Knoten erzeugt, ist leicht zu programmieren. (Vgl. hierzu die Ausführungen über
Turtle-Grafiken und L-Systeme in den Materialien 2 zur 4. Vorlesung)
Dort, wo in der Abb. (a) ein G steht, soll der Algorithmus eine genaue Kopie des Musters (a)
anfügen, also ein Muster, zu dessen Erzeugung er sich selbst aufrufen muss:
Auf diese Weise stellt er das Muster (b) her. Bei diesem könnte jetzt wiederum überall dort,
wo ein G steht, das Gleiche geschehen. (Das Muster (c) illustriert das gleiche, nur für eine
andere Ausgangsfigur).
Die vorstehende Abbildung (aus HOFSTADTER 1985) zeigt, wie sich aus dem Anfangsmuster
(a) durch die beschriebenen Erweiterungen ein sog. Baum erzeugen lässt, der, wenn man die
Knoten von unten nach oben durchnumeriert, an seinem rechten Rand die Fibonacci-Zahlen
aufführt. Demzufolge müssten sich die Fibonacci-Zahlen gleichfalls durch einen rekursiven
Algorithmus – hier als RTN (für Rekursives Transitions-Netzwerk oder recursive transition
network) erzeugen lassen. Das RTN-Diagramm von HOFSTADTER (seine Abb. 31) zeigt, wie
dies geschehen kann. (Links einzugeben ist FIBO(n) )
Etwas ganz Ähnliches zeigt – auf der vorstehenden Seite – die sogenannte HILBERT-Kurve. Das
unvollständige Quadrat oben links ist die Hilbert-Kurve 1. Ordnung, also die Grundfigur, genannt das
Axiom X. Die Figur oben rechts (die Kurve 2. Ordnung) entsteht aus vier (verkleinerten) Kopien
dieser Grundfigur, die jedoch noch durch eine zusätzliche Linie (Y) verbunden und nach dem
zugrundeliegenden Algorithmus auf bestimmte Weise in der Ebene gedreht werden (–). Wer die
Ausführungen über L-Systeme gelesen hat (in denen bereits ähnliche Kurven, z.B. die Koch-, die
Drachen- oder die Sierpinski-Kurve gezeigt wurden), sollte verstehen können, wie die Anweisung (die
unter den Kurven 5. und 6. Ordnung steht) aufzufassen und auszuführen ist.
Der Ausdruck „Kurve“ könnte hier etwas verwirren: die Hilbert-Kurve zeigt ja keinerlei
„Krümmung“; stattdessen füllt sie zunehmend die Ebene aus, je höher ihre Ordnung ist, was zu der
Frage führt, ob sie ein eindimensionales Gebilde ist – wie normale Kurven sonst – oder schon eher ein
zweidimensionales. Tatsächlich ist ihre Dimension eine gebrochene Zahl (engl. fraction), weshalb es
sich hier um ein Gebilde der sog. fraktalen Geometrie handelt.
Die Kurven vieler rekursiven Funktionen weisen oft noch ganz andere verblüffende Eigenschaften auf.
Als Beispiel diene der Graph (die Kurve) der von Hostadter (a.a.O., p. 150) erörterten Funktion
INT(x):
Diese diskontinuierliche – und fraktale – Kurve besteht bis in ihre unendliche Tiefe hinein nur
aus Kopien ihrer selbst. Man könnte ein beliebiges Teilstück davon, sei es auch noch so
winzig, herausvergrößern (zoomen) und erhielte eine vollständige Kopie des Bildes, das man
oben vor sich sieht. In der fraktalen Geometrie bezeichnet man diese Eigenschaft als
Selbstähnlichkeit. Diese ist uns übrigens auch von Blumenkohl oder Broccoli bekannt: bricht
man aus einem Kopf Blumenkohl ein Röschen heraus, so gleicht dessen Gestalt weitgehend
dem Ganzen.
Diese Eigenschaft weist auch die Graphik auf der folgenden Seite auf: sie stellt eine sog.
Julia-Menge dar, die einer spezifischen Koordinate der Mandelbrot-Menge (weithin
inzwischen auch als „Apfelmännchen bekannt) entspricht.
Auf der folgenden Seite sieht man den Auszug aus einem BASIC-Programm zur Erzeugung
der Hilbert-Kurve: Hier kann man besonders gut erkennen, wie der Algorithmus
gewissermaßen ineinander verschachtelt wird und die Berechnung für jede Ordnungsstufe
durch den Befehl GOSUB auf die Berechnung der nächstniederen zurückgreift.
In der Mengentheorie, in der mathematischen Logik und in der Automatentheorie hat der
Ausdruck rekursiv jedoch noch eine andere Bedeutung, die mit der zuvor erläuterten nicht
verwandt ist.
Um die Eigenschaften eines logischen Systems, also eines Kalküls, zu untersuchen, ist es
besonders beliebt, die Theoreme dieses Kalküls (das könnten Sätze sein oder auch nur
Zeichenfolgen – strings –, wie sie hier bereits früher betrachtet wurden) sozusagen einfach zu
nummerieren, genauer: sie eineindeutig (also eins zu eins) auf die Menge N der natürlichen
Zahlen abzubilden (wobei die Einzelheiten der Zuordnung hier nicht von Bedeutung sind) und
hernach die gewünschten strukturellen Untersuchungen an den Beziehungen zwischen den
jeweiligen Zahlen durchzuführen. Der Vorteil besteht darin, dass die Strukturen der
natürlichen Zahlen außerordentlich gut bekannt und übersichtlich sind. Vor allem aber können
die natürlichen Zahlen ebenso wie die Elemente vieler ihrer Teilmengen – z.B. die geraden
Zahlen, die Primzahlen usw. – stets durch einen Algorithmus (oder, wenn man lieber will;
durch eine „Maschine“) erzeugt werden.
Eine Menge P, die sich durch einen Algorithmus erzeugen lässt, welcher die Elemente von P
eines um das andere (vielleicht mit Wiederholungen) generiert, bezeichnet man als rekursiv
aufzählbar (recursively enumarable) *
Die Menge N der natürlichen Zahlen ist rekursiv aufzählbar, ebenso – als Teilmengen davon –
die Menge der geraden Zahlen :
die Menge der Quadratzahlen:
die Menge der Primzahlen:
die Menge der Fibonacci-Zahlen
0, 2, 4, 6, 8, 10, ..... 
0, 1, 4, 9, 16, 32 .... 
2, 3, 5, 7, 11, 13.... 
1, 1, 2, 3, 5, 8, 13, .. usw.
Auch die Komplementärmengen dazu, welche alle in der jeweiligen Teilmenge nicht
enthaltenen Elemente enthalten, sind rekursiv aufzählbar, z. B. für die ersten beiden Fälle
1, 3, 5, 7, 9, 11.... als Komplementärmenge der geraden Zahlen (= also die der
ungeraden) oder
2, 3, 5, 6, 7, 8, 10.. als Komplementärmenge der Quadratzahlen,
weil auch zur Erzeugung dieser Elemente ein Algorithmus existiert. Für die Menge N der
natürlichen Zahlen kann man sogar einen Algorithmus angeben, der entscheidet, ob ein
vorgegebenes Element z. B. zur Teilmenge der Primzahlen, der Kubikzahlen usw. oder zur
jeweiligen Komplementärmenge gehört.
Eine Menge R mit der Eigenschaft, dass sowohl sie selbst als auch ihre Komplementärmenge
rekursiv aufzählbar sind, heißt eine rekursive Menge.
Die Komplementärmenge einer rekursiven Menge ist gleichfalls eine rekursive Menge.
Nun stellt sich ein scheinbar ganz exotisches Problem: Gibt es Mengen, die rekursiv
aufzählbar, aber nicht rekursiv sind?
Als wir (siehe Materialien 1 zur 4. Vorlesung) erläutert haben, was ein Kalkül ist, haben wir
auch den Unterschied zwischen einem Theorem und einem Non-Theorem erklärt: ein
*
„Aufzählbar“ (enumerable) ist nicht das Gleiche wie „abzählbar“ (coutable)! Mathematiker sind da sehr
pingelig, aber der Unterschied ist hier nicht von Belang.
Theorem eines bestimmten Kalküls lässt sich nach den für ihn definierten generativen Regeln
aus seinen Axiomen ableiten (oder erzeugen), ein Non-Theorem – etwa irgendein string, in
dem die für den Kalkül eingeführten Basale (Zeichen) vorkommen – dagegen nicht. Die
Theoreme eines Kalküls, der (mathematische oder semantische) Aussagen verknüpft, nennt
man auch (seine) wahren Aussagen, die Non-Theoreme heißen dagegen falsch. Man hat sich
nun lange vorgestellt, die Menge der falschen Aussagen eines Kalküls sei die
Komplementärmenge zu der seiner wahren Aussagen, sodass das Ganze ungefähr so aussähe:
Würde man zum Beispiel die Menge W aller wahren Sätze des Kalküls (oder der Theorie) im
oben erläuterten Sinne auf die – beweisbar rekursiv aufzählbare – Menge der geraden Zahlen
abbilden und die Komplementärmenge der falschen Sätze auf die der ungeraden, die ja
gleichfalls rekursiv aufzählbar ist, so sollte es doch, da wir ja einen EntscheidungsAlgorithmus haben, der feststellen kann, ob irgendeine Zahl zur Teilmenge der geraden oder
der der ungeraden gehört, ebenso möglich sein, für eine beliebige Aussage, der ja eine
bestimmte Zahl aus N korrespondieren muss, zu entscheiden, ob sie zur Menge der wahren
Aussagen (oben weiß) oder der der falschen (oben schwarz) gehört.
Aber dem ist nicht so !!
Nehmen wir an, wir haben einen Kandidaten k: eine Aussage, von der wir wissen wollen, ob
sie eine gültige Aussage eines bestimmten Kalküls, also wahr ist oder ob sie in der Menge der
wahren Aussagen des Kalküls gar nicht enthalten, mithin falsch ist. Da die Menge aller
wahren Aussagen des Kalküls rekursiv aufzählbar ist, existiert ein Algorithmus, der alle ihre
Elemente der Reihe nach erzeugt. Wir brauchten also nur die Ableitungsregeln (Generatoren)
des Kalküls „in Betrieb zu setzen“, um ihn, angefangen mit den Axiomen, alle seine
Theoreme erzeugen zu lassen, bis eines auftaucht, das mit dem „Kandidaten“ übereinstimmt.
(Damit hätten wir übrigens k bewiesen). Natürlich könnte dieser Prozess, wenn k gar nicht zur
Menge der Theoreme des Kalküls gehört, unendlich lange dauern. Aber wir könnten ja,
parallel dazu, einen zweiten Algorithmus die Elemente der Komplementärmenge dazu (die
Non-Theoreme) erzeugen lassen und abwarten, ob der Kandidat k dort auftaucht: wenn ja,
hätten wir ihn widerlegt. Nur hat die Sache einen Haken: die letztere Prozedur funktioniert
nur dann, wenn die Gesamtmenge aus Theoremen und Non-Theoremen (in der Abbildung
oben: der ganze Kreis) rekursiv ist. Das ist sie wiederum nur dann, wenn auch die
Komplementärmenge (also die der Non-Theoreme) rekursiv aufzählbar wäre. Aber das ist sie
nicht! Es gibt zwar Non-Theoreme des Kalküls, aber keinen Algorithmus, der diese NonTheoreme der Reihe nach erzeugen könnte! Die Menge W (der wahren Aussagen des
Kalküls) ist mithin zwar rekursiv aufzählbar, aber nicht rekursiv (weil ihre
Komplementärmenge nicht rekursiv aufzählbar ist). Dies ist der Kern des GÖDEL’schen
Theorems: es gibt keinen Algorithmus, mit dem sich stets entscheiden ließe, ob eine Aussage
in Bezug auf einen bestimmten Kalkül wahr oder falsch ist. Als „rekursive Mathematik“
bezeichnet man deswegen Untersuchungen, die sich mit den Konsequenzen dieses
erschütternden Sachverhalts befassen. (näheres hierzu bei PENROSE 1991, p. 117 ff.)
Herunterladen