Come altri hanno sottolineato, l'analisi della ricorsione può diventare molto difficile molto velocemente. Ecco un altro esempio di tale cosa: link link
è difficile calcolare una risposta e un tempo di esecuzione per questi. Ciò è dovuto a queste funzioni reciprocamente ricorsive che hanno una "forma difficile".
In ogni caso, diamo un'occhiata a questo semplice esempio:
link
(declare funa funb)
(defn funa [n]
(if (= n 0)
0
(funb (dec n))))
(defn funb [n]
(if (= n 0)
0
(funa (dec n))))
Iniziamo cercando di calcolare funa(m), m > 0
:
funa(m) = funb(m - 1) = funa(m - 2) = ... funa(0) or funb(0) = 0 either way.
Il tempo di esecuzione è:
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
Ora prendiamo un altro esempio leggermente più complicato:
Ispirato al link , che è di per sé una buona lettura, diamo un'occhiata a: "" "I numeri di Fibonacci possono essere interpretato tramite ricorsione reciproca: F (0) = 1 e G (0) = 1, con F (n + 1) = F (n) + G (n) e G (n + 1) = F (n). " ""
Quindi, qual è il tempo di esecuzione di F? Andremo dall'altra parte.
Bene, R (F (0)) = 1 = F (0); R (G (0)) = 1 = G (0)
Ora R (F (1)) = R (F (0)) + R (G (0)) = F (0) + G (0) = F (1)
...
Non è difficile vedere che R (F (m)) = F (m) - ad es. il numero di chiamate di funzione necessarie per calcolare un numero di Fibonacci all'indice i è uguale al valore di un numero di Fibonacci all'indice i. Ciò presuppone che l'aggiunta di due numeri insieme sia molto più veloce di una chiamata di funzione. Se così non fosse, allora sarebbe vero: R (F (1)) = R (F (0)) + 1 + R (G (0)), e l'analisi di ciò sarebbe stata più complicata, possibilmente senza una soluzione di forma chiusa facile.
La forma chiusa per la sequenza di Fibonacci non è necessariamente facile da reinventare, per non parlare di alcuni esempi più complicati.