算法设计与分析第5讲-动态规划上.ppt

  1. 1、本文档共32页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
算法设计与分析第5讲-动态规划上

矩阵连乘问题 给定n个矩阵 ,其中 与 是可乘的,其中: 。考察这n个矩阵的连乘积 由于矩阵乘法满足结合律,所以计算矩阵的连乘可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。 若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。 给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,其中i=1,2 ,…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。 穷举法:列举出所有可能的计算次序,并计算出每一种计算次序相应需要的数乘次数,从中找出一种数乘次数最少的计算次序。 算法复杂度分析: 对于n个矩阵的连乘积,设其不同的计算次序为P(n)。 由于每种加括号方式都可以分解为两个子矩阵的加括号问题:(A1...Ak)(Ak+1…An)可以得到关于P(n)的递推式如下: 矩阵连乘问题 指数级别! 穷举法 动态规划 将矩阵连乘积 简记为A[i:j] ,这里i≤j 考察计算A[i:j]的最优计算次序。设这个计算次序在矩阵Ak和 Ak+1之间将矩阵链断开,i≤kj,则其相应完全加括号方式为 计算量:A[i:k]的计算量加上A[k+1:j]的计算量,再加上A[i:k] 和A[k+1:j]相乘的计算量 矩阵连乘问题 分析最优解的结构 特征:计算A[i:j]的最优次序所包含的计算矩阵子链 A[i:k]和A[k+1:j]的次序也是最优的。 矩阵连乘计算次序问题的最优解包含着其子问题的最优解。这种性质称为最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法求解的显著特征。 怎样理解 最优子结构性质? ——以要得到最大收益的原问题为例 原问题 规模:n 子问题1 规模:n/2 子问题2 规模:n/2 原问题规模特别大,不容易直接处理时,可以将其分解成多个子问题分别处理,然后再合并子问题的解就得到了原问题的解。 合并 子问题的解 子问题 的解 原问题 的解 每个子问题都可能有多种解,在合并子问题的解时,要使原问题获得最大收益的话,会选择子问题的哪个解进行合并? 子问题1的所有解: 解1对应的收益 解2对应的收益 解3对应的收益 子问题2的所有解: 解1对应的收益 解2对应的收益 解3对应的收益 答:应该选择使子问题收益最大的解 否则: 所以说:在原问题的最优解中,它对应的子问题的解是子问题所有解当中最优的,也可以说原问题的最优解包含子问题的最优解,即为最优子结构性质。 建立递归关系 设计算A[i:j],1≤i≤j≤n,所需要的最少数乘次数m[i,j],则原问题的最优值为m[1,n] 当i=j时:A[i:j]=Ai,因此,m[i,i]=0,i=1,2,…,n 当ij时: 可以递归地定义m[i,j]为: 这里 的维数为 的位置只有 种可能 计算最优值 对于1≤i≤j≤n不同的有序对(i,j)对应于不同的子问题。因此,不同子问题的个数最多只有 由此可见,在递归计算时,许多子问题被重复计算多次。这也是该问题可用动态规划算法求解的又一显著特征。 用动态规划算法解此问题,可依据其递归式以自底向上的方式进行计算。在计算过程中,保存已解决的子问题答案。每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免大量的重复计算,最终得到多项式时间的算法 用动态规划法求最优解 A1 A2 A3 A4 A5 A6 30?35 35?15 15?5 5?10 10?20 20?25 用动态规划法求最优解 public static void matrixChain(int [] p, int [][] m, int [][] s) { int n=p.length-1; for (int i = 1; i = n; i++) m[i][i] = 0; for (int r = 2; r = n; r++) for (int i = 1; i = n - r+1; i++) { int j=i+r-1; m[i][j] = m[i+1][j]+ p[i-1]*p[i]*p[j]; s[i][j] = i; for (int k = i+1; k j; k++) { int t = m[i

文档评论(0)

wyjy + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档