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描述,有兴趣的可以看看....

posted @ 2012-07-09 12:41  zhuangzhuang1988  阅读(361)  评论(1编辑  收藏  举报