算法解析——矩阵快速幂

算法解析——矩阵快速幂

一.简介

矩阵快速幂是一种对于矩阵连乘非常有效的算法

以矩阵 A A A为例,对于 A n A^n An,如果按照正常的方法,时间复杂度为 O ( n ) O(n) O(n)​,可如果考虑矩阵快速幂,我们可以将时间复杂度优化到 O ( log ⁡ n ) O(\log n) O(logn)

二.快速幂

先考虑常数的情况,设有常数 x x x,对于 x n x^n xn,不妨如下考虑:

假如 n = 100110 n=100110 n=100110,那么 x n = x 100110 = x 100000 ∗ x 000100 ∗ x 000010 x^n=x^{100110}=x^{100000}*x^{000100}*x^{000010} xn=x100110=x100000x000100x000010​,对于这种情况,我们可以采用如下方法进行优化

if __name__ == '__main__':
    n = 10
    x = 2
    sum = x
    ans = 1
    while n > 0:
        a = n & 1
        if a == 1:
            ans *= sum
        sum *= sum
        n >>= 1
    print(ans)

其原理就是用 a n s ans ans​记录答案,再用一个变量 s u m sum sum​记录当前是 x x x​的几次方(如: x 100000 , x 000100 , x 000010 x^{100000},x^{000100},x^{000010} x100000,x000100,x000010​),对于 n n n​的每一位进行判断,判断其是否为 1 1 1​,每次是 n n n​的该位为 1 1 1​就拿 a n s ans ans​乘以该 s u m sum sum​,最后 a n s ans ans​​​的结果即为所求

等于说,本题的算法复杂度实际上是 n n n的二进制位数,即 O ( log ⁡ n ) O(\log n) O(logn)

三.矩阵快速幂

如果常数可以进行快速幂,那么矩阵同样可以,唯一不同的就在于每次进行的 s u m ∗ s u m , a n s ∗ s u m sum*sum,ans*sum sumsum,anssum​是矩阵之间的乘法,而不是常数之间的乘法,虽然会增加一定的复杂度,但这些复杂度的增加是常数级别的,最终的时间复杂度仍然为 O ( log ⁡ n ) O(\log n) O(logn)

四.矩阵快速幂的应用

矩阵快速幂可以用于斐波那契数列的求和中

斐波那契数列的公式如下: f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n)=f(n-1)+f(n-2) f(n)=f(n1)+f(n2)​,对其进行一定的改写,我们可以得出 { f ( n ) = f ( n − 1 ) + f ( n − 2 ) f ( n − 1 ) = f ( n − 1 ) \begin {cases} f(n)=f(n-1)+f(n-2) \\ f(n-1)=f(n-1)\end{cases} {f(n)=f(n1)+f(n2)f(n1)=f(n1)

将其转换成矩阵乘法,我们有 [ f ( n ) f ( n − 1 ) ] = [ 1   1 1   0 ] [ f ( n − 1 ) f ( n − 2 ) ] = [ 1   1 1   0 ] n − 2 [ f ( 2 ) f ( 1 ) ] \left[\begin{matrix} f(n) \\ f(n-1)\end{matrix}\right] = \left[\begin{matrix} 1 \ 1 \\ 1 \ 0\end{matrix}\right] \left[\begin{matrix} f(n-1) \\ f(n-2)\end{matrix}\right]=\left[\begin{matrix} 1 \ 1 \\ 1 \ 0\end{matrix}\right]^{n-2} \left[\begin{matrix} f(2) \\ f(1)\end{matrix}\right] [f(n)f(n1)]=[1 11 0][f(n1)f(n2)]=[1 11 0]n2[f(2)f(1)]

我们可以直接通过公式+矩阵快速幂得到斐波那契数列的解,时间复杂度为求解 [ 1   1 1   0 ] n − 2 \left[\begin{matrix} 1 \ 1 \\ 1 \ 0\end{matrix}\right]^{n-2} [1 11 0]n2的时间复杂度,即 O ( log ⁡ n ) O(\log n) O(logn)

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值