问题描述

给定N 个矩阵 { A 1 , A 2 , A 3 … … A n } ,其中 A i 和 A i + 1 可以相乘的,即: A i
的列数等于 A i + 1行数。如何确定矩阵连乘的计算次序,使得按照此次序计算该矩阵连乘所需要的数乘次数最少?
两个矩阵相乘,它的数乘次数等于前一个矩阵的行数乘以后一个矩阵的列数,当这些矩阵相乘的次序不同时,它的数乘次数的有很大差异的。
输入A = [30, 35, 15, 5, 10, 20, 25],表示6个矩阵
输出最优的数乘次数与最佳分隔位置:最优的数乘次数15125 ; 最佳分隔位置 [3, 1, 5] (分隔点之间的顺序任意)。

如下例题:
例:现有四个矩阵 A , B , C , D 他们的维数分别是:A = 50 ∗ 10 , B = 10 ∗ 40 , C = 40 ∗
30 , D = 30 ∗ 5 ,则连乘 A , B , C , D 共有五种相乘的次序,如:

( A ( ( B C ) D ) ) ,数乘次数为 16000
( ( A B ) ( C D ) ),数乘次数为 36000
( ( A ( B C ) ) D ) ,数乘次数为 34500
( A ( B ( C D ) ) ) ,数乘次数为 10500
( ( ( A B ) C ) D ) ,数乘次数为 87500
我们可以看到,连乘的次序不同,它的数乘次数大区别也是很大的,最少的 10500
次,最多的,87500 次,相差 8 倍之多。所以,寻找一个矩阵连乘的最优分隔方式就显得尤为重要。

使用动态规划解决该问题的思路:

设f[i,j]f[i,j]f[i,j]为矩阵从Ai连乘到Aj的最优数乘值,因此可以写出如下递推公式:

设定一个二维数组m[N][N]表示当前矩阵的连乘次数,比如m[i][j]表示矩阵从Ai连乘到Aj的最优数乘值f[i,j]。
再设定一个二维数组s[N][N]表示当前矩阵连乘时最优分隔位置,比如s[i][j]表示矩阵从Ai连乘到Aj的数乘值最小时的分隔位置,也就是加括号的位置。

接下来画表:
连乘矩阵 :{ A 1 , A 2 , A 3 , A 4 , A 5 , A 6 }

m数组(状态转移矩阵):

  • 在计算该列表中的数据时,我首先可以明确对角线的值即f[i,i]都为0,因为这表示只有一个矩阵,数乘为0
  • 然后我们首先比较容易计算的就是两个矩阵相乘的最优数乘次数,因为两个矩阵相乘,分隔点只有一个,此时对应于主对角线的相邻对角线的值,即m[1,2], m[2,3], m[3,4], m[4,5], m[5,6]。当这几个值计算得到后,我们就可以接着计算三个矩阵相乘的最优数乘值,也就是m[1,3], m[2, 4], m[3, 5], m[4, 6],例如m[1,3]的分隔点有两个,分别是1和2,当分隔点k为1时:f[1,1]+f[2,3]+a0 * a[1] * a[3],当分隔点k为2时:f[1][2]+f[2][3]+a0 * a2 * a3,而m[1,3]取二者的最小值作为最优数乘值。依次类推,因此状态转移是从主对角线依次计算对角线,最终m[1,6]即为所求值。
  • 需要注意,m数组是索引为1的行和列来记录状态的,索引为0的行和列不用,这样做主要为了便去实现上面的推理。
    s数组:

    对于输出最优分隔位置,根据上图可以看出s[1,6]=3,首先在3处分隔,此时变为s[1,3]与s[4,6],s[1,3]在1处分隔,变为s[1,1]与s[2,3],s[4,6]在5处分隔,变为s[4,5]与s[6,6]。所以在1,3,5处分隔。因此可以利用递归完成。

完整代码:


def getIndex(i, j, s):global indexif j - i >= 2:index.append(s[i][j])else:returngetIndex(i, s[i][j], s)getIndex(s[i][j] + 1, j, s)def matrixChain(a):n = len(a)m = [[0 for _ in range(n)] for _ in range(n)]s = [[0 for _ in range(n)] for _ in range(n)]for r in range(2, n):  # r个矩阵连乘for i in range(1, n - r + 1):  # 填补表格的斜线部分的元素对应i标j = i + r - 1  # 填补表格的斜线部分的元素对应的j标m[i][j] = m[i][i] + m[i + 1][j] + a[i - 1] * a[i] * a[j]  # 首先计算第一个分割点,例如[1,3]的第一个分割点为1s[i][j] = i  # 然后将分割点暂时记录for k in range(i + 1, j):  # 计算其他的分隔点的数乘次数temp = m[i][k] + m[k + 1][j] + a[i - 1] * a[k] * a[j]if temp < m[i][j]:  # 如果当前分隔点的数乘次数更优,则更新s[i][j] = km[i][j] = tempgetIndex(1, n-1, s)  # 计算分隔点的位置return m[1][-1], indexif __name__ == "__main__":A = [30, 35, 15, 5, 10, 20, 25]index = []result = matrixChain(A)print(result)

参考:
https://blog.csdn.net/weixin_44952817/article/details/110124596
https://blog.csdn.net/qq_44755403/article/details/105015330

矩阵连乘(动态规划)相关推荐

  1. 矩阵连乘——动态规划算法

    矩阵连乘--动态规划算法 目录 矩阵连乘--动态规划算法 预备知识 前言 问题 应用动态规划方法的步骤 按照步骤分析问题 步骤1:最有括号化方案的结构特征 步骤2:一个递归求解方案 步骤3:计算最优代 ...

  2. 矩阵压缩降维动态规划递推【P1719 最大加权矩形】

    矩阵压缩&降维&动态规划&递推[P1719 最大加权矩形] 题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要 ...

  3. 矩阵快速幂+动态规划=蓝桥杯 垒骰子

    矩阵快速幂+动态规划=蓝桥杯 垒骰子 如果还不知道什么是矩阵快速幂,可以参加我的另一篇文章:矩阵快速幂详解 题目 分析 看到 nnn 的范围达到了 10910^{9}109 ,如果使用暴力搜索是不现实 ...

  4. 矩阵连乘 动态规划_Java动态规划

    1. 介绍 动态规划典型的被用于优化递归算法,因为它们倾向于以指数的方式进行扩展.动态规划主要思想是将复杂问题(带有许多递归调用)分解为更小的子问题,然后将它们保存到内存中,这样我们就不必在每次使用它 ...

  5. 矩阵连乘 动态规划 详解

    矩阵连乘问题----动态规划(转载): 给定n个矩阵{A1,A2,-,An},其中Ai与Ai+1是可乘的,i=1,2-,n-1.如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次 ...

  6. 矩阵连乘 动态规划_利用动态规划解LeetCode第62题:不同路径

    题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ).机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为&q ...

  7. 蓝桥杯:试题 算法训练 采油区域 矩阵前缀和+动态规划+分治+枚举

    资源限制 时间限制:2.0s 内存限制:512.0MB 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整块土地为一个矩形区域,被划分为M× ...

  8. 蓝桥杯:垒骰子【快速幂+矩阵乘法解决动态规划问题】

    先看题: [说实话,这道题是本菜写过最有数学味道的题目,虽然是是简单的矩阵运算和快速幂] 这道题目如果数据范围小的话,那么就是一个简单的dp,为了方便理解,我们先看不考虑时间复杂度的问题,先来看下怎么 ...

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

    目录 实现矩阵连乘积 题目 问题分析 算法分析 时间复杂度 代码实现 执行结果 动态规划 基本思想 举例 个人主页:天寒雨落的博客_CSDN博客-初学者入门C语言,python,数据库领域博主

  10. POJ - 3613 Cow Relays(Floyd思想+矩阵快速幂+动态规划)

    题目链接:点击查看 题目大意:给定一张由T(T<=100)条边构成的无向图,点的编号为1~1000,之间的整数,求从起点S到终点E恰好经过N(N<=1e6)条边(可重复经过)的最短路 题目 ...

最新文章

  1. Linux 中FTP服务的应用(安装配置)
  2. ***WindowsXP常用的七种方法
  3. ejs文件与html,将HTMLWebpackPlugin与EJS文件一起使用
  4. freeRtos学习笔记 (6)软件定时器
  5. TimesTen Warnings and Errors - TT0400 to TT9999 [IDnbsp (
  6. java多线程遇到的问题_关于Java多线程遇到的问题.
  7. 光感是什么_华强北airpods2洛达1536U-001到底升级了什么?
  8. 压缩感知 热身实验 OMP算法Python实现(详细代码注释)
  9. 数值方法:多项式插值
  10. 苏宁易购关键词搜索商品方法
  11. mysql select 列名_Mysql查询出所有列名
  12. 太阳方位角 matlab,太阳天顶角与太阳方位角计算软件V4.1及源码
  13. [分享]来自CSDN的精华网址
  14. 洛谷P1273 有线电视网 题解
  15. C# 重置IE安全等级
  16. 【Vue】报错信息: [WDS] Errors while compiling. Reload prevented.
  17. 解决hotmail邮箱无法登陆问题
  18. IO之 java中BIO NIO AIO原理、区别以及应用
  19. 做期货能不能尽量不止损?
  20. mysql my.cnf 不生效_MySQL修改my.cnf配置不生效的解决方法

热门文章

  1. html文件怎么传到服务器上,如何把html文件上传到云服务器
  2. 6-5 统计二叉树叶子结点个数 (10 分)(C语言版)
  3. kali下java,kali java安装
  4. 用C#语言实现记事本(代码)
  5. 专业测试油耗的软件,油耗软件app哪个好_检测汽车油耗的软件_油耗记录软件车机版...
  6. Struts的增删改查
  7. SIM800C的使用心得
  8. 城市应急指挥系统详情分析及建设方案概述
  9. 常见的一些反爬虫策略(上篇)-Java网络爬虫系统性学习与实战系列(9)
  10. 几种常用的PID控制算法