动态规划算法实验报告docWord文档格式.docx

上传人:b****6 文档编号:19559094 上传时间:2023-01-07 格式:DOCX 页数:26 大小:181.67KB
下载 相关 举报
动态规划算法实验报告docWord文档格式.docx_第1页
第1页 / 共26页
动态规划算法实验报告docWord文档格式.docx_第2页
第2页 / 共26页
动态规划算法实验报告docWord文档格式.docx_第3页
第3页 / 共26页
动态规划算法实验报告docWord文档格式.docx_第4页
第4页 / 共26页
动态规划算法实验报告docWord文档格式.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

动态规划算法实验报告docWord文档格式.docx

《动态规划算法实验报告docWord文档格式.docx》由会员分享,可在线阅读,更多相关《动态规划算法实验报告docWord文档格式.docx(26页珍藏版)》请在冰豆网上搜索。

动态规划算法实验报告docWord文档格式.docx

(A"

)"

else

("

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

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

intmain()

intw;

矩阵个数:

cin>

>

w;

intp[w],s[w][w];

输入矩阵A1维数:

p[0]>

p[1];

for(inti=2;

i<

=w;

i++)

intm=p[i-1];

输入矩阵A"

维数:

p[i-1]>

p[i];

if(p[i-1]!

=m)

endl<

维数不对,矩阵不可乘!

endl;

exit

(1);

Traceback(1,w,s);

return0;

运行结果

 

2、最长公共子序列

cstring>

#defineN100

//str1存储字符串x,str2存储字符串y

charstr1[N],str2[N];

//lcs存储最长公共子序列

charlcs[N];

//c[i][j]存储str1[1...i]与str2[1...j]的最长公共子序列的长度

intc[N][N];

//flag[i][j]==0为str1[i]==str2[j]

//flag[i][j]==1为c[i-1][j]>

=s[i][j-1]

//flag[i][j]==-1为c[i-1][j]<

s[i][j-1]

intflag[N][N];

//求长度

intLCSLength(char*x,char*y)

inti,j;

//分别取得x,y的长度

intm=strlen(x);

intn=strlen(y);

for(i=1;

=m;

c[i][0]=0;

for(i=0;

=n;

c[0][i]=0;

for(j=1;

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

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

flag[i][j]=0;

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

=c[i][j-1])

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

flag[i][j]=1;

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

flag[i][j]=-1;

returnc[m][n];

//求出最长公共子序列

char*getLCS(char*x,char*y,intlen,char*lcs)

inti=strlen(x);

intj=strlen(y);

while(i&

&

j)

if(flag[i][j]==0)

lcs[--len]=x[i-1];

i--;

j--;

elseif(flag[i][j]==1)

returnlcs;

inti;

请输入字符串x:

str1;

请输入字符串y:

str2;

intlcsLen=LCSLength(str1,str2);

最长公共子序列长度:

lcsLen<

char*p=getLCS(str1,str2,lcsLen,lcs);

最长公共子序列为:

lcsLen;

lcs[i]<

"

3、最大子段和

//分治法求最大子段和

intMaxSubSum(int*a,intleft,intright)

intsum=0;

if(left==right)sum=a[left]>

0?

a[left]:

0;

intcenter=(left+right)/2;

//最大子段和在左边

intleftsum=MaxSubSum(a,left,center);

//最大子段和在右边

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

//最大子段和在中间

ints1=0;

intlefts=0;

for(inti=center;

i>

=left;

i--)

lefts+=a[i];

if(lefts>

s1)s1=lefts;

ints2=0;

intrights=0;

for(inti=center+1;

=right;

rights+=a[i];

if(rights>

s2)s2=rights;

sum=s1+s2;

//前后子段和相加

//判断最大子段和

if(sum>

leftsum)sum=leftsum;

rightsum)sum=rightsum;

returnsum;

intMaxSum(int*a,intn)

returnMaxSubSum(a,1,n-1);

inta[8]={2,-3,-5,4,1,7,1,-5};

最大子段和为:

MaxSum(a,8);

//动态规划法

intsum=0,b=0;

for(inti=1;

n;

i++)//此处不能=n,

if(b>

0)b+=a[i];

elseb=a[i];

sum)sum=b;

4、凸多边形最优三角剖分

cmath>

#defineN50

structpoint

intx;

inty;

};

intdistance(pointX,pointY)//两点距离

intdis=(Y.x-X.x)*(Y.x-X.x)+(Y.y-X.y)*(Y.y-X.y);

return(int)sqrt(dis);

intw(pointa,pointb,pointc)//权值

returndistance(a,b)+distance(b,c)+distance(a,c);

boolJudgeInput()//判断是否能构成凸多边形

point*v;

//记录凸多边形各顶点坐标

int*total;

//记录坐标在直线方程中的值

intm,a,b,c;

请输入凸多边形顶点个数:

m;

intM=m-1;

for(inti=0;

m;

输入顶点v"

的坐标:

v[i].x>

v[i].y;

//根据顶点坐标判断是否能构成一个凸多边形

for(intj=0;

j<

j++)

intp=0;

intq=0;

if(m-1==j)

a=v[m-1].y-v[0].y;

b=v[m-1].x-v[0].y;

c=b*v[m-1].y-a*v[m-1].x;

a=v[j].y-v[j+1].y;

b=v[j].x-v[j+1].x;

c=b*v[j].y-a*v[j].x;

for(intk=0;

k<

k++)

total[k]=a*v[k].x-b*v[k].y+c;

if(total[k]>

0)

p=p+1;

elseif(total[k]<

q=q+1;

if((p>

0&

q>

0)||(p==0&

q==0))

无法构成凸多边形!

boolminWeightTriangulation()//计算最优值算法

intM;

int**t,**s;

for(inti=1;

=M;

t[i][i]=0;

for(intr=2;

r<

r++)

=M-r+1;

intj=i+r-1;

t[i][j]=t[i+1][j]+w(v[i-1],v[i],v[j]);

s[i][j]=i;

for(intk=i+1;

i+r-1;

intu=t[i][k]+t[k+1][j]+w(v[i-1],v[k],v[j]);

if(u<

t[i][j])

t[i][j]=u;

s[i][j]=k;

returntrue;

voidTraceback(inti,intj,int**s)

return;

三角形:

v"

i-1<

s[i][j]<

int**s;

//记录最优三角剖分中所有三角形信息

int**t;

//记录最优三角剖分所对应的权函数值

intM=0;

t=newint*[N];

s=newint*[N];

N;

t[i]=newint[N];

s[i]=newint[N];

v=newpoint[N];

total=newint[N];

if(JudgeInput())

if(minWeightTriangulation())

Traceback(1,M,s);

最优权值之和为:

t[1][M]<

运行结果:

5、流水作业调度

classJobtype

public:

/*intoperator<

=(Jobtypea)const

return(key<

=a.key);

}*/

intkey;

intindex;

booljob;

voidsort(Jobtype*d,intn)

Jobtypetemp;

boolexchange;

//交换标志

for(i=0;

i<

n;

i++){//最多做n-1趟排序

exchange=false;

//本趟排序开始前,交换标志应为假

for(j=n-1;

j>

=i;

j--)

if(d[j+1].key<

d[j].key){

temp=d[j+1];

d[j+1]=d[j];

d[j]=temp;

exchange=true;

//发生了交换,故将交换标志置为真

if(!

exchange)//本趟排序未发生交换,提前终止算法

intFlowShop(intn,int*a,int*b,int*c)

Jobtype*d=newJobtype[n];

i++)//初始化

d[i].key=a[i]>

b[i]?

b[i]:

a[i];

//执行时间

d[i].job=a[i]<

=b[i];

//作业组

d[i].index=i;

//作业序号

sort(d,n);

intj=0;

intk=n-1;

i++)//最优调度

if(d[i].job)

c[j++]=d[i].index;

c[k--]=d[i].index;

j=a[c[0]];

k=j+b[c[0]];

j+=a[c[i]];

k=j<

k?

k+b[c[i]]:

j+b[c[i]];

deleted;

//回收空间

returnk;

//返回调度时间

intn,*a,*b,*c;

作业数:

Jobtype*d=newJobtype[N];

a=newint[N];

b=newint[N];

c=newint[N];

请输入作业号和时间:

d[i].index>

d[i].key;

cout<

endl;

intk=FlowShop(n,a,b,c);

\n调度时间:

最优调度序列:

for(inti=0;

i<

i++)//输出最优调度序列

c[i]<

6、0-1背包问题

#include<

iomanip>

constintC=10;

//容量

constintN=5;

//个数

intmax(constinta,constintb)

returna>

b?

a:

b;

intmin(constinta,constintb)

returna<

/*

m为记录数组m[i][j]代表在剩有j容量的条件下,从i开始往后的物品中可以取得的最大价值

w为重量数组,v为价值数组

n为物品个数,c为开始容量

则m[1][c]即此背包能剩下的最大价值

*/

voidknapsack(int**m,intn,intc,int*w,int*v)

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

//前n-1个物品

=jMax;

m[n][j]=0;

for(intj=w[n];

=c;

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

for(inti=n-1;

1;

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

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

for(intj=w[i];

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

m[1][c]=m[2][c];

if(c>

=w[1])

m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]);

//找出最优解,0表示不能装,1表示能装

voidtraceback(int**m,intn,intc,int*x,int*w)

if(m[i][c]==m[i+1][c])x[i]=0;

x[i]=1;

c-=w[i];

x[n]=(m[n][c]==0)?

0:

int*v=newint[N+1];

int*w=newint[N+1];

int**m=newint*[N+1];

int*x=newint[N+1];

N+1;

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

输入重量序列,"

N<

个"

=N;

w[i];

输入价值序列,"

v[i];

knapsack(m,N,C,w,v);

traceback(m,N,C,x,w);

cout<

最优值:

m[1][C]<

是否装入背包的情况:

x[i];

deletem[i];

delete[]m;

7、最优二叉搜索树

limits>

constdoubleMAX=numeric_limits<

double>

:

max();

//double的最大值

//a[i]为结点i被访问的概率

//b[i]为“虚结点”i被访问的概率

//m[i][j]用来存放子树(i,j)的期望代价

//w[i][j]用来存放子树(i,j)的所有结点(包括虚结点)的a,b概率之和

//s[i][j]用来跟踪root的

voidOptimalBinarySearchTree(double*a,double*b,intn)

ints[N][N];

doublem[N][N];

doublew[N][N];

inti,j,l,r;

=n+1;

m[i][i-1]=b[i-1];

w[i][i-1]=b[i-1];

for(l=1;

l<

l++)

=n-l+1;

j=l+i-1;

m[i][j]=MAX;

w[i][j]=w[i][j-1]+a[j]+b[j];

for(r=i;

=j;

doublek=m[i][r-1]+w[i][j]+m[r+1][j];

if(k<

m[i][j])

m[i][j]=k;

m[1][n];

doublea[N],b[N];

intn;

doublesum=0;

inti,j,l;

请输入关键字的个数:

请输入每个关键字的概率:

sum+=a[i];

请输入每个虚拟键的概率:

b[i];

sum+=b[i];

if(abs(sum-1)>

0.01)

输入的概率和不为1,请重新输入"

最优二叉查找树的期望搜索代价为:

OptimalBinarySear

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

当前位置:首页 > 成人教育 > 电大

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

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