实验02动态规划算法.docx
- 文档编号:10312931
- 上传时间:2023-02-10
- 格式:DOCX
- 页数:20
- 大小:264.33KB
实验02动态规划算法.docx
《实验02动态规划算法.docx》由会员分享,可在线阅读,更多相关《实验02动态规划算法.docx(20页珍藏版)》请在冰豆网上搜索。
实验02动态规划算法
1120542宇
实验02动态规划算法
[实验目的]
1.掌握动态规划算法的基本方法
2.掌握动态规划算法中最优子结构的分析
3.掌握递归求解最优值的方法
4.掌握最优解的构造.
[预习要求]
1.认真阅读算法设计教材,了解动态规划原理;
2.设计用动态规划算法求解矩阵连乘、最长公共子序列以及电路布线的java程序.
[实验题]
1.给定n个矩阵{A1,A2,…,An},其中,Ai与Ai+1是可乘的,计算这n个矩阵的连乘积。
从中找出一种乘次数最少的计算次序。
2.给定2个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列。
3.在一块电路板的上、下2端分别有n个接线柱。
根据电路设计,要求用导线(i,π(i))将上端接线柱与下端接线柱相连,确定将哪些连线安排在第一层上,使得该层上有尽可能多的连线。
该问题要求确定导线集Nets={(i,π(i)),1≤i≤n}的最大不相交子集。
[实验步骤]
1.设计并实现算法并准备测试用例,修改并调试程序,直至正确为止;
2.应用设计的算法和程序求解问题;
3.将程序整理成功能模块存盘备用.
[实验报告要求]
1.阐述实验目的和实验内容;
2.阐述求解问题的算法原理;
3.提交实验程序的功能模块;
4.记录最终测试数据和测试结果。
[算法分析]
(一)矩阵连乘类
解这个问题的最容易想到的方法是穷举搜索法。
也就是列出所有可能的计算次序,并计算出每一种计算次序相应需要的计算量,然后找出最小者。
然而,这样做计算量太大。
事实上,对于n个矩阵的连乘积,设有P(n)个不同的计算次序。
由于我们可以首先在第k个和第k+1个矩阵之间将原矩阵序列分为两个矩阵子序列,k=1,2,…,n-1;然后分别对这两个矩阵子序列完全加括号;最后对所得的结果加括号,得到原矩阵序列的一种完全加括号方式。
所以关于P(n),我们有递推式如下:
解此递归方程可得,P(n)实际上是Catalan数,即P(n)=C(n-1),其中,
也就是说,P(n)随着n的增长是指数增长的。
因此,穷举搜索法不是一个有效算法。
下面我们来考虑用动态规划法解矩阵连乘积的最优计算次序问题。
此问题是动态规划的典型应用之一。
1.分析最优解的结构
首先,为方便起见,将矩阵连乘积AiAi+1…Aj简记为Ai…j。
我们来看计算A1…n的一个最优次序。
设这个计算次序在矩阵Ak和Ak+1之间将矩阵链断开,1<=k 照此,我们要先计算A1…k和Ak+1…n,然后,将所得的结果相乘才得到A1…n。 显然其总计算量为计算A1…k的计算量加上计算Ak+1…n的计算量,再加上A1…k与Ak+1…n相乘的计算量。 这个问题的一个关键特征是: 计算A1…n的一个最优次序所包含的计算A1…k的次序也是最优的。 事实上,若有一个计算A1…k的次序需要的计算量更少,则用此次序替换原来计算A1…k的次序,得到的计算A1…n的次序需要的计算量将比最优次序所需计算量更少,这是一个矛盾。 同理可知,计算A1…n的一个最优次序所包含的计算矩阵子链Ak+1…n的次序也是最优的。 根据该问题的指标函数的特征也可以知道该问题满足最优化原理。 另外,该问题显然满足无后向性,因为前面的矩阵链的计算方法和后面的矩阵链的计算方法无关。 2.建立递归关系 对于矩阵连乘积的最优计算次序问题,设计算Ai…j,1≤i≤j≤n,所需的最少数乘次数为m[i,j],原问题的最优值为m[1,n]。 ▪当i=j时,Ai…j=Ai为单一矩阵,无需计算,因此m[i,i]=0,i=1,2,…,n; ▪当i 事实上,若计算Ai…j的最优次序在Ak和Ak+1之间断开,i≤k m[i,j]=m[i,k]+m[k+1,j]+pi-1pkpj 由于在计算时我们并不知道断开点A的位置,所以A还未定。 不过k的位置只有j-i个可能,即k∈{i,i+1,…,j-1}。 因此k是这j-i个位置中计算量达到最小的那一个位置。 从而m[i,j]可以递归地定义为: m[i,j]给出了最优值,即计算Ai…j所需的最少数乘次数。 同时还确定了计算Ai…j的最优次序中的断开位置k,也就是说,对于这个k有m[i,j]=m[i,k]+m[k+1,j]+pi-1pkpj。 若将对应于m[i,j]的断开位置k记录在s[i,j]中,则相应的最优解便可递归地构造出来。 3.计算最优值 根据m[i,j]的递归定义(2.1),容易写一个递归程序来计算m[1,n]。 稍后我们将看到,简单地递归计算将耗费指数计算时间。 然而,我们注意到,在递归计算过程中,不同的子问题个数只有θ(n2)个。 事实上,对于1≤i≤j≤n不同的有序对(i,j)对应于不同的子问题。 因此,不同子问题的个数最多只有 个。 由此可见,在递归计算时,许多子问题被重复计算多次。 这也是该问题可用动态规划算法求解的又一显著特征。 用动态规划算法解此问题,可依据递归式(2.1)以自底向上的方式进行计算,在计算过程中,保存已解决的子问题答案,每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免大量的重复计算,最终得到多项式时间的算法。 下面所给出的计算m[i,j]动态规划算法中,输入是序列P={p0,p1,…,pn},输出除了最优值m[i,j]外,还有使 m[i,j]=m[i,k]+m[k+1,j]+pi-1pkpj 达到最优的断开位置k=s[i,j],1≤i≤j≤n。 (二)最长公共子序列的结构 设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk},则 (1)若xm=yn,则zk=xm=yn,且z(k-1)是x(m-1)和y(n-1)的最长公共子序列。 (2)若xm! =yn且zk! =xm,则Z是x(m-1)和Y的最长公共子序列。 (3)若xm! =yn且zk! =yn,则Z是X和y(n-1)的最长公共子序列。 由此可见,2个序列的最长公共子序列包含了这2个序列的前缀的最长公共子序列。 因此,最长公共子序列问题具有最优子结构性质。 子问题的递归结构 由最长公共子序列问题的最优子结构性质建立子问题最优值的递归关系。 用c[i][j]记录序列Xi和Yi的最长公共子序列的长度。 其中,Xi={x1,x2,…,xi};Yj={y1,y2,…,yj}。 当i=0或j=0时,空序列是Xi和Yj的最长公共子序列。 故此时C[i][j]=0。 其它情况下,由最优子结构性质可建立递归关系如下: 由于在所考虑的子问题空间中,总共有θ(mn)个不同的子问题,因此,用动态规划算法自底向上地计算最优值能提高算法的效率 算法的改进 在算法lcsLength和lcs中,可进一步将数组b省去。 事实上,数组元素c[i][j]的值仅由c[i-1][j-1],c[i-1][j]和c[i][j-1]这3个数组元素的值所确定。 对于给定的数组元素c[i][j],可以不借助于数组b而仅借助于c本身在时间内确定c[i][j]的值是由c[i-1][j-1],c[i-1][j]和c[i][j-1]中哪一个值所确定的。 如果只需要计算最长公共子序列的长度,则算法的空间需求可大大减少。 事实上,在计算c[i][j]时,只用到数组c的第i行和第i-1行。 因此,用2行的数组空间就可以计算出最长公共子序列的长度。 进一步的分析还可将空间需求减至O(min(m,n))。 (三)电路步线: 记N(i,j)={t|(t,π(t))∈Nets,t≤i,π(t)≤j}.N(i,j)的最大不相交子集为MNS(i,j)Size(i,j)=|MNS(i,j)|。 (1)当i=1时 (2)当i>1时 ① j<π(i)。 此时,(i,π(i))不属于N(i,j)。 故在这种情况下,N(i,j)=N(i-1,j),从而Size(i,j)=Size(i-1,j)。 ② j≥π(i)。 此时,若(i,π(i))∈MNS(i,j),则对任意(t,π(t))∈MNS(i,j)有t 在这种情况下MNS(i,j)-{(i,π(i))}是N(i-1,π(i)-1)的最大不相交子集。 否则,子集MNS(i-1,π(i)-1)∪{(i,π(i))}包含于N(i,j)是比MNS(i,j)更大的N(i,j)的不相交子集。 这与MNS(i,j)的定义相矛盾。 若(i,π(i))不属于MNS(i,j),则对任意(t,π(t))∈MNS(i,j),有t 从而MNS(i,j)包含于N(i-1,j),因此,Size(i,j)≤Size(i-1,j)。 另一方面,MNS(i-1,j)包含于N(i,j),故又有Size(i,j)≥Size(i-1,j),从而Size(i,j)=Size(i-1,j)。 3、递推关系 电路布线问题的最优值为Size(n,n)。 由该问题的最优子结构性质可知,子问题最优值的递归关系如下: [参考] //矩阵连乘类 publicclassMatrix{ privateintMN;//表示矩阵链中矩阵的数目 privateint[]p;//存放各个矩阵的维数 privateint[][][]A;//存放要进行连乘的多个矩阵 privateint[][]m;//用来存放Ai到Aj的最少乘次数 privateint[][]s;//用来存放Ai到Aj的最后断开位置 // publicMatrix() { MN=0; p=newint[MN]; } //构造函数,L为矩阵的数目 publicMatrix(intL) { MN=L; p=newint[MN+1]; A=newint[MN][][]; m=newint[MN+1][MN+1]; s=newint[MN+1][MN+1]; //随机生成连乘矩阵的维数[1-11] for(inti=0;i<=MN;i++) { p[i]=(int)Math.round(Math.random()*10)+1; } //随机生成各个矩阵 for(inti=0;i { A[i]=newint[p[i]][p[i+1]]; CreatMatrix(A[i],p[i],p[i+1]); } } //创建矩阵a,维数为m*n privatevoidCreatMatrix(int[][]a,intm,intn) {
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 02 动态 规划 算法