利用矩阵求斐波那契数列
flyfish 2015-8-27
矩阵(matrix)定义
一个m*n的矩阵是一个由m行n列元素排成的矩形阵列。矩阵里的元素可以是数字符号或者数学式.
形如
形如
的有序对称为 列向量Column vector
设
则
称为二阶矩阵A与平面向量X的乘积,记为AX=Y
斐波那契(Fibonacci)数列
从第三项开始,每一项都是前两项之和。
Fn
=
Fn
−
1
+
Fn
−
2
,
n⩾3
把斐波那契数列中 相邻的两项
Fn
和
Fn
−
1
写成一个2
×
1的矩阵。
F0=0
F1=1
求F(n)等于求二阶矩阵的n - 1次方,结果取矩阵第一行第一列的元素。
问题转换为二阶矩阵的n次幂
二阶矩阵的乘法
设
矩阵A与矩阵B的积记做AB。
假设计算A的N次幂
方法1:
二阶矩阵的乘法满足结合律
设A,B,C都是任意的二阶矩阵
A(BC)=(AB)C
n=N/2 结果向下取整
AN=An∗An
当n为偶数
AN=An∗An∗A
当n为基数
相当于
A6=A3∗A3
A7=A3∗A3∗A
这样可以减少计算次数
因为
A6=A∗A∗A∗A∗A∗A
这里有5个乘
A6=(A∗A∗A)∗(A∗A∗A)
计算完A*A*A 得到结果
A3
再乘以
A3
这里用了3个乘
方法2
以计算
A6
为例
将6转化成二进制110
A6=A4∗A2
上图显示二进制与幂的指数关系
二进位为1需要乘,为0不需要乘
10进制7 = 二进制 111
例如
A7=A4∗A2∗A1
xie10进制31 = 二进制 11111
A31=A16∗A8∗A4∗A2∗A1
先写一个快速求幂的算法 该代码段是独立代码
#include <stdio.h>
//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<iostream>
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<<n
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
代码中单位矩阵的解释
二阶方阵
对于任意二阶方阵A,都有 AE=EA=A
单位矩阵E在二阶方阵乘法的作用,相当于1在数的乘法中的作用。