Fibonacci求序列和
文章来自http://www.mathworks.cn/moler/exm/chapters/fibonacci.pdf中的一道思考题,当然他上面已经有解了.我看了下挺好玩的所有写出来.
已知序列A={a1,a2,a3,a4...}
求函数F(x) = a1*x + a2*x^2+a3*x^3+a4*x^4+...
如果A为Fibonacci则求和结果
F(x) = x+2x^2+3x^3+5x^4+8x^5+...(假设0<x<1)不然这个数字会无限增大
我们很快根据这个写出函数
1 bool double_eq(double d1,double d2) 2 { 3 return abs(d1-d2) <0.0001; 4 } 5 6 //F(x) = x+2x^2+3x^3+5x^4+8x^5+... 7 double fibonacci_1(double x) 8 { 9 const int n = 1476; 10 int fibs[n]; 11 double sum = 0.0; 12 double temp = sum; 13 14 fibs[0] = 1; 15 fibs[1] = 2; 16 sum = fibs[0]*x +fibs[1]*x*x; 17 for(int i = 2;i<n;i++) 18 { 19 fibs[i] = fibs[i-1]+fibs[i-2]; 20 sum += fibs[i]*pow(x,i+1); 21 if(double_eq(sum,temp)) 22 break; 23 temp = sum; 24 } 25 return sum; 26 }
但是仔细想想有没有更好的方法呢,既然Fib可以迭代,x呢,每次求x^n也是很耗时间的.
由此引出了第二中解决方法
1 //f(k) =fib(k) x^k = (fib(k-1)+fib(k-1))x^k = fib(k-1)*x^(k-1)*x + fib(k-2)*x^(k-2)*x^2 2 // = f(k-1)*x + f(k-2)*x^2 = x*(f(k-1)+f(x-2)*x) 3 4 double fibonacci_2(double x) 5 { 6 double f_k_2,f_k_1,f_k; 7 double sum = 0.0,temp; 8 f_k_2 = x; 9 f_k_1 = x + 2*pow(x,2); 10 f_k = (f_k_1+f_k_2*x)*x; 11 sum = f_k+f_k_1+f_k_2; 12 temp = sum; 13 while(true) 14 { 15 f_k_1 = f_k_2; 16 f_k_2 = f_k; 17 f_k = (f_k_1+f_k_2*x)*x; 18 sum+=f_k; 19 20 if(double_eq(sum,temp)) 21 break; 22 temp = sum; 23 } 24 25 return 0.0; 26 }
其中省去了pow函数的使用.
此时可能会想,这个方法肯定很牛了,直接使用了F(x)各个项之间的关系了.
但是还有更加吐血的方法.
于是有了下面的函数:
1 //F(x) = x+2x^2+3x^3+5x^4+8x^5 2 // = x+(1+1)x^2 + (2+1)x^3+(3+2)x^4+(5+3)x^5 3 // = x + x^2 + x(x+2x^2+3x^3+5x^4) + x^2(x+2x^2+3x^3+...) 4 // = x+x^2+xF(x)+x^2F(x) 5 // (1-x-x^2)F(x) = x+x^2 6 // 7 // F(x) = (x+x^2)/(1-x-x^2); 8 9 double fibonacci_3(double x) 10 { 11 return (x+x*x)/(1-x-x*x); 12 }
作者是这样说的'It is not even necessary to have a .m file.A one-liner does the job.'
记得<组合数学>上面好像说这个叫生成函数..嗯 挺好玩的........
当然最后要推荐下这本书<Experiments with MATLAB>http://www.mathworks.cn/moler/exm/chapters.html,电子版的,作者好像是Matlab他爸..上面还有PageRank算法的Matlab描述,有兴趣的可以看看....