实验报告余双.docx

上传人:b****2 文档编号:20897409 上传时间:2023-04-25 格式:DOCX 页数:24 大小:167.76KB
下载 相关 举报
实验报告余双.docx_第1页
第1页 / 共24页
实验报告余双.docx_第2页
第2页 / 共24页
实验报告余双.docx_第3页
第3页 / 共24页
实验报告余双.docx_第4页
第4页 / 共24页
实验报告余双.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

实验报告余双.docx

《实验报告余双.docx》由会员分享,可在线阅读,更多相关《实验报告余双.docx(24页珍藏版)》请在冰豆网上搜索。

实验报告余双.docx

实验报告余双

实验编号:

3四川师大《算法设计与分析》实验报告2016年5月1日

计算机科学学院14级4班实验名称:

动态规划及其应用

姓名:

余双学号:

2014110451指导老师:

__苏菡__实验成绩:

_____

实验一动态规划及其应用

一.实验目的及要求

目的要求:

(1)理解动态规划算法的概念和基本要素,并能和分治法进行比较。

(2)掌握设计动态规划算法的步骤,并编程实现有关算法。

(3)理解这样一个观点:

同样的问题可以用不同的方法解决,一个好的算法是反复努力和重新修正的结果。

二.实验内容

(1)编程实现矩阵连乘问题的求解。

(2)编程实现最大子段和问题的求解(分别采用分治法和动态规划法求解)。

(3)编程实现0-1背包问题的求解。

(4)设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

(5)编程实现最长公共子序列(LCS)问题的求解。

(6)设计算法求解数字三角形问题,并编程实现。

(P80算法实现题3-4)

(7)设计算法求解独立任务最优调度问题,并编程实现。

问题描述:

欧诺个2台处理机A和B处理n个作业。

设第i个作业交给机器A处理时需要时间ai,若由机器B来处理,则需要时间bi。

由于各作业的特点和机器的性能关系,很可能对于某些i,有ai>=bi,而对于某些j,j不等于i,有aj

设计一个动态规划算法,是的这2台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总时间)。

研究一个实例:

(a1,a2,a3,a4,a5,a6)=(2,5,7,10,5,2);(b1,b2,b3,b4,b5,b6)=(3,8,4,11,3,4)

如:

(8)设计算法求解最少硬币问题,并编程实现。

注:

至少选择其中3题完成。

主要仪器设备及软件

(1)PC机

(2)TC、VC++、Java等任一编程语言

三.实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请另加附页)

(1)编程实现矩阵连乘问题的求解。

程序代码:

main.cpp

#include

#include"head.h"

usingnamespacestd;

intmain()

{

inti,n,*p;

cout<<"请输入矩阵的个数:

"<

cin>>n;

p=newint[n+1];

cout<<"请输入矩阵的维数(相邻矩阵的行列相等,只输入一次就行!

)";

for(i=0;i<=n;i++){

cin>>p[i];

}

int**m,**s;

m=newint*[n+1];

s=newint*[n+1];

for(i=1;i<=n;i++){

m[i]=newint[n+1];

s[i]=newint[n+1];

}

MatrixChain(p,n,m,s);

TraceBack(1,n,s);

return0;

}

MatrixChain.cpp

#include

#include"head.h"

usingnamespacestd;

voidMatrixChain(int*p,intn,int**m,int**s){

inti,j,r,k;

for(i=1;i<=n;i++){

m[i][i]=0;

s[i][i]=0;

}

for(r=2;r<=n;r++){

for(i=1;i

j=i+r-1;

if(j<7){

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

s[i][j]=i;

for(k=i+1;k

inttemp;

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

if(temp

m[i][j]=temp;

s[i][j]=k;

}

}

}

}

}

}

TraceBack.cpp

#include

#include"head.h"

usingnamespacestd;

voidTraceBack(inti,intj,int**s){

if(i==j){

return;

}

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

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

cout<<"MultiplyA"<

}

head.h:

#ifndefHEAD_H_INCLUDED

#defineHEAD_H_INCLUDED

voidMatrixChain(int*p,intn,int**m,int**s);

voidTraceBack(inti,intj,int**s);

#endif//HEAD_H_INCLUDED

运行结果:

(2)编程实现最大子段和问题的求解(分别采用分治法和动态规划法求解)。

分治法:

main.cpp:

#include

#include"head.h"

usingnamespacestd;

intmain(){

intn,i,*a;

cout<<"请输入序列长度:

"<

cin>>n;

a=newint[n+1];

cout<<"请输入该序列具体的数:

";

for(i=1;i<=n;i++){

cin>>a[i];

}

intsum=MaxSubSum(1,n,a);

cout<<"该序列的最大字段和为:

"<

}

MaxSubSum.cpp:

#include

#include"head.h"

intMaxSubSum(intleft,intright,int*a){

intsum=0;

if(left==right){

sum=a[left]>0?

a[left]:

0;

}

else{

intcenter=(left+right)/2;

intleftsum=MaxSubSum(left,center,a);

intrightsum=MaxSubSum(center+1,right,a);

ints1=0;intlefts=0;

for(inti=center;i>=left;i--){

lefts+=a[i];

if(lefts>s1){

s1=lefts;

}

}

ints2=0;intrights=0;

for(intj=center+1;j<=right;j++){

rights+=a[j];

if(rights>s2){

s2=rights;

}

}

sum=s1+s2;

if(leftsum>sum)sum=leftsum;

if(rightsum>sum)sum=rightsum;

}

returnsum;

}

head.h:

#ifndefH

#defineH

intMaxSubSum(intleft,intright,int*a);

#endif

运行结果:

动态规划法:

main.cpp

#include

#include"head.h"

usingnamespacestd;

intmain(){

intn,i,*a;

cout<<"请输入序列长度:

"<

cin>>n;

a=newint[n+1];

cout<<"请输入该序列具体的数:

";

for(i=1;i<=n;i++){

cin>>a[i];

}

intsum=MaxSubSum(n,a);

cout<<"该序列的最大字段和为:

"<

}

MaxSubSum.cpp

#include

#include"head.h"

usingnamespacestd;

intMaxSubSum(intn,int*a){

intsum=0,b=0;

for(inti=1;i<=n;i++){

if(b>0)b+=a[i];

elseb=a[i];

if(b>sum)sum=b;

}

returnsum;

}

head.h:

#ifndefH

#defineH

intMaxSubSum(intn,int*a);

#endif

运行结果:

(3)编程实现0-1背包问题的求解

main.cpp:

#include

#include"head.h"

usingnamespacestd;

intmain(){

inti,n,c,*v,*w,**m;

cout<<"请输入物品个数:

"<

cin>>n;

cout<<"请输入背包总容量:

"<

cin>>c;

v=newint[n+1];

w=newint[n+1];

cout<<"请输入每个物品的价值:

"<

for(i=1;i<=n;i++){

cin>>v[i];

}

cout<<"请输入每个物品的重量:

"<

for(i=1;i<=n;i++){

cin>>w[i];

}

m=newint*[n+1];

for(i=0;i<=n;i++){

m[i]=newint[n+1];

}

package(n,c,v,w,m);

cout<<"物品装入背包的情况如下:

(0表示该物品未放入背包,1表示该物品放入了背包)"<

traceBack(1,c,w,m,n);

}

package.cpp:

#include

#include"head.h"

usingnamespacestd;

voidpackage(intn,intc,int*v,int*w,int**m){

inti,j;

for(i=0;i<=n;i++){

m[i][0]=0;

}

for(j=0;j<=c;j++){

m[0][j]=0;

if(w[n]>j){

m[n][j]=0;

}else{

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

}

}

for(i=n-1;i>0;i--){

for(j=c;j>0;j--){

if(w[i]>j){

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

}elseif(m[i+1][j]

m[i][j]=v[i]+m[i+1][j-w[i]];

}else{

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

}

}

}

}

traceBack.cpp:

#include

#include"head.h"

usingnamespacestd;

voidtraceBack(inti,intj,int*w,int**m,intn){

if(i==n){

if(w[i]<=j){

cout<<"物品"<

1"<

}else{

cout<<"物品"<

0"<

}

return;

}

if(m[i][j]==m[i+1][j]){

cout<<"物品"<

0"<

i++;

traceBack(i,j,w,m,n);

}else{

cout<<"物品"<

1"<

j-=w[i];

i++;

traceBack(i,j,w,m,n);

}

}

head.h:

#ifndefH

#defineH

voidpackage(intn,intc,int*v,int*w,int**m);

voidtraceBack(inti,intj,int*w,int**m,intn);

#endif

运行结果:

(4)设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

程序代码:

main.cpp:

#include

#include"Sub.h"

usingnamespacestd;

intmain(){

intn,*a,*b,*c,i;

cout<<"请输入序列长度:

"<

cin>>n;

a=newint[n+1];

b=newint[n+1];

c=newint[n+1];

cout<<"请输入该序列的每一个数:

"<

for(i=1;i<=n;i++){

cin>>a[i];

}

b[n]=1;

Sub(n,a,b,c);

inttemp=b[1],j=1;

for(i=1;i<=n;i++){

if(temp

temp=b[i];

j=i;

}

}

cout<<"最长单调递增子序列长度为"<

"<

while(c[j]!

=j){

cout<

j=c[j];

}

cout<

}

sub.cpp:

#include

#include"Sub.h"

usingnamespacestd;

intSub(intn,int*a,int*b,int*c){

inti,k,j,temp,temp2;

for(i=n;i>0;i--){

temp=a[i];j=0;temp2=0;b[i]=1;

for(k=i+1;k<=n;k++){

if(a[i]temp2){

j=k;

temp=a[k];

temp2=b[k];

}

}

if(temp==a[i]){

b[i]=1;

c[i]=i;

}else{

b[i]=1+temp2;

c[i]=j;

}

}

return0;

}

sub.h:

#ifndefH

#defineH

intSub(intn,int*a,int*b,int*c);

#endif

运行结果:

(5)编程实现最长公共子序列(LCS)问题的求解

程序代码:

main.cpp:

#include

#include"head.h"

usingnamespacestd;

intmain()

{

char*x,*y;

intm,n;

cout<<"请输入第一个序列的长度:

"<

cin>>m;

x=newchar[m+1];

cout<<"请输入第一个序列:

"<

for(inti=1;i<=m;i++){

cin>>x[i];

}

cout<<"请输入第二个数序列长度:

"<

cin>>n;

y=newchar[n+1];

cout<<"请输入第二个序列:

"<

for(intj=1;j<=n;j++){

cin>>y[j];

}

int**c,**b;

c=newint*[m+1];

b=newint*[m+1];

for(intk=0;k<=m;k++){

c[k]=newint[n+1];

b[k]=newint[n+1];

}

LCSLegth(m,n,x,y,c,b);

char*z=newchar[c[m][n]+1];

LCS(m,n,x,b,z,c[m][n]);

cout<<"最长公共子序列如下:

"<

for(i=1;i<=c[m][n];i++){

cout<

}

cout<

return0;

}

LCS.cpp:

#include

#include"head.h"

usingnamespacestd;

intLCS(inti,intj,char*x,int**b,char*z,intk){

if(i==0||j==0){

return0;

}elseif(b[i][j]==1){

z[k]=x[i];

i--;

j--;

LCS(i,j,x,b,z,k-1);

}else{

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

i--;

LCS(i,j,x,b,z,k);

}else{

j--;

LCS(i,j,x,b,z,k);

}

}

}

LCSLegth.cpp:

#include

#include"head.h"

usingnamespacestd;

intLCSLegth(intm,intn,char*x,char*y,int**c,int**b){

inti,j;

for(i=0;i<=m;i++)

c[i][0]=0;

for(j=0;j<=n;j++)

c[0][j]=0;

for(i=1;i<=m;i++){

for(j=1;j<=n;j++){

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

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

b[i][j]=1;

}else{

if(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;

}

}

}

}

return0;

}

head.h:

#ifndefH

#defineH

intLCSLegth(intm,intn,char*x,char*y,int**c,int**b);

intLCS(inti,intj,char*,int**b,char*z,intk);

#endif

运行结果:

(6)设计算法求解数字三角形问题,并编程实现。

(P80算法实现题3-4)

程序代码:

#include

#include

usingnamespacestd;

intn,**d;

intMaxSum(inti,intj){

if(i==n-1){

returnd[i][j];

}else{

intSum1=MaxSum(i+1,j);

intSum2=MaxSum(i+1,j+1);

if(Sum1>Sum2){

returnSum1+d[i][j];

}else{

returnSum2+d[i][j];

}

}

}

intmain(){

//freopen("D:

\\VC\\MicrosoftVisualStudio\\MyProjects\\experiment_3\\Data3\\input.txt","r",stdin);

//freopen("D:

\VC\MicrosoftVisualStudio\MyProjects\experiment_3\Data3\\output.txt","w",stdout);

inti,j;

cout<<"请输入数字三角形的行数:

"<

cin>>n;

d=newint*[n];

for(i=0;i

d[i]=newint[n];

}

cout<<"请输入每一个数:

"<

for(i=0;i

for(j=0;j<=i;j++){

cin>>d[i][j];

}

}

intmax=MaxSum(0,0);

cout<<"求得的最大路径的和值为:

"<

}

运行结果:

四:

实验结果的分析与评价(该部分如不够填写,请另加附页)

注:

实验成绩等级分为(90-100分)优,(80-89分)良,(70-79分)中,(60-69分)及格,(59分)不及格。

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

当前位置:首页 > 法律文书 > 调解书

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

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