Je ne crois pas être hors sujet non plus.
Dans le cas de la suite de Fibonacci, trouver la fonction récursive n’est pas difficile. Même l’auteur l’a trouvée.
C’est plutôt le temps d’exécution dû au nombre total d’appels et la grandeur de la pile qui pose problème.
Pour ce qui est de la grandeur de la pile, elle sera de l’ordre de n
. En effet, dans le pire des cas, on aura un appel pour:
soit n+1
appels.
Le nombre total d’appels est nettement moins que prévu. Il n’est pas de l’ordre de 2**n
.
Il devient tout de même rapidement très grand.
On peut le voir comme un arbre binaire pour lequel la profondeur d’une branche est toujours un de moins que celle de l’autre branche.
Le code suivant montre comment le calculer avec vérification.
def fibo(n):
global c
c += 1
if n <= 0: return 0
if n == 1: return 1
return fibo(n-1) + fibo(n-2)
F = [1, 1]
for n in range(2, 100+1):
F.append(F[-1] + F[-2] + 1)
for n in range(30+1):
c = 0
fibo(n)
if c != F[n]: print(f"erreur pour {n}, c={c}, F={F[n]}")
print(F[78])
Ce qui donne:
L’évaluation est bonne jusqu’à au moins 30.
On voit pourquoi c’est si long pour le terme 78.
Pour me convaincre que le nombre d’appel pour F(n)
n’était pas de l’ordre de grandeur de 2**n
et que la suite des rapports était une suite monotone décroissante, sauf pour quelques petits nombres, j’ai écrit le code suivant:
F = [1, 1]
for n in range(2, 100+1):
F.append(F[-1]+F[-2]+1)
m = 4
for i in range(len(F)):
z = F[i] / 2**i
if z > m: print(i)
m = z
print(m)
Qui donne
Pour 1 j’ai 1/2 et pour 2 j’ai 3/4. Mais ça décroit par la suite.