【动态规划算法】【Python实现】矩阵连乘问题

文章目录

问题描述

  • 给定 n n n个矩阵 A 1 A_{1} A1 A 2 A_{2} A2 ⋯ \cdots A n A_{n} An,其中 A i A_{i} Ai A i + 1 A_{i + 1} Ai+1是可乘的( i = 1 i = 1 i=1 2 2 2 ⋯ \cdots n − 1 n - 1 n1), A i A_{i} Ai的维数为 p i − 1 × p i , i = 1 , 2 , ⋯ , n p_{i - 1} \times p_{i} , i = 1 , 2 , \cdots , n pi1×pi,i=1,2,,n,确定这 n n n个矩阵的连乘积 A 1 A 2 ⋯ A n A_{1} A_{2} \cdots A_{n} A1A2An的计算次序,使得以此计算矩阵连乘积需要的数乘次数最少

穷举搜索法

  • 对于 n n n个矩阵的连乘积,设有不同的计算次序 P ( n ) P(n) P(n)
  • 可以先在第 k k k个( k = 1 k = 1 k=1 2 2 2 ⋯ \cdots n − 1 n - 1 n1)和第 k + 1 k + 1 k+1个矩阵之间将原矩阵序列分为两个矩阵子序列,然后分别对这两个矩阵子序列完全加括号,最后对所得的结果加括号,得到原矩阵序列的一种完全加括号方式
  • P ( n ) P(n) P(n)递归方程

P ( n ) = { 1 , n = 1 ∑ k = 1 n − 1 P ( k ) P ( n − k ) , n > 1 P(n) = \begin{cases} 1 , & n = 1 \\ \displaystyle\sum\limits_{k = 1}^{n - 1}{P(k) P(n - k)} , & n > 1 \end{cases} P(n)= 1,k=1n1P(k)P(nk),n=1n>1

    • P ( n ) P(n) P(n)实际上是 C a t a l a n Catalan Catalan数,即 P ( n ) = C ( n − 1 ) P(n) = C(n - 1) P(n)=C(n1) C ( n ) = 1 n + 1 ( 2 n n ) = Ω ( 4 n / n 3 / 2 ) C(n) = \cfrac{1}{n + 1} \left(\begin{matrix} 2n \\ n \end{matrix}\right) = \Omega(4^{n} / n^{3 / 2}) C(n)=n+11(2nn)=Ω(4n/n3/2) P ( n ) P(n) P(n)是随 n n n的增长呈指数增长的

动态规划算法

分析最优解的结构
  • 考察计算 A [ 1 : n ] A[1 : n] A[1:n]的最优计算次序
  • 设这个计算次序在矩阵 A k ( 1 ≤ k < n ) A_{k} (1 \leq k < n) Ak(1k<n) A k + 1 A_{k + 1} Ak+1之间将矩阵链断开
  • 计算 A [ 1 : n ] A[1 : n] A[1:n]的最优次序所包含的计算矩阵子链 A [ 1 : k ] A[1 : k] A[1:k] A [ k + 1 : n ] A[k + 1 : n] A[k+1:n]的次序也是最优的
    • 如果计算 A [ 1 : k ] A[1 : k] A[1:k]的次序需要的计算量更少,则用此次序替换原来计算 A [ 1 : k ] A[1 : k] A[1:k]的次序,得到的计算 A [ 1 : n ] A[1 : n] A[1:n]的计算量将比最优次序所需计算量更少,这是一个矛盾
  • 矩阵连乘积计算次序问题的最优解包含其子问题的最优解,这种性质称为最优子结构性质
建立递归关系
  • 设计算 A [ i : j ] ( 1 ≤ i ≤ j ≤ n ) A[i : j] (1 \leq i \leq j \leq n) A[i:j](1ijn)所需的最少数乘次数为 m [ i ] [ j ] m[i][j] m[i][j]
  • i = j i = j i=j时, m [ i ] [ i ] = 0 ( i = 1 , 2 , ⋯ , n ) m[i][i] = 0 (i = 1 , 2 , \cdots , n) m[i][i]=0(i=1,2,,n)
  • i < j i < j i<j时,若计算 A [ i : j ] A[i : j] A[i:j]的最优次序在 A k ( i ≤ k < j ) A_{k} (i \leq k < j) Ak(ik<j) A k + 1 A_{k + 1} Ak+1之间断开,则 m [ i ] [ j ] = m [ i ] [ k ] + m [ k + 1 ] [ j ] + p i − 1 p k p j m[i][j] = m[i][k] + m[k + 1][j] + p_{i - 1} p_{k} p_{j} m[i][j]=m[i][k]+m[k+1][j]+pi1pkpj
  • 将对应 m [ i ] [ j ] m[i][j] m[i][j]的断开位置 k k k记为 s [ i ] [ j ] s[i][j] s[i][j]
m [ i ] [ j ] m[i][j] m[i][j]递归方程

m [ i ] [ j ] = { 0 , i = j min ⁡ i ≤ k < j { m [ i ] [ k ] + m [ k + 1 ] [ j ] + p i − 1 p k p j } , i < j m[i][j] = \begin{cases} 0 , & i = j \\ \min\limits_{i \leq k < j}{\set{m[i][k] + m[k + 1][j] + p_{i - 1} p_{k} p_{j}}} , & i < j \end{cases} m[i][j]= 0,ik<jmin{m[i][k]+m[k+1][j]+pi1pkpj},i=ji<j

计算最优值
  • 对于 1 ≤ i ≤ j ≤ n 1 \leq i \leq j \leq n 1ijn不同的有序对 ( i , j ) (i , j) (i,j)对应不同的子问题
  • 不同子问题的个数最多只有 ( n 2 ) + n = θ ( n 2 ) \left(\begin{matrix} n \\ 2 \end{matrix}\right) + n = \theta(n^{2}) (n2)+n=θ(n2)
构造最优解
  • s [ i ] [ j ] s[i][j] s[i][j]中的数表明,计算矩阵链 A [ i : j ] A[i : j] A[i:j]的最佳方式是在矩阵 A k A_{k} Ak A k + 1 A_{k + 1} Ak+1之间断开,即最优加括号方式为 ( A [ i : k ] ) ( A [ k + 1 : j ] ) (A[i : k])(A[k + 1 : j]) (A[i:k])(A[k+1:j])
Python实现
def matrix_chain_order(p):n = len(p) - 1  # 矩阵的数量m = [[float('inf')] * (n + 1) for _ in range(n + 1)]  # 存储最小乘法次数的矩阵s = [[0] * (n + 1) for _ in range(n + 1)]  # 存储最佳分割位置的矩阵# 对角线上的子问题, 乘法次数为 0for i in range(1, n + 1):m[i][i] = 0# l 表示子问题的规模for l in range(2, n + 1):for i in range(1, n - l + 2):j = i + l - 1for k in range(i, j):# 计算 m[i][j] 的值q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]if q < m[i][j]:m[i][j] = qs[i][j] = kreturn m, sdef print_optimal_parens(s, i, j):if i == j:print(f'A{i}', end='')else:print('(', end='')print_optimal_parens(s, i, s[i][j])print_optimal_parens(s, s[i][j] + 1, j)print(')', end='')matrix_sizes = [30, 35, 15, 5, 10, 20, 25]m, s = matrix_chain_order(matrix_sizes)n = len(matrix_sizes) - 1print('最佳乘法顺序:', end='')
print_optimal_parens(s, 1, n)
print()minimum_multiplications = m[1][n]
print('最小乘法次数:', minimum_multiplications)
最佳乘法顺序:((A1(A2A3))((A4A5)A6))
最小乘法次数: 15125
时间复杂性
  • 三重循环的总次数为 O ( n 3 ) O(n^{3}) O(n3),计算时间上界为 O ( n 3 ) O(n^{3}) O(n3)

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

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

相关文章

STM32中SysTick系统滴答定时器用于延时功能的实现及说明

目录 STM32中SysTick系统滴答定时器用于延时功能的实现及说明 delay.h文件 delay.c文件 STM32中SysTick系统滴答定时器用于延时功能的实现及说明 在进行stm32开发的过程中&#xff0c;我们可能会使用到系统滴答定时器SysTick进行延时。系统滴答定时器是一个24位的向下倒计时的…

Python与C#之间的双向管道连接-发送数据

在Python中创建named pipe&#xff1a; import os import time pipe "\\\\.\\pipe\\my_pipe" try: os.mkfifo(pipe) except OSError: pass fifo open(pipe, wb) 在C#中创建named pipe&#xff1a; using System.IO.Pipes; string pipeName "my_pipe&…

学习torchmd分子动力学模拟

TorchMD打算提供一种简单易用的API&#xff0c;用于使用PyTorch进行分子动力学。这使研究人员能够更快地进行力场开发研究&#xff0c;并以PyTorch的简单性和强大性将神经网络潜力无缝集成到动力学中。 TorchMD使用与经典MD代码&#xff08;如ACEMD&#xff09;一致的化学单位&…

引入OSS

前置条件 AccessKey 引入依赖 都是官网上的&#xff1a;https://help.aliyun.com/zh/oss/developer-reference/java-installation?spma2c4g.11186623.0.i16 <!--若是创建项目的时候这个依赖勾选了就不用了--><!--不加启动会报错No active profile set, falling back…

JavaScript之数据类型(2)——复杂类型(object)

object的介绍&#xff1a; 我对于object的理解是和C/C中的结构体一样&#xff0c;是一个自定义的数据类型&#xff0c;我们可以通过多个简单的数据类型来定义一个便于我们使用的新的数据类型。 在网上某佬对于其解释如下&#xff1a; Object类型&#xff0c;我们也称为一个对象…

Windows命令行一键安装、配置WSL的方法

本文介绍在Windows电脑中&#xff0c;通过命令行的方式&#xff0c;快速、方便安装适用于Linux的Windows子系统&#xff08;Windows Subsystem for Linux&#xff0c;WSL&#xff09;的方法。 WSL是由微软开发的一项功能&#xff0c;允许在Windows操作系统上运行Linux发行版系统…

【Linux的文件篇章 - 磁盘文件】

Linux学习笔记---012 Linux之进程程序替换理解1、磁盘文件1.1、文件如何存取的问题1.2、了解磁盘的存储结构1.3、如何找到指定位置的扇区&#xff1f;1.4、对磁盘的存储进行逻辑抽象(了解OS对磁盘这样的硬件设备的抽象与管理) 2、磁盘级文件系统2.1、Linux文件系统特定2.2、文件…

Ansible--Templates 模块 Tags模块 Roles模块

一 Templates 模块 ①Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件&#xff0c;可看作一个编译过的模 板文件&#xff0c;用来产生目标文本&#xff0c;传递Python的变量给模板去替换模板中的标记。 ②在配置文件中&#xff0c;会有一些数据&#xff08;如…

Java毕设之基于SpringBoot的在线拍卖系统

运行环境 开发语言:java 框架:springboot&#xff0c;vue JDK版本:JDK1.8 数据库:mysql5.7(推荐5.7&#xff0c;8.0也可以) 数据库工具:Navicat11 开发软件:idea/eclipse(推荐idea) 系统详细设计 管理员功能模块 管理员登录&#xff0c;管理员通过输入用户名、密码、角色等信…

UE4_Water插件_Buoyancy组件使用

water插件提供了一个浮力Actor蓝图类。 需要注意的几个问题&#xff1a; 1、StaticMesh需要替换根组件。 2、需要模拟物理设置质量。 3、需要添加浮力组件&#xff0c;设置浮力点&#xff0c;应用水中牵引力。 4、最重要的是需要激活——自动启用。 5、调水波长的地方 双击图片…

FreeRTOS学习 -- 任务相关API函数

一、任务创建和删除API函数 FreeRTOS 最基本的功能就是任务管理&#xff0c;而任务管理最基本的操作就是创建和删除任务。 FreeRTOS的任务创建和删除API函数如下&#xff1a; 1、函数 xTaskCreate() 此函数用来创建一个任务&#xff0c;任务需要 RAM 来保存于任务有关的状…

前端js面试题--从字符串中删除删除注释代码

问题&#xff1a;从字符串中删除删除注释代码 描述&#xff1a; solution(weex,rex # and react\nflutter\nnative ssss !hybrid app, [#, !]) 写一个solution函数清除后面参数数组里面的字符串 打印效果 代码1 思路&#xff1a; 将字符全凡是有去掉标志符号的全部添加\n…

Java_File

介绍&#xff1a; File对象表示路径&#xff0c;可以是文件&#xff0c;也可以是文件夹。这个路径可以是存在的&#xff0c;也可以是不存在的&#xff0c;带盘符的路径是绝对路径&#xff0c;不带盘符的路径是相对路径&#xff0c;相对路径默认到当前项目下去找 构造方法&…

基于SSM的校园短期闲置资源置换平台(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的校园短期闲置资源置换平台&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过…

燃气电力瓶装气行业入户安检小程序开发

我们开发的小区业主入户安检小程序&#xff0c;旨在满足燃气、电力以及其他需要入户安检的行业需求。该程序支持自定义安检项目&#xff0c;实现线下实地安检与线上数据保存的完美结合。在安检过程中&#xff0c;我们可以拍照或录像&#xff0c;以确保安检的透明性和可追溯性&a…

渲染管线中光照的计算

文章目录 渲染管线中光照的计算前言法向量朗伯余弦定律漫反射环境光照镜面光照菲涅尔效应 表面粗糙度光照模型平行光源点光源衰减 聚光灯 渲染管线中光照的计算 前言 首先我们来看一下同一个模型在有光与无光下的区别&#xff1a; 无光&#xff1a; 有光 很明显的感知就是…

加速科技突破2.7G高速数据接口测试技术

随着显示面板分辨率的不断提升&#xff0c;显示驱动芯片&#xff08;DDIC&#xff09;的数据接口传输速率越来越高&#xff0c;MIPI、LVDS/mLVDS、HDMI等高速数据接口在DDIC上广泛应用。为满足高速数据接口的ATE测试需求&#xff0c;作为国内少数拥有完全自研的LCD Driver测试解…

【Web前端】定位_浮动_音视频

1、定位 1.1想对定位 相对定位&#xff0c;使用relative&#xff0c;参考点是标签之前的位置&#xff0c;不是相对于父节点、同级节点或浏览器。相对定位通过left、right进行水平偏移&#xff0c;通过top、bottom进行垂直偏移Ieft:表示相对于原本位置的左外边界右移的距离rig…

WebSocket 来单提醒和客户催单功能

一&#xff1a;WebSocket &#xff1a; WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c; 并进行双向数据传输。 HTTP协议和WebSocket协议对比&#…

算法提高之迷宫问题

算法提高之迷宫问题 核心思想&#xff1a;最短路问题 从(n-1,n-1)开始bfs 往前走一个就存入pre数组 之后再遍历pre数组输出 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 1010,M N*N;#define x first#def…