Mehrfachrekursionen

Aus ProgrammingWiki
Archivierte Version vom 2013-12-10T22:48:11+00:00. Aktuelle Version

Inhaltsverzeichnis

Die Fibonaccizahlen

Einer der bedeutendsten Mathematiker des Mittelalters, Leonardo Fibonacci di Pisa (* um 1180; † 1241), beschrieb die Fortpflanzung von Kaninchen mit der Zahlenfolge:

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

Definition:

\mbox{fibo}(n)=\begin{cases}1,\mbox{wenn}\hspace{0.3em}n=1\\1,\mbox{wenn}\hspace{0.3em}n=2\\\mbox{fibo}(n-1)+\mbox{fibo}(n-2),\mbox{sonst}\end{cases}

Beschreibung:

  • Die ersten beiden Glieder der Zahlenfolge sind jeweils 1.
  • Jedes weitere Glied ergibt sich aus der Summe seiner beiden Vorgänger.


Das explizite Bildungsvorschrift wurde übrigens unabhängig voneinander von den französischen Mathematikern Abraham de Moivre (* 26. Mai 1667; † 27. November 1754) erst im Jahr 1718 und Jacques Philippe Marie Binet (* 2. Februar 1786; † 12. Mai 1856) sogar erst im Jahr 1843 entdeckt.

Fibonacci1.jpg
Berechnung der "Kaninchenaufgabe" mit der Fibonacci-Folge

Implementation:

Hinweis: Testen Sie diese Prozedur mit kleinen Argumenten!

In dieser echt rekursiven Prozedur erfolgt der rekursive Aufruf zweimal. Rekursionen, in denen der rekursive Aufruf mehrfach erfolgt, heißen Mehrfachrekursionen. Unsere Problemlösungen zum Binärbaum, zu den Fraktalen sowie zum "Turm von Hanoi" sind ebenfalls Mehrfachrekursionen.

Aufwandsbetrachtungen

Mehrfachrekursive Prozeduren können dann sehr uneffizient werden, wenn gleiche Operationen mehrfach ausgeführt werden.
Wir testen dazu die Prozedur im Trace-Modus:

Die nachfolgende Abbildung verdeutlicht die Abarbeitung des Prozeduraufrufs (fibo 6) in einer Baumstruktur:

FiboBaum1.GIF

Die nachfolgende Prozedur berechnet die n-te Fibonaccizahl und bestimmt dabei die Anzahl der Rekursionschritte. Beide Werte werden als Paar (<ergebnis> . <aufwand>)</aufwand></ergebnis> ausgegeben:

Hinweis: Während mit let lokale Wertbeindungen vorgenommen werden, lassen sich mit letrec lokale rekursive Datenstrukturen definieren.

Experimente

Wir wollen den Aufwand zur Bestimmung der n-ten Fibonaccizahl in einem Balkendiagramm visualisieren. Dazu müssen die Zählergebnisse der Prozedur fibo-aufwand in einer Liste gesammelt werden:

Diese Liste wird der Prozedur balkendiagramm mit folgender Syntax übergeben:

(balkendiagramm <ls>) ; <ls> ... Liste mit Zahlenwerten</ls></ls>

Achtung! Beim Experimentieren ist etwas Geduld erforderlich!

Ihr Browser unterstützt Canvas nicht.

Endständig rekursive Bestimmung der n-ten Fibonaccizahl

Um den erheblichen Mehraufwand zu vermeiden, könnte sich in diesem Fall eine endständig rekursive Problemlösung (Iteration) anbieten.
Vervollständigen Sie die entsprechende Hilfsprozedur.

Es wäre nun falsch anzunehmen, dass Mehrfachrekursionen aus Effizienzgründen vermieden werden müssen. Im Gegenteil!
Mehrfachrekursionen können auch eine universelle Lösungsstrategie spezieller Probleme darstellen.

Länge einer unverschachtelten bzw. verschachtelten Listen

Länge einer unverschachtelten Liste (Anzahl aller Listenelemente):

Länge einer verschachtelten Liste:

Zählen eines Elements in einer unverschachtelten bzw. verschachtelten Listen

Elementanzahl in einer unverschachtelten Liste:

Elementanzahl in einer verschachtelten Liste:

Hinweis: equal?, eqv? und eq? sind allgemeine Vergleichsprädikate einfacher und höherer Datenstrukturen.

Aufgaben

  1. Elementprüfer

    Schreiben Sie zur Wiederholung das Prädikat element?, das entscheidet, ob ein vorgegebenes Element in einer unverschachtelten Liste enthalten ist.

    Implementieren Sie nun das Prädikat superelement?, das sich in analoger Weise auf verschachtelte Listen anwenden lässt.

  2. Streichen eines Elements

    Schreiben Sie zunächst nochmals die Prozeduren streiche-erstes und streiche-alle, die ein vorgegebenes Element in einer unverschachtelten Liste beim ersten bzw. bei jedem Auftreten streichen.

    Implementieren Sie nun die Prozedur superstreichen für die entsprechende Anwendung auf verschachtelte Listen.

  3. "Glätten" einer verschachtelten Liste

    Manchmal ist ist es sinnvoll, eine verschachtelte Liste in eine unverschachtelte Liste umzuwandeln. Wir wollen diese Konvertierung als "Glätten" bezeichnen. Dabei muss natürlich jedes Element aus jeder beliebigen Verschachtelungstiefe übernommen werden.
    Implementieren Sie die Prozedur glaetten.

Zum Weiterarbeiten

Superminimum

Implementieren Sie das "Superminimum" einer verschachtelten Liste. Entwickeln Sie weitere Prozeduren für verschachtelte Listen.

Zur Problemlösung.