动态规划之矩阵连乘
时间:2022-05-08
本文章向大家介绍动态规划之矩阵连乘,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2 ,…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。
例如:
A1={30x35} ; A2={35x15} ;A3={15x5} ;A4={5x10} ;A5={10x20} ;A6={20x25} ;
结果为:((A1(A2A3))((A4A5)A6)) 最小的乘次为15125。
原问题为n个矩阵连乘,将原问题分解为子问题,即当n等于1,2,3.....时。
n==1时,单一矩阵,不需要计算。最小乘次为0
n==2时,根据n==1时的结果,遍历计算出每相邻两个矩阵的最小乘次
n==3时,根据n==1和n==2时的结果,此时已经求出每相邻1个、2个矩阵的最小乘次,遍历计算出该相邻三个矩阵的最小乘次
依次类推……
当n==n时,根据n==1、2、……n-1时的结果,此时已经求出每相邻1个、2个、3个……n-1个矩阵的最小乘次,由此求出n==n时的最小乘次
每当n增加1时,就利用已求出的子结构来求解此时的最优值。
数学描述如下:
设矩阵Ai的维数为Pi × Pi+1。
设A[i:j]为矩阵AiAi+1....Aj的连乘积,即从Ai到Aj的连乘积,其中,0 <= i <= j <= n-1
设m[i][j]为计算A[i:j]的最小乘次,所以原问题的最优值为m[0][n-1]。
当 i==j 时,单一矩阵,无需计算。m[i][i]=0,i=0,1,....n-1
当 i < j 时,利用最优子结构,计算m[i][j]。即寻找断开位置k(i <= k < j),使得m[i][k]+m[k+1][j]+Pi*Pk+1*Pj+1最小。
该算法的python实现:
1 # coding=gbk
2 # 矩阵连乘问题
3 __author__ = 'ice'
4
5
6 # row_num 每个矩阵的行数
7 class Matrix:
8 def __init__(self, row_num=0, col_num=0, matrix=None):
9 if matrix != None:
10 self.row_num = len(matrix)
11 self.col_num = len(matrix[0])
12 else:
13 self.row_num = row_num
14 self.col_num = col_num
15 self.matrix = matrix
16
17
18 def matrix_chain(matrixs):
19 matrix_num = len(matrixs)
20 count = [[0 for j in range(matrix_num)] for i in range(matrix_num)]
21 flag = [[0 for j in range(matrix_num)] for i in range(matrix_num)]
22 for interval in range(1, matrix_num + 1):
23 for i in range(matrix_num - interval):
24 j = i + interval
25 count[i][j] = count[i][i] + count[i + 1][j] + matrixs[i].row_num * matrixs[i + 1].row_num * matrixs[j].col_num
26 flag[i][j] = i
27 for k in range(i + 1, j):
28 temp = count[i][k] + count[k + 1][j] + matrixs[i].row_num * matrixs[k + 1].row_num * matrixs[j].col_num
29 if temp < count[i][j]:
30 count[i][j] = temp
31 flag[i][j] = k
32 traceback(0, matrix_num - 1, flag)
33 return count[0][matrix_num - 1]
34
35
36 def traceback(i, j, flag):
37 if i == j:
38 return
39 if j - i > 1:
40 print(str(i + 1) + '~' + str(j + 1), end=': ')
41 print(str(i + 1) + ":" + str(flag[i][j] + 1), end=',')
42 print(str(flag[i][j] + 2) + ":" + str(j + 1))
43 traceback(i, flag[i][j], flag)
44 traceback(flag[i][j] + 1, j, flag)
45
46
47 matrixs = [Matrix(30, 35), Matrix(35, 15), Matrix(15, 5), Matrix(5, 10), Matrix(10, 20), Matrix(20, 25)]
48 result = matrix_chain(matrixs)
49 print(result)
50
51 # 1~6: 1:3,4:6
52 # 1~3: 1:1,2:3
53 # 4~6: 4:5,6:6
54 # 15125
- AsyncTask和Handler对比
- sql初始化XML操作
- 给你一根杠杆,撬起万亿的小程序红利市场!
- Flash/Flex学习笔记(43):动量守恒与能量守恒
- Flash/Flex学习笔记(57):实用技巧
- 使用 MEF 轻松实现云部署
- 检测常见ASP.NET配置安全漏洞
- Flash/Flex学习笔记(56):矩阵变换
- js小技巧:tab页切换
- c#字符串操作方法实例
- Android中Fragment+ViewPager的配合使用
- 结合机器学习与生物医学技术,寻找Uber司机出行模式
- ASP.NET MVC 4 - 测试驱动 ASP.NET MVC
- LVS+Keepalived高可用环境部署梳理(主主和主从模式)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ThinkPHP3.2框架自带分页功能实现方法示例
- PHP获取访问设备信息的方法示例
- PHP实现微信提现功能
- PHP实现微信退款功能
- PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
- PHP登录验证功能示例【用户名、密码、验证码、数据库、已登陆验证、自动登录和注销登录等】
- 实现php删除链表中重复的结点
- Yii2.0框架实现带分页的多条件搜索功能示例
- 定位地理位置PHP判断员工打卡签到经纬度是否在打卡之内
- PHP APP微信提现接口代码
- thinkPHP5.1框架路由::get、post请求简单用法示例
- Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
- Python爬虫实例——scrapy框架爬取拉勾网招聘信息
- php实现微信企业转账功能
- Laravel框架模型的创建及模型对数据操作示例