Je me suis intéressé récemment aux algorithmes, et la séquence de fibonacci a attiré mon attention en raison de sa simplicité.Javascript Fibonacci nième terme Optimisation
J'ai réussi à mettre quelque chose en javascript qui calcule le nième terme dans la séquence de fibonacci en moins de 15 millisecondes après avoir lu beaucoup d'informations sur le web. Il va jusqu'à 1476 ... 1477 est l'infini et 1478 est NaN (selon javascript!)
Je suis assez fier du code lui-même, sauf que c'est un monstre absolu. Voici donc ma question: A) Y a-t-il un moyen plus rapide de calculer la séquence? B) existe-t-il un moyen plus rapide/plus petit de multiplier deux matrices?
Voici le code:
//Fibonacci sequence generator in JS
//Cobbled together by Salty
m = [[1,0],[0,1]];
odd = [[1,1],[1,0]];
function matrix(a,b) {
/*
Matrix multiplication
Strassen Algorithm
Only works with 2x2 matrices.
*/
c=[[0,0],[0,0]];
c[0][0]=(a[0][0]*b[0][0])+(a[0][1]*b[1][0]);
c[0][1]=(a[0][0]*b[0][1])+(a[0][1]*b[1][1]);
c[1][0]=(a[1][0]*b[0][0])+(a[1][1]*b[1][0]);
c[1][1]=(a[1][0]*b[0][1])+(a[1][1]*b[1][1]);
m1=(a[0][0]+a[1][1])*(b[0][0]+b[1][1]);
m2=(a[1][0]+a[1][1])*b[0][0];
m3=a[0][0]*(b[0][1]-b[1][1]);
m4=a[1][1]*(b[1][0]-b[0][0]);
m5=(a[0][0]+a[0][1])*b[1][1];
m6=(a[1][0]-a[0][0])*(b[0][0]+b[0][1]);
m7=(a[0][1]-a[1][1])*(b[1][0]+b[1][1]);
c[0][0]=m1+m4-m5+m7;
c[0][1]=m3+m5;
c[1][0]=m2+m4;
c[1][1]=m1-m2+m3+m6;
return c;
}
function fib(n) {
mat(n-1);
return m[0][0];
}
function mat(n) {
if(n > 1) {
mat(n/2);
m = matrix(m,m);
}
m = (n%2<1) ? m : matrix(m,odd);
}
alert(fib(1476)); //Alerts 1.3069892237633993e+308
La fonction de matrice prend deux arguments: a et b, et renvoie a * b où a et b sont des tableaux 2x2. Oh, et sur une note de côté, une chose magique s'est produite ... Je convertissais l'algorithme de Strassen en notation de tableau JS et cela a fonctionné lors de mon premier essai! Fantastique, non? : P
Merci d'avance si vous parvenez à trouver un moyen plus facile de le faire.
votre fonction cesse de fonctionner si elle est appelée à plusieurs reprises - il retournera NaN sur le deuxième appel ... – Christoph
ajoutant 'm = [ [1,0], [0,1]]; 'en tant que première ligne de' fib() 'répare ceci ... – Christoph
btw: avez-vous remarqué que vous avez calculé deux fois c - le code avant m1 est déjà une manipulation matricielle 2x2 - que vous écrasez dans les étapes suivantes ... – Christoph