实现矩阵乘法【矩阵乘法复杂度优化】

实现矩阵乘法【矩阵乘法复杂度优化】

  • 题目描述:
  • 解题思路一:使用NumPy库
  • 解题思路二:三个for循环
  • 解题思路三:分块矩阵乘法, 利用多线程或多进程

题目描述:

实现矩阵乘法【矩阵乘法复杂度优化】

解题思路一:使用NumPy库

import numpy as npdef matrix_multiply(A, B):"""计算矩阵A和B的乘积。参数:A -- nxm矩阵 (numpy.ndarray)B -- mxn矩阵 (numpy.ndarray)返回:C -- 乘积矩阵,大小为nxn (numpy.ndarray)"""# 确保A的列数与B的行数相等,这是矩阵乘法的前提条件if A.shape[1] != B.shape[0]:raise ValueError("矩阵A的列数必须与矩阵B的行数相等")# 使用numpy的dot函数进行矩阵乘法C = np.dot(A, B)return C# 示例:创建两个矩阵并进行乘法运算
# 假设A是3x2矩阵,B是2x3矩阵
A = np.array([[1, 2], [3, 4], [5, 6]])
B = np.array([[7, 8, 9], [10, 11, 12]])# 计算乘积
C = matrix_multiply(A, B)print("矩阵A:")
print(A)
print("\n矩阵B:")
print(B)
print("\n乘积矩阵C:")
print(C)

在NumPy中,矩阵乘法通常是利用高度优化的底层库(如BLAS、OpenBLAS或MKL)来执行的,这些库对于大型矩阵运算特别高效。对于两个矩阵A(nxm)和B(mxn)的乘法,其时间和空间复杂度大致如下:

时间复杂度:
矩阵乘法的一般时间复杂度是O(n3),这是因为每个元素C[i][j]都是由A的第i行与B的第j列对应元素相乘后求和得到的,这一过程需要大约n2次乘法和n2次加法。不过,实际的执行时间会受到具体实现算法的影响,比如分块矩阵乘法、Strassen算法(对于非常大的矩阵有更优的时间复杂度O(nlog2(7))约为O(n^2.81))以及硬件加速等因素。NumPy使用的底层库往往实现了高度优化的算法,因此实际运行速度通常远快于最坏情况下的理论复杂度。

空间复杂度:
空间复杂度主要考虑执行矩阵乘法所需的额外存储空间。对于基本的矩阵乘法算法,主要需要存储输入矩阵A和B以及输出矩阵C,因此空间复杂度是O(nm + mn + n*n) = O(n^2 + 2nm)。在实际应用中,由于C矩阵必须被创建来存储结果,所以至少需要O(n2)的空间(当n>m时,或者具体说是max(n,m)2)。不过,这个分析没有考虑算法内部可能使用的临时存储空间,但通常这些开销会被底层库优化以减少额外内存需求。

总结来说,虽然理论上的时间复杂度较高,但得益于高效的库和算法,NumPy中的矩阵乘法在实践中表现得非常高效。而空间复杂度主要取决于输出矩阵的大小,以及算法实现的具体细节。

解题思路二:三个for循环

def matrix_multiply(A, B):"""计算矩阵A和B的乘积。参数:A -- nxm矩阵 (二维列表)B -- mxn矩阵 (二维列表)返回:C -- 乘积矩阵,大小为nxn (二维列表)"""# 获取矩阵的维度n, m = len(A), len(B[0])p = len(B)# 检查矩阵A的列数是否等于矩阵B的行数if m != p:raise ValueError("矩阵A的列数必须与矩阵B的行数相等")# 初始化乘积矩阵CC = [[0 for _ in range(n)] for _ in range(n)]# 执行矩阵乘法for i in range(n):for j in range(n):for k in range(m):C[i][j] += A[i][k] * B[k][j]return C# 示例:创建两个矩阵并进行乘法运算
A = [[1, 2, 3],[4, 5, 6]]B = [[7, 8],[9, 10],[11, 12]]# 计算乘积
C = matrix_multiply(A, B)print("矩阵A:")
for row in A:print(row)
print("\n矩阵B:")
for row in B:print(row)
print("\n乘积矩阵C:")
for row in C:print(row)

时间复杂度:O(n2m)
空间复杂度:O(n2)

解题思路三:分块矩阵乘法, 利用多线程或多进程

对于较大的矩阵乘法,虽然基本的三重循环方法直观且易于理解,但在实践中可能不是最高效的。除了使用NumPy这样的专门库之外,还有一些其他方法可以提高效率,特别是对于大规模数据集。这里介绍两种常见的改进方法:

分块矩阵乘法是将大矩阵分割成小块,对这些小块分别进行乘法运算,然后再合并结果。这种方法可以更好地利用现代CPU的缓存,减少内存访问的延迟,从而提高计算效率。以下是一个简单的分块矩阵乘法的Python示例:

def block_matrix_multiply(A, B, block_size=100):"""分块矩阵乘法实现。参数:A, B -- 输入矩阵block_size -- 分块大小,默认为100返回:C -- 乘积矩阵"""n, m = len(A), len(B[0])p = len(B)if m != p:raise ValueError("矩阵A的列数必须与矩阵B的行数相等")C = [[0]*n for _ in range(n)]for i in range(0, n, block_size):for j in range(0, n, block_size):for k in range(0, m, block_size):# 确保不会超出矩阵边界i_end = min(i + block_size, n)j_end = min(j + block_size, n)k_end = min(k + block_size, m)for ii in range(i, i_end):for jj in range(j, j_end):for kk in range(k, k_end):C[ii][jj] += A[ii][kk] * B[kk][jj]return C

对于非常大的矩阵,可以利用Python的多线程或多进程能力来并行计算不同部分的乘积,然后合并结果。这在多核处理器上尤其有效。使用concurrent.futures模块可以简化这一过程。然而,要注意的是,Python的全局解释器锁(GIL)可能限制了多线程在CPU密集型任务中的性能提升,此时多进程可能是更好的选择。

这两种方法可以在一定程度上提高计算效率,尤其是对于大规模数据集,但它们也引入了更复杂的代码和潜在的同步开销。在实际应用中,如果性能是关键因素,使用像NumPy这样成熟的数学库仍然是最佳选择,因为这些库已经内置了高度优化的并行计算和分块技术。


创作不易,观众老爷们请留步… 动起可爱的小手,点个赞再走呗 (๑◕ܫ←๑)
欢迎大家关注笔者,你的关注是我持续更博的最大动力


原创文章,转载告知,盗版必究



在这里插入图片描述


在这里插入图片描述
♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/362849.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试突击:Java 集合知识体系梳理

本文已收录于:https://github.com/danmuking/all-in-one(持续更新) 前言 哈喽,大家好,我是 DanMu。在 Java 开发中,集合类对象绝对是被使用最频繁的对象之一。因此,深入了解集合类对象的底层数…

World of Warcraft T2.5

World of Warcraft T2.5 猎人和术士套装需要的材料,好多啊,废墟和神殿打材料 猎人: 术士:

k8s学习--k8s群集部署zookeeper应用及详细解释

文章目录 zookeeper什么是zookeeper基本概念主要功能工作原理使用场景优点缺点 k8s集群部署zookeeper环境一、zookeeper部署YAML资源清单准备二、zookeeper部署及部署验证三、zookeeper应用验证 zookeeper 什么是zookeeper ZooKeeper 是一个开源的分布式协调服务,…

多线程(基础)

前言👀~ 上一章我们介绍了什么是进程,对于进程就了解那么多即可,我们作为java程序员更关注线程,线程内容比较多,所以我们要分好几部分才能讲完 目录 进程的缺点 多线程(重要) 进程和线程的区…

数据结构速成--树和二叉树

由于是速成专题,因此内容不会十分全面,只会涵盖考试重点,各学校课程要求不同 ,大家可以按照考纲复习,不全面的内容,可以看一下小编主页数据结构初阶的内容,找到对应专题详细学习一下。 气死了…

昇思25天学习打卡营第4天|数据集Dataset

数据集 Dataset 介绍 之前说过,MindSpore是基于Pipeline,通过Dataset和Transformer进行数据处理。Dataset在其中是用来加载原始数据的。mindSpore提供了数据集加载接口,可以加载文本、图像、音频等,同时也可以自定义加载接口。此…

乾坤微服务的使用

前言: 在这里整理下用乾坤来开发微服务的一些资料。 使用好处: 使用乾坤可以实现什么效果呢?众所周知,前端的框架五花八门,react/vue/angular等各领风骚,那么如果我们有需要把不同技术栈的项目整合起来&…

Vue3学习笔记<->创建第一个vue项目

新建一个项目目录 找一个盘新建一个目录,我这里在D盘创建一个vuedemo目录作为项目存放的目录。使用idea打开目录。   单击ieda底部的按钮“Terminal”,打开命令行窗口,如果命令行窗口当前目录不是“vuedemo”,就切换到“vuedem…

文本分类-RNN-LSTM

1.前言 本节介绍RNN和LSTM,并采用它们在电影评论数据集上实现文本分类,会涉及以下几个知识点。 1. 词表构建:包括数据清洗,词频统计,词频截断,词表构建。 2. 预训练词向量应用:下载并加载Glove的…

Vue2 - 首页登录实现随机验证码组件的封装与实现详解(详细的注释及常见问题汇总)

在网站首页等登录时,随机验证码在现代网络应用中扮演着重要的安全角色。为了帮助开发者轻松集成和使用随机验证码功能,本文将介绍如何利用 Vue.js 2 封装一个简单而功能强大的随机验证码组件。让你能够快速理解并应用这一组件到你的项目中。 一、解决方案 本文提供了完美便捷…

上海计算机考研避雷,25考研慎报

上大计算机一直很热 408考研er重来没有让我失望过,现在上大的专业课是11408,按理说,这个专业课的难度是很高的,但是408er给卷出了新高度,大家可以去上大官网看看今年最新的数据,我也帮大家统计了24年最新的…

Redis集群(Clustering in Redis)工作机制详解

Redis集群工作机制详解 Redis 集群是用于提高 Redis 可扩展性和高可用性的解决方案。 维基百科:Scalability is the property of a system to handle a growing amount of work by adding resources to the system. 可扩展性是系统的一种允许通过增加系统资源来处…

《Windows API每日一练》6.4 程序测试

前面我们讨论了鼠标的一些基础知识,本节我们将通过一些实例来讲解鼠标消息的不同处理方式。 本节必须掌握的知识点: 第36练:鼠标击中测试1 第37练:鼠标击中测试2—增加键盘接口 第38练:鼠标击中测试3—子窗口 第39练&…

Linux Static calls机制

文章目录 前言一、简介二、Background: indirect calls, Spectre, and retpolines2.1 Indirect calls2.2 Spectre (v2)2.3 RetpolinesConsequences 2.4 Static callsHow it works 三、其他参考资料 前言 Linux内核5.10内核版本引入新特性:Static calls。 Static c…

计算机毕业设计hadoop+spark+hive知识图谱医生推荐系统 医生数据分析可视化大屏 医生爬虫 医疗可视化 医生大数据 机器学习 大数据毕业设计

测试过程及结果 本次对于医生推荐系统测试通过手动测试的方式共进行了两轮测试。 (1)第一轮测试中执行了个20个测试用例,通过16个,失败4个,其中属于严重缺陷的1个,属于一般缺陷的3个。 (2&am…

Spark SQL 的总体工作流程

Spark SQL 是 Apache Spark 的一个模块,它提供了处理结构化和半结构化数据的能力。通过 Spark SQL,用户可以使用 SQL 语言或 DataFrame API 来执行数据查询和分析。这个模块允许开发者将 SQL 查询与 Spark 的数据处理能力结合起来,实现高效、优化的数据处理。下面是 Spark S…

Spring Boot中实现定时任务最常用的方法 @Scheduled 注解和 TaskScheduler 接口【包含详情代码】

Spring Boot中实现定时任务最常用的方法 Scheduled 注解和 TaskScheduler 接口【包含详情代码】 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……) 2、学会Oracle数据库入门到入土用法(创作中……) 3、手把手教你开发炫酷的vbs脚本制作(完善中………

CogMG:用大模型解决知识图谱覆盖不足的问题

CogMG:用大模型解决知识图谱覆盖不足的问题 提出背景知识图谱的作用知识覆盖不完整知识更新不对齐 显式分解知识三元组和补全检索增强生成(RAG)和知识更新 框架设计1. 查询知识图谱2. 处理结果3. 知识图谱演化 CogMG 实现3.1 模型和组件问题分…

.NET 漏洞分析 | 某ERP系统存在SQL注入

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

c++智能指针shared_ptr

文章目录 概念1.shared_ptr1.基本使用2.如何获取原始指针3. 指定删除器 2 使用shared_ptr要注意的问题2.1不要用一个原始指针初始化多个shared_ptr2.2. 避免循环引用 小结 概念 C程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。内存…