热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

动态规划_算法分析四:动态规划

篇首语:本文由编程笔记#小编为大家整理,主要介绍了算法分析四:动态规划相关的知识,希望对你有一定的参考价值。 一.动态规划基本结构 二.典型例题 2.1  矩阵链问题:给定一个n个

篇首语:本文由编程笔记#小编为大家整理,主要介绍了算法分析四:动态规划相关的知识,希望对你有一定的参考价值。


一.动态规划基本结构

技术图片

 

二.典型例题

 

2.1  矩阵链

问题:给定一个n个矩阵的矩阵链技术图片,矩阵技术图片的维度为技术图片 (1 ≤ in),求一个最优的加括号方案,使得计算矩阵乘积技术图片所需要的标量乘法次数最少。

解法:1.穷举法:

    定义T(N)是顺序的个数,则T(N)=Σ(i=1,N-1)T(i)T(N-i),有catalan数可知,该数呈指数增长。(过于繁杂舍去)

   2.动态规划法:

    下面用动态规划方法来求解矩阵链的最优括号方案,我们还是按照之前提出的4个步骤进行:

    1.刻画一个最优解的结构特征

    2.递归地定义最优解的值

    3.计算最优解的值,通常采用自底向上的方法

    4.利用计算出的信息构造一个最优解接下来按顺序进行这几个步骤,清楚地展示针对本问题每个步骤应如何做。

步骤1:最优括号化方案的最优解结构

动态规划的第一步是寻找最优子结构,然后就可以利用这种子结构从子问题的最优解构造出原问题的最优解。在矩阵链乘法问题中,我们假设A(i)A(i+1)...A(j)的最优括号方案的分割点在A(k)和A(k+1)之间。                    那么,继续对“前缀”子链A(i)A(i+1)..A(k)进行括号化时,我们应该直接采用独立求解它时所得的最优方案。

我们已经看到,一个非平凡(i≠j)的矩阵链乘法问题实例的任何解都需要划分链,而任何最优解都是由子问题实例的最优解构成的。为了构造一个矩阵链乘法问题实例的最优解,我们可以将问题划分为两                    个子问题(A(i)A(i+1)...A(k)和A(k+1)A(k+2)..A(j)的最优括号化问题),求出子问题实例的最优解,然后将子问题的最优解组合起来。我们必须保证在确定分割点时,已经考察了所有可能的划分点,这样就可保                      证不会遗漏最优解。

步骤2:一个递归求解方案
下面用子问题的最优解来递归地定义原问题最优解的代价。对于矩阵链乘法问题,我们可以将对所有1<=i<=j<=n确定A(i)A(i+1)...A(j)的最小代价括号化方案作为子问题。令m[i,j]表示计算矩阵A(i..j)所需标量乘法次数的最小值,那么,原问题的最优解—计算A(1..n)所需的最低代价就是m[1,n]。
我们可以递归定义m[i,j]如下。对于i=j时的平凡问题,矩阵链只包含唯一的矩阵A(i..j)=A(i),因此不需要做任何标量乘法运算。所以,对所有i=1,2,...,n,m[i,i]=0。若i  m[i,j]=m[i,k]+m[k+1,j]+ p(i-1)p(k)p(j)
此递归公式假定最优分割点k是已知的,但实际上我们是不知道。不过,k只有j-i种可能的取值,即k=i,i+1,...,j-1。由于最优分割点必在其中,我们只需检查所有可能情况,找到最优者即可。
因此,A(i)A(i+1)...A(j)的最小代价括号化方案的递归求解公式变为:

①如果i=j,m[i,j]=0
②如果i
m[i,j]的值给出了子问题最优解的代价,但它并未提供足够的信息来构造最优解。为此,我们用s[i,j]保存最优括号化方案的分割点位置k,即使得m[i,j]=m[i,k]+[k+1,j]+p(i-1)p(k)p(j)成立的k值。

步骤3:计算最优代价
现在,我们可以很容易地基于递归公式写出一个递归算法,但递归算法是指数时间的,并不必检查若有括号化方案的暴力搜索方法更好。注意到,我们需要求解的不同子问题的数目是相对较少的:每对满足1<=i<=j<=n 的i和j对应一个唯一的子问题,共有n^2(最少)。递归算法会在递归调用树的不同分支中多次遇到同一个子问题。这种子问题重叠的性质是应用动态规划的另一标识(第一个标识是最优子结构)。
我们采用自底向上表格法代替递归算法来计算最优代价。此过程假定矩阵Ai的规模为p(i-1)×pi(i=1,2,...,n)。它的输入是一个序列p=,其长度为p.length=n+1。过程用一个辅助表m[1..n,1..n]来保存代价m[i,j],用另一个辅助表s[1..n-1,2..n](s[1,2]..s[n-1,n]这里i 对于矩阵A(i)A(i+1)...A(j)最优括号化的子问题,我们认为其规模为链的长度j-i+1。因为j-i+1个矩阵链相乘的最优计算代价m[i,j]只依赖于那么少于j-i+1个矩阵链相乘的最优计算代价。因此,算法应该按长度递增的顺序求解矩阵链括号化问题,并按对应的顺序填写表m。

技术图片

 

 n=6和矩阵规模如下表时,MATRIX_CHAIN_ORDER计算出m表和s表

 技术图片

 

 

 6个矩阵相乘所需的最少标量乘法运算次数为m[1,6]=15125。表中有些表项被标记了深色阴影,相同的阴影表示在第13行中计算m[2,5]时同时访问了这些表项:

技术图片

 

 

 

 

步骤4:构造最优解
虽然MATRIX_CHAIN_ORDER求出了计算矩阵链乘积所需的最少标量乘法运算次数,但它并未直接指出如何进行这种最优代价的矩阵链乘法计算。表s[i,j]记录了一个k值,指出A(i)A(i+1)...A(j)的最优括号化方案的分割点应在A(k)和A(k+1)之间。
因此,我们A(1..n)的最优计算方案中最后一次矩阵乘法运算应该是以s[1,n]为分界的A(1..s[1,n])*A(s[1,n]+1..n)。我们可以用相同的方法递归地求出更早的矩阵乘法的具体计算过程,因为s[1,s[1,n]]指出了计算A(1..s[1,n])时应进行的最后一次矩阵乘法运行;s[s[1,n]+1,n]指出了计算A(s[1,n]+1..n)时应进行的最后一次矩阵乘法运算。

2.3  找零钱

问题:假设只有 1 分、 2 分、五分、 1 角、二角、 五角、 1 元的硬币。在超市结账时,如果需要找零钱,收银员希望将最少的硬币数找给顾客。那么,给定需要找的零钱数目,如何求得最少的硬币数呢?

解法:1.贪心算法:(实际上并不成立):贪心算法要依靠贪心性质

  例如: 1  80 60    目标:160  显然贪心性质不成立。

   2.动态规划:

          应用动态规划方法我们还是按照之前提出的4个步骤进行:

    1.刻画一个最优解的结构特征

    2.递归地定义最优解的值

    3.计算最优解的值,通常采用自底向上的方法

    4.利用计算出的信息构造一个最优解接下来按顺序进行这几个步骤,清楚地展示针对本问题每个步骤应如何做。

   

步骤1:最优方案的最优结构

  假设有 a,b,c,d四种币值的零钱,现在要找的钱数为N:

  我们的思路是:a,b,c,d中的一种凑N,或者其中的两种凑N,或者其中的三种凑N,或者四种凑N.

  即定义函数 F(k,y)表示前K种零钱币值达到y所要的最少数目

步骤2:一个递归求解方案
  F(k,y)怎样求呢? 我们不妨为他找个帮手以F(4,100)为例,我们可以找到F(3,100)F(4,100-v4*n)+n,将两个函数进行对比选取较小的那一个。由此可知,

  F(k,y)= min(F(k-1,y),F(k,vk*n)+n);

步骤3:计算最优代价








































1234100(共一百列)
前1种:10050 。。。25basis
2    
4    
5   最优解

                                              F(n) = O(n.M).O(1) 

步骤4:构造最优解

  如步骤三种求出“最优解”

 

2.4  最长子序列

问题:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列,使得对所有的j=0,1,…,k-1,有xij=yj。例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。

解法:

步骤1:最优方案的最优结构

     考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bm-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。不难证明有以下性质:

(1) 如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;

(2) 如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;

(3) 如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。

这样,在找A和B的公共子序列时,如有am-1=bn-1,则进一步解决一个子问题,找“a0,a1,…,am-2”和“b0,b1,…,bm-2”的一个最长公共子序列;如果am-1!=bn-1,则要解决两个子问题,找出“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列和找出“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列,再取两者中较长者作为A和B的最长公共子序列。

引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。

步骤2:一个递归求解方案

引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。

问题的递归式写成:

技术图片

步骤3:计算最优代价

回溯输出最长公共子序列过程:

技术图片

 

算法分析:
由于每次调用至少向上或向左(或向上向左同时)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时开始返回。返回时与递归调用时方向相反,步数相同,故算法时间复杂度为Θ(m + n)。

步骤4:构造最优解

利用步骤三中的图,从右下角开始寻找。

2.5  “0”“1”背包

问题:给定n中物品和一个背包,物品i的重量为wi,体积为ci,价值为vi, 如何选择装入背包的物品,使得装入背包的物品总价值最大?

解法:

在解决问题之前,为描述方便,首先定义一些变量:Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值,同时背包问题抽象化(X1,X2,…,Xn,其中 Xi 取0或1,表示第 i 个物品选或不选)。

1、建立模型,即求max(V1X1+V2X2+…+VnXn);

2、寻找约束条件,W1X1+W2X2+…+WnXn

3、寻找递推关系式,面对当前商品有两种可能性:

包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);
还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}。
其中V(i-1,j)表示不装,V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i),但价值增加了v(i);

由此可以得出递推关系式:

j j>=w(i) V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}
这里需要解释一下,为什么能装的情况下,需要这样求解(这才是本问题的关键所在!):

可以这么理解,如果要到达V(i,j)这一个状态有几种方式?

肯定是两种,第一种是第i件商品没有装进去,第二种是第i件商品装进去了。没有装进去很好理解,就是V(i-1,j);装进去了怎么理解呢?如果装进去第i件商品,那么装入之前是什么状态,肯定是V(i-1,j-w(i))。由于最优性原理(上文讲到),V(i-1,j-w(i))就是前面决策造成的一种状态,后面的决策就要构成最优策略。两种情况进行比较,得出最优。

4、填表


推荐阅读
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文详细解析了JavaScript中相称性推断的知识点,包括严厉相称和宽松相称的区别,以及范例转换的规则。针对不同类型的范例值,如差别范例值、统一类的原始范例值和统一类的复合范例值,都给出了具体的比较方法。对于宽松相称的情况,也解释了原始范例值和对象之间的比较规则。通过本文的学习,读者可以更好地理解JavaScript中相称性推断的概念和应用。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 给定一个二维平面上的一些点,通过计算曼哈顿距离,求连接所有点的最小总费用。只有任意两点之间有且仅有一条简单路径时,才认为所有点都已连接。给出了几个示例并给出了对应的输出。 ... [详细]
  • 电脑公司win7剪切板位置及使用方法
    本文介绍了电脑公司win7剪切板的位置和使用方法。剪切板一般位于c:\windows\system32目录,程序名为clipbrd.exe。通过在搜索栏中输入cmd打开命令提示符窗口,并输入clip /?即可调用剪贴板查看器。赶紧来试试看吧!更多精彩文章请关注本站。 ... [详细]
  • 本文介绍了如何将CIM_DateTime解析为.Net DateTime,并分享了解析过程中可能遇到的问题和解决方法。通过使用DateTime.ParseExact方法和适当的格式字符串,可以成功解析CIM_DateTime字符串。同时还提供了关于WMI和字符串格式的相关信息。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • Excel数据处理中的七个查询匹配函数详解
    本文介绍了Excel数据处理中的七个查询匹配函数,以vlookup函数为例进行了详细讲解。通过示例和语法解释,说明了vlookup函数的用法和参数的含义,帮助读者更好地理解和运用查询匹配函数进行数据处理。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
author-avatar
you是was的was
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有