实验三动态规划Word格式.docx

上传人:b****5 文档编号:18580996 上传时间:2022-12-28 格式:DOCX 页数:16 大小:79.57KB
下载 相关 举报
实验三动态规划Word格式.docx_第1页
第1页 / 共16页
实验三动态规划Word格式.docx_第2页
第2页 / 共16页
实验三动态规划Word格式.docx_第3页
第3页 / 共16页
实验三动态规划Word格式.docx_第4页
第4页 / 共16页
实验三动态规划Word格式.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

实验三动态规划Word格式.docx

《实验三动态规划Word格式.docx》由会员分享,可在线阅读,更多相关《实验三动态规划Word格式.docx(16页珍藏版)》请在冰豆网上搜索。

实验三动态规划Word格式.docx

(2)建立递归关系:

设计算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

当i<

j时,

可以递归地定义m[i,j]为:

k的位置有j-i种可能

(3)计算最优值:

用动态规划算法解此问题,可依据其递归式以自底向上的方式进行计算。

在计算过程中,保存已解决的子问题答案。

每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免大量的重复计算,最终得到多项式时间的算法

publicstaticvoidMatrixChain(int[]p,int[][]m,int[][]s)

{

intn=p.length-1;

for(inti=1;

i<

=n;

i++)m[i][i]=0;

for(intr=2;

r<

r++)

for(inti=1;

=n-r+1;

i++)

{

intj=i+r-1;

m[i][j]=m[i+1][j]+p[i+1][i][j];

s[i][j]=i;

for(intk=i+1;

k<

j;

k++)

intt=m[i][k]+m[k+1][j]+p[i-1][k][j];

if(t<

m[i][j]){

m[i][j]=t;

s[i][j]=k;

}

}

}

(4)构造最优解:

算法matrixChain记录了构造最优解所需的全部信息。

s[i][j]=k表明计算矩阵链A[i:

j]的最佳方式在矩阵Ak和

Ak+1之间断开,即最优的加括号方式为(A[i:

k])(A[k+1:

j])。

因此,从s[1][n]记录的信息可知计算A[1:

n]的最优加括号

方式为(A[1:

s[1][n]])(A[s[1][n]+1:

n])。

而A[1:

s[1][n]]的最

优加括号方式为

(A[1:

s[1][s[1][n]]])(A[s[1][s[1][n]]+1:

s[1][s[1][n]]])。

同理可以确定A[s[1][n]+1:

n]的最优加括号方式在s[s[1][n]+1][n]处断开。

照此递推下去,最终可以得到A[1:

n]的最优完全加括号方式,

即构造出问题的一个最优解。

publicstaticvoidtraceback(int[][]s,inti,intj)

if(i==j)return;

traceback(s,i,s[i][j]);

traceback(s,s[i][j]+1,j);

System.out.println("

MultiplyA"

+i+"

"

+s[i][j]+"

andA"

+(s[i][j]+1)+"

+j);

1.2程序源码

矩阵连乘代码:

/**

*下面是矩阵连乘问题的动态规划算法

*假设有6个矩阵:

*A1A2A3A4A5A6

*30*3535*1515*55*1010*2020*25则matrixChain为

*{30,35,15,5,10,20,25}结果为

*((A1*(A2*A3))*((A4*A5)*A6))

*@authorzhanlingxia

*/

packagejuzhenliancheng;

publicclassjuzhenliancheng{

publicstaticvoidmain(String[]args){

int[]p={30,35,15,5,10,20,25};

//矩阵的维数存放于数组p中

matrixMultiply(p);

}

//矩阵连乘

publicstaticvoidmatrixMultiply(int[]p){

intdimen=p.length;

int[][]m=newint[dimen][dimen];

//定义了存放最优值数组m

int[][]s=newint[dimen][dimen];

//定义了记录断开位置的数组s

MatrixChain(p,m,s);

最优乘法次数:

"

+m[1][dimen-1]);

划分规则为:

);

traceback(s,1,dimen-1);

/*1:

首先计算出m[i][i]

2:

然后根据递归式按矩阵链长递增的方式以此计算m[i][i+1]i=1,2,3.。

3:

计算m[i][j]时,只要用到m[i][k]和m[k+1][j]*/

//计算单一矩阵

//根据递归式按矩阵链长递增的方式以此计算m[i][i+1]i=1,2,3.。

m[i][j]=m[i+1][j]+p[i+1]*p[i]*p[j];

intt=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];

//更新m[i][j],s[i][j]的值

m[i][j])

{

//按算法MatrixChain计算出断点矩阵s指示的加括号方式

publicstaticvoidtraceback(int[][]s,inti,intj)

{

if(i==j)return;

traceback(s,i,s[i][j]);

traceback(s,s[i][j]+1,j);

System.out.println("

}

1.3实验结论

1.4心得体会

算法设计真的需要逻辑思维,能得到结果挺开心的。

2:

最长公共子序列

2.1算法设计思想

(1)

设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk},则

若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列。

若xm≠yn且zk≠xm,则Z是Xm-1和Y的最长公共子序列。

若xm≠yn且zk≠yn,则Z是X和Yn-1的最长公共子序列

(2)建立递归关系:

由最长公共子序列问题的最优子结构性质建立子问题最优值的递归关系。

用c[i][j]记录序列和的最长公共子序列的长度。

其中,Xi={x1,x2,…,xi};

Yj={y1,y2,…,yj}。

当i=0或j=0时,空序列是Xi和Yj的最长公共子序列。

故此时C[i][j]=0。

其他情况下,由最优子结构性质可建立递归关系如下:

算法lcsLength以序列X={x1,x2…xm}和Y={y1,y2…ym}作为输入。

输出两个数组c和b。

其中,c[i][j]存储Xi和Yj的最长公共子序列的长度,b[i][j]记录c[i][j]的值是由哪一个子问题的解得到的,问题的最优值存放于c[m][n]中

publicstaticintlcsLength(char[]x,char[]y,int[][]b)

intm=x.length-1;

intn=y.length-1;

int[][]c=newint[m+1][n+1];

=m;

i++)c[i][0]=0;

i++)c[0][i]=0;

for(intj=1;

j<

j++)

if(x[i]==y[j])

{

c[i][j]=c[i-1][j-1]+1;

b[i][j]=1;

}

elseif(c[i-1][j]>

=c[i][j-1])

c[i][j]=c[i-1][j];

b[i][j]=2;

else

c[i][j]=c[i][j-1];

b[i][j]=3;

returnc[m][n];

publicstaticvoidlcs(inti,intj,char[]x,int[][]b)

if(i==0||j==0)return;

if(b[i][j]==1){

lcs(i-1,j-1,x,b);

System.out.print(x[i]);

elseif(b[i][j]==2)lcs(i-1,j,x,b);

elselcs(i,j-1,x,b);

2.2程序源码

最长公共子序列代码:

*下面是最长公共子序列问题的动态规划算法

*char[]x={'

A'

'

B'

C'

D'

};

*char[]y={'

*打印结果为CAB

packagezuichanggonggongzixulie;

publicclasszuichanggonggongzixulie{

/*计算最优值

c[i][j]存储Xi和Yi的最长公共子序列的长度

b[i][j]记录c[i][j]的值是由最长公共子序列*/

publicstaticintlcsLength(char[]x,char[]y,int[][]b)

//空序列最长公共子序列

//对角线+1

//和上面一样

//和左边一样

//打印最长公共子序列

publicstaticvoidlcs(inti,intj,char[]x,int[][]b)

publicstaticvoidmain(Stringargs[])

char[]x={'

char[]y={'

int[][]b=newint[x.length+1][y.length+1];

最长公共子序列:

intn=lcsLength(x,y,b);

System.out.println();

其长度为:

+n);

最长公共子序列为:

lcs(x.length-1,y.length-1,x,b);

2.3实验结论

2.4心得体会:

最长公共子序列比较好理解哦。

做起来也相较简单多了

30-1背包问题

3.1算法设计思想

(1)分析最优解:

设(y1,y2,…,yn)是所给0-1背包问题的一个最优解,则

(y2,…,yn)是下面相应子问题的一个最优解。

设所给0-1背包问题的子问题

的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。

由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下。

publicstaticvoidknapsack(int[]v,int[]w,intc,int[][]m)

intn=v.length-1;

intjMax=Math.min(w[n]-1,c);

for(intj=0;

j<

=jMax;

j++)

m[n][j]=0;

//当w[n]>

j有m[n][j]=0

//m[n][j]表示只有n物品,背包的容量为j时的最大价值

for(intj=w[n];

=c;

j++)

m[n][j]=v[n];

//当w[n]<

=j有m[n][j]=v[n]

//递规调用求出m[][]其它值,直到求出m[0][c]

for(inti=n-1;

i>

=1;

i--)

jMax=Math.min(w[i]-1,c);

j<

=jMax;

m[i][j]=m[i+1][j];

for(intj=w[i];

m[i][j]=Math.max(m[i+1][j],m[i+1][j-w[i]]+v[i]);

m[0][c]=m[1][c];

if(c>

=w[0])

m[0][c]=Math.max(m[0][c],m[1][c-w[0]]+v[0]);

System.out.println(+m[0][c]);

publicstaticvoidtraceback(int[][]m,int[]w,intc,int[]x)

{//根据最优值求出最优解

intn=w.length-1;

for(inti=0;

i<

n;

if(m[i][c]==m[i+1][c])

x[i]=0;

else{

x[i]=1;

c-=w[i];

x[n]=(m[n][c]>

0)?

1:

0;

3.2程序源码

0-1背包问题代码:

*下面是0-1的动态规划算法

*v[]w[]c分别是价值、重量、和背包容量数组

*m[i][j]表示有i~n个物品,背包容量为j的最大价值。

*/

publicclassbeibao

publicstaticvoidknapsack(int[]v,int[]w,intc,int[][]m)

publicstaticvoidtraceback(int[][]m,int[]w,intc,int[]x)

publicstaticvoidmain(String[]args)

//测试

int[]w={2,2,6,5,4};

int[]v={6,3,5,4,6};

int[][]m=newint[11][11];

0-1背包问题最优值:

knapsack(v,w,10,m);

0-1背包问题最优解:

int[]x=newint[w.length];

traceback(m,w,10,x);

x.length;

System.out.print(x[i]);

3.3实验结论

3.4心得体会

深夜了,我被0-1背包问题折磨了一晚上,总算搞定了;

从伪代码到代码的历程好艰辛。

不过还是有点成就感的

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1