Exkurs - Rekursive Berechnungen mit hohem Aufwand

Wege im Galtonbrett

Betrachte noch einmal die Funktion galton zur Berechnung der Anzahl der Wege im Galton-Brett.

def galton(m, n):
    print('galton(', m, ",", n, ')')
    if m < n:
        return None
    else:
        if (n == 0) or (m == n):
            return 1
        else:
            return (galton(m-1, n-1) + galton(m-1, n))

Beachte, dass diese Implementierung jeden Funktionsaufruf mit den aktuellen Parameterwerten auf dem Bildschirm ausgibt.

Aufgabe 1

Der folgende Python-Dialog zeigt die Auswertung des Funktionsaufrufs galton(5, 3).

>>> galton(5, 3)
galton( 5 , 3 )
galton( 4 , 2 )
galton( 3 , 1 )
galton( 2 , 0 )
galton( 2 , 1 )
galton( 1 , 0 )
galton( 1 , 1 )
galton( 3 , 2 )
galton( 2 , 1 )
galton( 1 , 0 )
galton( 1 , 1 )
galton( 2 , 2 )
galton( 4 , 3 )
galton( 3 , 2 )
galton( 2 , 1 )
galton( 1 , 0 )
galton( 1 , 1 )
galton( 2 , 2 )
galton( 3 , 3 )
10

Was fällt hier auf?

Erstelle selbst eine vollständige Reduktionskette. In jedem Reduktionsschritt sollst du nur eine Reduktionsregel anwenden. Kürze den Funktionsnamen galton mit g ab.

g(5, 3) ->
g(4, 2) + g(4, 3) ->
(g(3, 1) + g(3, 2)) + g(4, 3) ->
...
10

Warum handelt es sich bei der vorliegenden Funktionsdefinition um ein ineffizientes Berechnungsverfahren? Woran liegt das?

Die Ackermann-Funktion

Die Ackermann-Funktion wird durch folgende Reduktionsregeln festgelegt.

ack(0, y) -> y+1 
ack(x, 0) -> ack(x-1, 1), falls x > 0
ack(x, y) -> ack(x-1, ack(x, y-1)), falls y > 0

Aufgabe 2

Implementiere die Ackermann-Funktion in Python so, dass jeder Funktionsaufruf mit den aktuellen Parameterwerten auf dem Bildschirm ausgegeben wird (vgl. Aufgabe 1).

Teste verschiedene Funktionsaufrufe wie z. B. ack(2, 3) und ack(3, 2). Was fällt auf?

Kaskadenartige und verschachtelte Rekursion

Wenn auf der rechten Seite in einer Reduktionsregel mehrere rekursive Funktionsaufrufe vorkommen, dann spricht man von kaskadenartiger Rekursion. Verschachtelte Rekursion liegt vor, wenn ein rekursiver Aufruf weitere rekursive Aufrufe der Fuktion enthält. In beiden Fällen kann es zu einer raschen Vermehrung an rekursivebn Funktionsaufrufen kommen. Dabei kann es durchaus vorkommen, dass ein und dieselbe Berechnung mehrfach durchgeführt wird. Beide Aspekte - die Verwaltung vieler Funktionsaufrufe sowie die mehrfache Durchführung identischer Berechnungen - führen zu einem hohen Verbrauch an Ressourcen.

X

Fehler melden

X

Suche