生成全1矩阵_1.3 矩阵乘方:快速幂

本节我们研究矩阵的乘方。

生成单位矩阵

由于矩阵的

次方是单位矩阵,因此有必要先写一个生成单位矩阵的算法。方法很简单,就是写一个for循环,让对角线上的元素为1即可(其余元素在矩阵初始化的时候默认为0,不用管)。下面直接贴出代码:
//mathalgorithm.h

时间复杂度:

(其中
是矩阵规模)

空间复杂度:

普通的乘方算法

现在讨论矩阵的乘方。我们举一个例子,计算

。通常的运算是这样的:
A

我们发现,上述方法需要使用

次乘法运算才能够算出
。一般而言,为计算
,用上述方法需要
次乘法才可以。那能不能改进呢?

快速幂算法

我们采用二分的策略优化它。具体如下所示:

T1

我们发现,按照这种方法去计算,仅仅用了

次乘法运算就能算出

我们把如上算法一般化。 下面使用自顶向下的递归方法:

计算 

时间复杂度:设为

,其中
是矩阵的幂次。从上述代码中不难得出
。利用主定理,可以解得

空间复杂度:每一次递归调用时新建了一个变量

。由于代码需要执行
次,即递归深度是
,所以空间复杂度是

除此之外,还可以把自顶向下的递归转化为自底向上的循环,代码如下:

//mathalgorithm.h

时间复杂度:

,因为while循环要执行

空间复杂度:

,因为只设了常数个变量。

为了加速,这里判断奇偶直接用位与运算符&,除以2用右移运算符>>。

细心的读者可能想到,万一幂次为负数

怎么办?事实上,这需要先求出矩阵的逆
,再让这个逆
次方即可。关于求逆矩阵的方法,我们留到解方程组那一块在讨论。

例子:计算斐波那契数列第n项

斐波那契数列定义为:

如果直接递归,那么时间复杂度是

;如果直接递推或者采用动态规划,那么时间复杂度是
。还有更快的做法吗?

注意到,以上递推式可以写成矩阵形式:

用数学归纳法可以证明

由于快速幂的时间复杂度是

,所以用矩阵去计算斐波那契数列第
项的时间复杂度是
。以
为例,代码如下:(在main.cpp中)
//main.cpp

以下是运行结果:

4a8a42b71ce783930f9fe7624da51090.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值