Jak zauważyli inni, analiza rekurencji może być bardzo trudna bardzo szybko. Oto inny przykład takiej rzeczy: http://rosettacode.org/wiki/Mutual_recursion http://en.wikipedia.org/wiki/Hofstadter_sequence#Hofstadter_Female_and_Male_sequences
ciężko jest obliczyć odpowiedź i czas ich trwania. Wynika to z faktu, że te wzajemnie rekurencyjne funkcje mają „trudną formę”.
W każdym razie spójrzmy na ten prosty przykład:
http://pramode.net/clojure/2010/05/08/clojure-trampoline/
(declare funa funb)
(defn funa [n]
(if (= n 0)
0
(funb (dec n))))
(defn funb [n]
(if (= n 0)
0
(funa (dec n))))
Zacznijmy od próby obliczenia funa(m), m > 0
:
funa(m) = funb(m - 1) = funa(m - 2) = ... funa(0) or funb(0) = 0 either way.
Czas działania wynosi:
R(funa(m)) = 1 + R(funb(m - 1)) = 2 + R(funa(m - 2)) = ... m + R(funa(0)) or m + R(funb(0)) = m + 1 steps either way
Teraz wybierzmy inny, nieco bardziej skomplikowany przykład:
Zainspirowany http://planetmath.org/encyclopedia/MutualRecursion.html , który sam w sobie jest dobrym odczytem, spójrzmy na: „” „Liczby Fibonacciego można interpretować poprzez wzajemną rekurencję: F (0) = 1 i G (0 ) = 1, przy czym F (n + 1) = F (n) + G (n) i G (n + 1) = F (n). "" "
Więc jaki jest czas działania F? Pójdziemy w drugą stronę.
Cóż, R (F (0)) = 1 = F (0); R (G (0)) = 1 = G (0)
Teraz R (F (1)) = R (F (0)) + R (G (0)) = F (0) + G (0) = F (1)
...
Nietrudno zauważyć, że R (F (m)) = F (m) - np. Liczba wywołań funkcji potrzebnych do obliczenia liczby Fibonacciego o indeksie i jest równa wartości liczby Fibonacciego o indeksie i. Zakładało to, że dodanie dwóch liczb razem jest znacznie szybsze niż wywołanie funkcji. Gdyby tak nie było, byłoby to prawdą: R (F (1)) = R (F (0)) + 1 + R (G (0)), a analiza tego byłaby bardziej skomplikowana, ewentualnie bez łatwego rozwiązania w formie zamkniętej.
Zamknięta postać sekwencji Fibonacciego niekoniecznie jest łatwa do odkrycia, nie wspominając o bardziej skomplikowanych przykładach.