实现矩阵连乘积(动态规划)

简介: 实现矩阵连乘积(动态规划)

实现矩阵连乘积

题目
给定n个矩阵{A1,A2,…,An},其中A(i)与A(i+1)是可乘的,i=1,2…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。

问题分析

算法分析
RecurMatrixChain:A1,A2,…,An可乘。

令A1:p0xp1

A2:p1xp2

A3:p2xp3

......

An:An-1xAn

注:以上数字均为下标

当n=2,A1A2:p0xp1xp2

当n=3,A1A2A3,此时根据矩阵乘法的结合律可分两种情况,去最优解即取要的数乘次数最少的:

A1(A2A3):p1xp2xp3+p0xp1xp3(其中p1xp2xp3是A2A3的数乘次数,p0xp1xp3是p1和A2A3乘积结果后新的矩阵的数乘次数)
(A1A2)A3:p0xp1xp2+p0xp2xp3(其中p0xp1xp2是A1A2的数乘次数,p0xp1xp3是p3和A1A2乘积结果后新的矩阵的数乘次数)
令f(n)为求解矩阵连乘积需要的最少数乘次数

f(n)=min{f(k)+f(n-k)+p0xpkxpn}

f(k)+f(n-k)是拆分,p0xpkxpn是合并

i<=k<j,假设在第k位置上找到最优解,则问题变成了两个子问题(Ai...Ak)(Ak+1...Aj)

用mi表示矩阵连乘的最优值,则初始状态为mi,j,最终状态为m[1,n]

用si记录断开位置

时间复杂度
p(n)=O(n^3)

代码实现

//重叠子问题的递归最优解
 
//A1 30*35 A2 35*15 A3 15*5 A4 5*10 A5 10*20 A6 20*25
//p[0-6]={30,35,15,5,10,20,25}
#include <iostream>
using namespace std;
int RecurMatrixChain(int i, int j, int **s, int *p); //递归求最优解
void Traceback(int i, int j, int **s); //构造最优解
 
int main() {
    int L = 7;
    int p[L] = {30, 35, 15, 5, 10, 20, 25};
    int **s = new int *[L];
 
    for (int i = 0; i < L; i++) {
        s[i] = new int[L];
    }
 
    cout << "矩阵的最少计算次数为:" << RecurMatrixChain(1, 6, s, p) << endl;
    cout << "矩阵最优计算次序为:" << endl;
    Traceback(1, 6, s);
    return 0;
}
 
int RecurMatrixChain(int i, int j, int **s, int *p) {
    if (i == j)
        return 0;
 
    int u = RecurMatrixChain(i, i, s, p) + RecurMatrixChain(i + 1, j, s, p) + p[i - 1] * p[i] * p[j];
    s[i][j] = i;
 
    for (int k = i + 1; k < j; k++) {
        int t = RecurMatrixChain(i, k, s, p) + RecurMatrixChain(k + 1, j, s, p) + p[i - 1] * p[k] * p[j];
 
        if (t < u) {
            u = t;
            s[i][j] = k;
        }
    }
 
    return u;
}
 
 
 
void Traceback(int i, int j, int **s) {
    if (i == j)
        return;
 
    Traceback(i, s[i][j], s);
    Traceback(s[i][j] + 1, j, s);
    printf("Multiply (A%d and A%d),断开位置是:%d\n", i, j, s[i][j]);
}

执行结果

image.png

动态规划

基本思想
其基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解,经分解得到子问题往往不是互相独立的

举例

你知道两个1相加等于2,问你三个1相加你是拿前面的两个1相加的结果加上1呢,还是再用1+1+1,你肯定会用前面的那种方法对吧,这就是动态规划,(1+1)就是(1+1+1)的子问题,且并不是相互独立,你得到了(1+1)就好得到(1+1+1)了
相关文章
|
Linux 网络安全
linux避免ssh远程超时断开
linux避免ssh远程超时断开
linux避免ssh远程超时断开
|
存储 安全 关系型数据库
【Linux】CentOS-6.8超详细安装教程
【Linux】CentOS-6.8超详细安装教程
687 1
|
Java 数据安全/隐私保护
IoTDB服务安装教程-集群版
IoTDB服务安装教程-集群版
582 0
|
存储 索引 Python
蓝桥杯系列2——python基本语法
蓝桥杯系列2——python基本语法
187 0
|
存储 Kubernetes 监控
一文带你玩转全新采集配置 CRD:AliyunPipelineConfig
相较于 AliyunLogConfig,AliyunPipelineConfig 在配置格式、行为逻辑上做了很大改进,主打灵活、简单、稳定。点击本文,手把手教你如何配置 AliyunPipelineConfig,欢迎大家使用~
37073 120
|
JavaScript
TypeScript——使用npm安装和编译
TypeScript——使用npm安装和编译
176 0
|
前端开发 小程序 应用服务中间件
在服务器上正确配置域名https证书(ssl)及为什么不推荐使用宝塔申请免费ssl证书
在服务器上正确配置域名https证书(ssl)及为什么不推荐使用宝塔申请免费ssl证书
516 4
|
机器学习/深度学习 人工智能 自然语言处理
探索未来:量子计算与人工智能的融合之路
【8月更文挑战第8天】在科技的浪潮中,量子计算和人工智能作为两颗耀眼的星辰,各自拥有改变世界的力量。然而,当这两股力量汇聚时,它们将如何共同塑造未来?本文将带你走进量子计算与人工智能交汇的世界,探讨它们如何相互促进,共同开启技术革新的新篇章。
|
人工智能 自然语言处理 IDE
《AIGC+软件开发新范式》--01.当「软件研发」遇上 AI 大模型(2)
在AI 热度持续上升的当下,阿里云推出AI智能编码助手—通义灵码。通义灵码是一款基于阿里云通义代码大模型打造的智能编码助手,基于海量优秀开源代数据集和编程教科书训练,为开发者带来高效、流畅的编码体验。
342 1
|
存储 编译器 C语言
【C++】string类的使用①(默认成员函数
本文介绍了C++ STL中的`string`类,它是用于方便地操作和管理字符串的类,替代了C语言中不便的字符数组操作。`string`基于`basic_string`模板,提供类似容器的接口,但针对字符串特性进行了优化。学习资源推荐[cplusplus.com](https://cplusplus.com/)。`string`类提供了多种构造函数,如无参构造、拷贝构造、字符填充构造等,以及析构函数和赋值运算符重载。示例代码展示了不同构造函数和赋值运算符的用法。
下一篇
开通oss服务