【Strassen】矩阵乘法的Strassen算法,时间复杂度 O(n^2.81) (rust 语言实现)

本文介绍了Strassen算法,一种改进的矩阵乘法方法,其时间复杂度为O(n^2.81)。通过递归和7次矩阵乘法而非传统的8次,减少了计算量。文章详细阐述了算法步骤,并提供了Rust语言的实现,通过测试验证了算法的正确性。
摘要由CSDN通过智能技术生成

矩阵乘法的定义:

A = ( a i j ) A=(a_{ij}) A=(aij) B = ( b i j ) B=(b_{ij}) B=(bij) n × n n \times n n×n 的方阵, 则对 i , j = 1 , 2 , . . . , n i, j = 1, 2, ..., n i,j=1,2,...,n,定义乘积 C = A ⋅ B C=A\cdot B C=AB 中的元素 c i j c_{ij} cij 为:

c i j = ∑ k = 1 n a i k ⋅ b k j c_{ij} = \sum_{k=1}^{n} a_{ik} \cdot b_{kj} cij=k=1naikbkj

按照矩阵乘法的定义不难写出算法1

// 算法1:定义法
pub fn square_matrix_multiply<T: Default + Clone + AddAssign + Mul<Output = T>>(
    a: &Vec<Vec<T>>,
    b: &Vec<Vec<T>>,
) -> Vec<Vec<T>>
where
    T: Mul<T>,
{
   
    let mut c = vec![vec![T::default(); a.len()]; a.len()];
    if a.len() == a[0].len() && b.len() == a[0].len() && a.len() == b.len() {
   
        let n = a.len();
        for i in 0..n {
   
            for j in 0..n {
   
                c[i][j] = T::default();
                for k in 0..a.len() {
   
                    c[i][j] += a[i][k].clone() * b[k][j].clone();
                }
            }
        }
    }
    return c;
}

由于三重 for 循环的每一重都恰好执行 n 步,因此该算法的时间复杂度为 O ( n 3 ) O(n^3) O(n3)

为此我们尝试改进

一个简单的分治算法

为简单起见,假定三个矩阵均为 n × n n \times n n×n 矩阵, n n n 2 2 2 的幂,矩阵 A , B , C A, B, C A,B,C 均分解为 4 4 4 n / 2 × n / 2 n / 2 \times n / 2 n/2×n/2 的子矩阵,则计算公式等价于

C 11 = A 11 ⋅ B 11 + A 12 ⋅ B 21 C_{11} = A_{11} \cdot B_{11} + A_{12} \cdot B_{21} C11=A11B11+A12B21

C 12 = A 11 ⋅ B 12 + A 12 ⋅ B 22 C_{12} = A_{11} \cdot B_{12} + A_{12} \cdot B_{22} C12=A11B12+A12B22

C 21 = A 21 ⋅ B 11 + A 22 ⋅ B 21 C_{21} = A_{21} \cdot B_{11} + A_{22} \cdot B_{21} C21=A21B11+A22B

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值