代码改变世界

fibonacci数的矩阵乘法

2012-04-15 02:01  youxin  阅读(360)  评论(0编辑  收藏  举报

 斐波那契数列1,1,2,3,5,8,13…….有如下定义
F(n)=f(n-1)+f(n-2)
F(1)=1
F(2)=1
对于以下矩阵乘法

 

[F(n+1)]=[1    0][F(n)   ]
[    F(n)]=[1    0][F(n-1)]
  结果
  F(n+1)=F(n)+F(n-1)
  F(n)=F(n)

 

  设[ 1    1] 
     [ 1    0]为A

 f(n)=Af(n-1)=A^n-1f(1)

f(1)可以表示成 [ 1    1] 
                 [ 1    0]

 

   所以 F[n] = A^n  

 还有另外一种形式:

 

( F(n+1) F(n)            

 F(n)     F(n-1) )   = A^n;

先看自己写的简单易懂的代码:

#include<iostream>
using namespace std;

void mul(int m[2][2],int f[2][2])
{
    int x,y,z,w;  // 必须用4个变量暂存结果
        
    x=m[0][0]*f[0][0]+m[0][1]*f[1][0];
    y=m[0][0]*f[0][1]+m[0][1]*f[1][1];
    z=m[1][0]*f[0][0]+m[1][1]*f[1][0];
    w=m[1][0]*f[0][1]+m[1][1]*f[1][1];
    
    f[0][0]=x;f[0][1]=y;
    f[1][0]=z;f[1][1]=w;
}

void power(int f[2][2],int n)
{ 
    int m[2][2]={{1,1},{1,0}};

    f[0][0]=f[0][1]=f[1][0]=1;
    f[1][1]=0;
    if(n==1)
        return ;

    for(int i=2;i<=n;i++)
        mul(m,f);
}

int main()
{
    int n;

    int f[2][2];

    cin>>n;

    for(int i=1;i<=n;i++)
    {
         power(f,i);
        cout<<f[0][1]<<endl;
    }
}

 

再看别人写的:

#include <stdio.h>
#include <stdlib.h>
/*******************************************
*
*          matrix A =   [[1, 1],
*                        [1, 0]]
*          A^n = [[F(N+1), F(N)],
*                 [F(N),   F(N -1)]];
*
********************************************/

#define fib(n, power) \
    int F[2][2] = {{1,1},{1,0}};\
    if(n == 0)\
        return 0;\
    power(F, n-1);\
    return F[0][0]; //为什么是f[0][0];因为这里传递的是N-1,第一个为Fn,推荐用这种,减少了一步计算

void mul(int F[2][2], int M[2][2]);
void power1(int F[2][2], int n);
void power2(int F[2][2], int n);
int fib1(int n);
int fib2(int n);void mul(int F[2][2], int M[2][2])
{
    // [[l: left, r : right],
    //  [t: top,  b : bootom]]
    int lt, rt,
        bl, br;

//  parallel setions by order {

    //parallel section 1 {
    lt = F[0][0]*M[0][0] + F[0][1]*M[1][0], rt =  F[0][0]*M[0][1] + F[0][1]*M[1][1];
    bl = F[1][0]*M[0][0] + F[1][1]*M[1][0], br =  F[1][0]*M[0][1] + F[1][1]*M[1][1];
    //}
    //parallel section 2 {
    F[0][0] = lt, F[0][1] = rt;
    F[1][0] = bl, F[1][1] = br;
    //}
//}

}

// func : power1
// params :
// todo(matrix power)
// Time Complexity: O(n)
// Extra Space: O(1)
void power1(int F[2][2], int n)
{
    int i;
    int M[2][2] = {{1,1},{1,0}};

    for ( i = 2; i <= n; i++ )
        mul(F, M);

}

// func : power2
// params :
// todo(matrix power)
// Time Complexity: O(Logn)
// Extra Space: {'fuction stack size' : O(Logn),
//              'otherwise' : O(1)}
void power2(int F[2][2], int n)
{
    if( n == 0 || n == 1)
        return;
    int M[2][2] = {{1,1},{1,0}};

    power2(F, n/2);
    mul(F, F);

    if( n%2 != 0 )
        mul(F, M);
}


int fib1(int n)
{
    fib(n, power1)
}

int fib2(int n)
{
  fib(n, power2);
}

int main()
{
    int n = 30;
    printf("Fibonacci(%03d) = %d\n", n, fib2(n));
    getchar();

    return 0;
}
 

 这篇也不错!

http://caoruntao.iteye.com/blog/1129379