précédent | suivant | table des matières
Les nombres de Fibonacci sont définis par la récurrence :
Programmation récursive
long fibonR( int n ){
if((n==0)||(n==1))
return 1;
else return fibonR(n-1)+fibonR(n-2);
}
Le nombre d'appels de la méthode fibonR générés par un appel de fibonR(n) est donné par la récurrence suivante
On montre par récurrence que Nn=2×Fn-1.
La récurrence qui exprime le nombre de Fibonnacci au rang n se résout de la façon suivante :
![]()
![]()
![]()
![]()
![]()
![]()
Soient
et
les racines de
l’équation
sont
et ![]()
On a ![]()
Or ![]()
On a alors ![]()
Donc
et
, le deuxième terme tend donc vers 0, donc le nombre d'appels récursifs a une croissance exponentielle !
Programmation itérative
long fibonI( int n ){
long F0 = 1, F1 = 1, F = 1;
for(int i = 2; i<= n; ++i){
F = F0+F1;
F0 = F1;
F1 = F;
}
return F1;
}
Le temps de calcul est clairement de l'ordre de n.
Peut-on faire mieux ?
Soit
alors on
a :
et
.
On déduit que 
Nous nous proposons de calculer Mn en faisant le moins possible de multiplications. L’algorithme classique effectue n multiplications. Pour en faire moins nous nous proposons de programmer l’algorithme suivant :
Supposons que n soit une puissance de 2. Le nombre de multiplications effectuées par cette méthode est donné par la récurrence :
Soit ![]()
Dans ce cas le temps de calcul de
est donc proportionnel à ![]()
public class Matrice {
long A, B, C, D;
Matrice(long a, long b, long c, long d){
A=a; B=b; C=c; D=d;
}
public Matrice multiplie( Matrice m){
long a, b, c, d;
a = A*m.A + B*m.C;
b = A*m.B + B*m.D;
c = C*m.A + D*m.C;
d = C*m.B + D*m.D;
return new Matrice(a, b, c, d);
}
}
Matrice xn( int n, Matrice m){
if(n==0) return new Matrice(1, 0, 0, 1);
else if(n==1) return new Matrice(m.A, m.B, m.C, m.D);
else {
int n2 = n/2;
Matrice res = xn(n2, m.multiplie(m));
int nMod2 = n%2;
if(nMod2!=0) res = m.multiplie(res);
return res;
}
}
public long fibonM(int n){
Matrice m = new Matrice(0,1,1,1);
return xn(n, m).D;
}
Exercice : A partir de quelle valeur de n les algorithmes précédents ont des temps de calcul sensiblement différents.