利用矩阵求斐波那契数列

利用矩阵求斐波那契数列

flyfish 2015-8-27
矩阵(matrix)定义

一个m*n的矩阵是一个由m行n列元素排成的矩形阵列。矩阵里的元素可以是数字符号或者数学式.

形如

{acbd}
的数表称为 二阶矩阵,它由二行二列组成,其中a,b,c,d称为这个矩阵的元素。

形如

{x1x2}

的有序对称为 列向量Column vector

A={acbd}

X={x1x2}

Y={ax1+bx2cx1+dx2}

称为二阶矩阵A与平面向量X的乘积,记为AX=Y

斐波那契(Fibonacci)数列

从第三项开始,每一项都是前两项之和。
Fn = Fn 1 + Fn 2 , n3

把斐波那契数列中 相邻的两项 Fn Fn 1 写成一个2 × 1的矩阵。
F0=0
F1=1

{FnFn1}

={Fn1+Fn2Fn1}

={1×Fn1+1×Fn21×Fn1+0×Fn2}

={1110}×{Fn1Fn2}

={1110}n1×{F1F0}

={1110}n1×{10}

求F(n)等于求二阶矩阵的n - 1次方,结果取矩阵第一行第一列的元素。

问题转换为二阶矩阵的n次幂

二阶矩阵的乘法

A={acbd},B={egfh},AB={ae+bgce+dgaf+bhcf+dh}

矩阵A与矩阵B的积记做AB。

假设计算A的N次幂
方法1:
二阶矩阵的乘法满足结合律
设A,B,C都是任意的二阶矩阵
A(BC)=(AB)C

n=N/2 结果向下取整

AN=AnAn 当n为偶数
AN=AnAnA 当n为基数

相当于

A6=A3A3
A7=A3A3A
这样可以减少计算次数
因为
A6=AAAAAA 这里有5个乘
A6=AAAAAA 计算完A*A*A 得到结果 A3
再乘以 A3 这里用了3个乘

方法2
以计算 A6 为例
将6转化成二进制110
A6=A4A2

利用矩阵求斐波那契数列_第1张图片

上图显示二进制与幂的指数关系
二进位为1需要乘,为0不需要乘

10进制7 = 二进制 111
例如 A7=A4A2A1
xie10进制31 = 二进制 11111
A31=A16A8A4A2A1

先写一个快速求幂的算法 该代码段是独立代码

#include 
//base 底数 ,exp 指数 
int qpow(int base,int exp)
{
if (0==exp ) return 1;

int ret=1;

while(exp)
{
    if(exp&1)//exp最右边一位 按位与&
    {
        ret=ret*base;
    }
    base=base*base;
    exp>>=1;//右移一位 
}
return ret;
} 

int main()
{
    printf("%d",qpow(3,5));
    return 0;
}

再写利用矩阵求斐波那契数列

#include
using namespace std;
class Matrix
{
public:
    void Init()  
    {         
        e_[0][0]=1;
        e_[0][1]=1;
        e_[1][0]=1;
        e_[1][1]=0; 
    }
    void Unit() //单位矩阵 
    {   
        e_[0][0]=1;
        e_[0][1]=0;
        e_[1][0]=0;
        e_[1][1]=1;        
    }
public:  
   int Get() const
   {
   return e_[0][1];
   }
    friend Matrix operator*(const Matrix& A,const Matrix& B)
    {
        Matrix AB;   
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        {   
            AB.e_[i][j]=0;
            for(int k=0;k<2;k++)
                AB.e_[i][j]+=A.e_[i][k]*B.e_[k][j];         
        }  
    return AB;
    }

private:
    __int64 e_[2][2];    

};

int qpow(Matrix& AB,int n) //矩阵快速幂 
{   
#define Bit(n) 1<
    Matrix t; 
    t.Init(); 
    for(int i=0;Bit(i)<=n;i++) 
    {   if(Bit(i)&n) AB=AB*t; 
        t=t*t;     
    }
    return AB.Get();    
}

调用方法

int n=10;
Matrix AB;
AB.Unit();
qpow(AB,n);//输出是55

代码中单位矩阵的解释
二阶方阵

{1001}
称为单位矩阵,通常记做E
对于任意二阶方阵A,都有 AE=EA=A
单位矩阵E在二阶方阵乘法的作用,相当于1在数的乘法中的作用。

你可能感兴趣的:(数据结构与算法设计)