浅谈矩阵快速幂
Posted baihualiaoluan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈矩阵快速幂相关的知识,希望对你有一定的参考价值。
矩阵快速幂
一.简介
首先,矩阵快速幂是从快速幂里延伸出的算法,需要快速幂以及线性代数的知识。快速幂是利用二进制的有关性质快速计算出xn,矩阵快速幂则是通过将递推式化成一个矩阵,求解某个递推结果的过程变成求解一个矩阵的n次幂的过程,从而能用快速幂加快递推式的求解。
举个例子,我们来用斐波那契数列来解释一下矩阵快速幂的具体流程。大家都知道递推式为F(n) = F(n-1)+F(n-2)。这个式子十分浅显易懂,但是用来及求解较大的项时就会变得非常慢,因此我们可以考虑用矩阵快速幂来优化一下计算过程。在一般情况下,我们要通过递推式获得一个矩阵之间的递推关系,形如T*A(n-1) = A(n)(其中T,A(n-1),A(n)均为矩阵)。
对于F(n),我们可以得到一个矩阵之间的递推关系就是
其中,要注意的是,为了方便运算,我们构造的矩阵都是方阵,在这里An其实也是一个2*2的方阵,但我们只关心An的左边,所以就没有写出An的右边。很明显,上面给出的等式是成立的,接下来,如果我们要求F(n),就可以先求出A(n) = Tn-2*A(1),
A(1)是左边为两个1的2*2矩阵,此时F(n)就是A(n)左上角的值。这样,我们就把一个递推式的计算过程优化,然后运用矩阵快速幂进行极快的求解。
矩阵快速幂的难点就在于矩阵的构造。
下面给一些简单的递推式
1.f(n)=a*f(n-1)+b*f(n-2)+c;(a,b,c是常数)
2.f(n)=c^n-f(n-1) ;(c是常数)
二.代码实现
const int N = 2; const int mod = 10000; struct Matrix { int mat[N][N]; Matrix(){}; Matrix operator*(Matrix const &b) const { Matrix res; memset(res.mat,0,sizeof(res.mat)); for(int i = 0;i<N;++i) { for(int j = 0;j<N;++j) { for(int k = 0;k<N;++k) { printf("%d %d %d ",i,j,k); res.mat[i][j] = (res.mat[i][j]+this->mat[i][k]*b.mat[k][j])%mod; } } } return res; } void Print() { for(int i =0;i<N;++i) { for(int j = 0;j<N;++j) printf("%d ",mat[i][j]); printf(" "); } return ; } }; Matrix pow_mod(Matrix base,int n) { Matrix res; memset(res.mat,0,sizeof(res.mat)); for(int i = 0;i<N;++i) res.mat[i][i] = 1; while(n>0) { if(n&1) { res.Print(); res= res*base; } base = base*base; n>>=1; res.Print(); } return res; }
三.相关习题
以上是关于浅谈矩阵快速幂的主要内容,如果未能解决你的问题,请参考以下文章