算法部分作业答案.docx

上传人:b****2 文档编号:11674691 上传时间:2023-06-02 格式:DOCX 页数:24 大小:225.15KB
下载 相关 举报
算法部分作业答案.docx_第1页
第1页 / 共24页
算法部分作业答案.docx_第2页
第2页 / 共24页
算法部分作业答案.docx_第3页
第3页 / 共24页
算法部分作业答案.docx_第4页
第4页 / 共24页
算法部分作业答案.docx_第5页
第5页 / 共24页
算法部分作业答案.docx_第6页
第6页 / 共24页
算法部分作业答案.docx_第7页
第7页 / 共24页
算法部分作业答案.docx_第8页
第8页 / 共24页
算法部分作业答案.docx_第9页
第9页 / 共24页
算法部分作业答案.docx_第10页
第10页 / 共24页
算法部分作业答案.docx_第11页
第11页 / 共24页
算法部分作业答案.docx_第12页
第12页 / 共24页
算法部分作业答案.docx_第13页
第13页 / 共24页
算法部分作业答案.docx_第14页
第14页 / 共24页
算法部分作业答案.docx_第15页
第15页 / 共24页
算法部分作业答案.docx_第16页
第16页 / 共24页
算法部分作业答案.docx_第17页
第17页 / 共24页
算法部分作业答案.docx_第18页
第18页 / 共24页
算法部分作业答案.docx_第19页
第19页 / 共24页
算法部分作业答案.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

算法部分作业答案.docx

《算法部分作业答案.docx》由会员分享,可在线阅读,更多相关《算法部分作业答案.docx(24页珍藏版)》请在冰点文库上搜索。

算法部分作业答案.docx

算法部分作业答案

 

算法部分作业答案(总18页)

算法:

是对特定问题求解步骤的一种描述,是指令的有限序列。

程序:

当一个算法用某种程序设计语言来描述时,得到的就是程序,也就是说,程序是用某种程序设计语言对算法的具体实现.

算法有输入、输出、确定性、能行性和有限性等特征,当不具备有穷性时,只能叫做计算过程,而不能称之为算法,算法可以终止,而程序没有此限制。

程序证明和程序测试的目的各是什么?

程序证明是确认一个算法能正确无误的工作.

程序测试的目的是发现错误

1-9解:

n!

的递归定义:

求解n!

的递归函数

longFactorial(longn)

{

if(n<0)

{

cout<<”error!

”;

exit(0);

}

if(n==0)

return1;

elsereturnn*Factorial(n-1);

}

1-10使用归纳法,证明上题所设计的计算n!

的递归函数的正确性

证明(归纳法证明):

(1)首先,如果n=0,那么程序执行

if(n==0)

return1;

返回1,算法显然正确;

(2)假定函数Factorial对n1)能正确运行,那么,当n=k时,算法必定执行:

elsereturnk*Factorial(k-1);

因为Factorial(k-1)正确,所以,当n=k时,程序运行正确

综合以上两点,可得程序正确.

证毕.

2-1,简述衡量一个算法的主要性能标准,说明算法的正确性与健壮性的关系

答:

衡量一个算法的主要性能指标有:

正确性,简单性,高效低存储,最优性

算法的正确性与健壮性的关系:

所谓算法的正确性:

是指在合法的输入下,算法应实现预先规定的功能和计算精度要求;所谓算法的健壮性,是指当输入不合法时,算法应该能按某种预定的方式做出适当的处理;

正确的算法不一定的是健壮的,健壮的算法也不一定是完全正确的.正确性和健壮性是相互补充的.一个可靠的算法,要求能在正常情况下正确的工作,而在异常情况下,亦能做出适当处理.

2-9

(1)设计一个C/C++程序,实现一个n*m的矩阵转置,原矩阵与其转置矩阵保存在二维数组中.

Voidreverse(int**a,int**b,intn,intm)

{

For(inti=0;i

For(intj=0;j

b[j][i]=a[i][j];

}

(2)使用全局变量count,改写矩阵转置程序,并运行修改后的程序以确定此程序所需的程序步

Voidreverse(int**a,int**b,intn,intm,int&count)

{

inti=0;

count++;

intj=0;

count++;

For(;i

For(;j

{

count++;

b[j][i]=a[i][j];

count++;

}

}

2-10试用定义证明下列等式的正确性

(1)5n2-8n+2=O(n2)

证明:

因为当n0=1,C=6时,当n>n0时,有5n2-8n+2<=6n2

2-16使用递推关系式计算求n!

的递归函数的时间(即分析1-9题中的函数的时间复杂度),要求使用替换和迭代两种方法分别计算之.

解:

分析1-9题中的函数的时间复杂度:

用基本运算乘法的运算次数作为衡量时间复杂度的量

当n=0时,程序执行if(n==0)return1;,并没有做乘法,故T(0)=0;当n>=1时程序执行n*Factorial(n-1);此时T(n)=T(n-1)+1故:

替换法:

T(0)=0,T

(1)=1,T

(2)=2-----

总结得到:

T(n)=n;

归纳法证明:

(1),当n=0时,T(0)=0,结论成立;

(2)假设当k

所以,对所有n>=0有T(n)=n;成立.

迭代法:

T(n)=T(n-1)+1

=(T(n-2)+1)+1=((T(n-3)+1)+1)+1=....=T(0)+1+1......+1(n个1)=n

2-19利用递归树计算递推方程

假设n=2k,那么,总共有logn+1(即k+1)层,非递归部分之和为

n2+n2/21+n2/22+…+n2/2k=(1+1/2+1/22+1/23+…+1/2logn)n2

=2n2+2n=O(n2)

5-8三分搜索算法的做法是:

它先将待查元素X与n/3处的元素比较,然后将X与2n/3处的元素比较,比较的结果或者找到X,或者将范围缩小到原来的n/3

intSearch3(inta[],intleft,intright,intx)/*递归算法*/

{

intl,u;

if(left<=right)

{

l=left+(right-left)/3;

u=left+(right-left)*2/3;

if(x==a[u])

returnu;

elseif(x==a[l])

returnl;

elseif(x>a[u])

returnSearch3(a,u+1,right,x);

elseif(x>a[l])

returnSearch3(a,l+1,u-1,x);

else

returnSearch3(a,left,l-1,x);

}

return-1;

}

voidmain()

{

intn,*a;

intx,i;

cout<<"Pleaseinputn:

";

cin>>n;

(1)a=newint[n];假设当n=2)时,算法正确,即对于所有元素个数小于n的元素集,算法能正确排序.

那么,当n=right-left+1时,算法执行程序段:

intk=(right-left+1)/3;

stoogesort(a,left,right-k);

stoogesort(a,left+k,right);

stoogesort(a,left,right-k);

由假设可知:

以上三条语句都能正确运行,所以,当n=right-left+1时,算法正确.

由以上两点可知,算法正确.

分析算法的时间复杂度:

排序算法,基本运算仍然是元素之间的比较,所以,算法时间复杂度为:

(用替换或迭代法计算之即可)

6-1设有背包问题实例,n=7,(w0,w1,w2,w3,w4,w5,w6)=(2,3,5,7,1,4,1),(p0,p1,p2,p3,p4,p5,p6)=(10,5,15,7,6,18,3),M=15。

求这一实例的最优解及最大收益.

解:

首先,选择最优量度标准为收益重量比;

其次,依据收益重量比的非增次序对输入(物品)进行排序

(p0/w0,p1/w1,p2/w2,p3/w3,p4/w4,p5/w5,p6/w6)=(5,5/3,3,1,6,,3)

对物品排序结果为:

4,0,5,2,6,1,3

最后,进行贪心选择:

X=(4)X=(4,0)X=(4,0,5)

(剩余载重)U=14U=12U=8

(收益)P=6P=6+10=16P=16+18=34

X=(4,0,5,2)X=(4,0,5,2,6)X=(4,0,5,2,6,1(2/3))

(剩余载重)U=3U=2U=0

(收益)P=34+15=49P=49+3=52P=52+2/3*5=

所以,最优解为x=(1,2/3,1,0,1,1,1);即装入第0,2,4,5,6物品和第1个物品的2/3

最大收益:

P=

6-2,0/1背包问题是一种特殊的背包问题,装入背包的物品不能分割,只允许或者整个物品装入背包,或者不装入,即xi=0,或1,(0<=i

解:

首先,选择最优量度标准为收益重量比;

其次,依据收益重量比的非增次序对输入(物品)进行排序

(p0/w0,p1/w1,p2/w2,p3/w3,p4/w4,p5/w5,p6/w6)=(5,5/3,3,1,6,,3)

对物品排序结果为:

4,0,5,2,6,1,3

最后,进行贪心选择:

X=(4)X=(4,0)X=(4,0,5)

(剩余载重)U=14U=12U=8

(收益)P=6P=6+10=16P=16+18=34

X=(4,0,5,2)X=(4,0,5,2,6)X=(4,0,5,2,6)

(剩余载重)U=3U=2继续考察第1和第3个

(收益)P=34+15=49P=49+3=52物品,都不能装入.

所以,贪心法求得的0/1背包问题的最优解为x=(1,0,1,0,1,1,1);即装入第0,2,4,5,6物品

最大收益:

P=52

但实际上,当y=(1,1,1,0,1,1,0)即装入第0,1,2,4,5物品,可获收益为P=54,所以,贪心法求得的0/1背包问题的解x一定不是最优解.

原因是:

对于0/1背包问题,贪心法并不能保证使其单位载重下的收益最大,因为通常在背包没还装满时,却再也装不下任何物品,这样,就使得单位载重下的物品收益减少,所以,0/1背包问题通常不能用贪心法求解.

6-3设有带时限的作业排序实例n=7,收益(p0,p1,p2,p3,p4,p5,p6)=(3,5,20,18,1,6,30),作业的时限(d0,d1,d2,d3,d4,d5,d6)=(1,3,4,3,2,1,2),给出以此实例为输入,执行函数JS得到的用最优解和最大收益。

解:

X={5,6,3,2}最大收益为74

函数JS如下:

intJS(int*d,int*x,intn)

{

X:

6

X:

0123456

首先,考虑作业6,假设将其加入集合X,即x[0]=6;

考虑X中的作业能否均如期完成,因为此时X中只有作业6,其截止时限为2,故,能如期完成,此时,将作业6加入作业子集X中,此时,子集X中的最大可用下标k=0;

X:

6

接着,考虑作业2.

首先搜索作业2在X集合中的插入位置,使得X集合中的元素按作业的截止时限的非减次序排序,因为d6=2,而d2=4,所以,可将作业2插在作业6的后面,即x[1]=2,得到X=(6,2),

X:

6

2

 

考虑X中的作业能否均如期完成?

因为d6=2>=1,d2=4>=2,所以,X中作业均能如期完成,将作业2加入子集X中.子集X中的最大可用下标k=k+1=1

X:

6

2

 

考虑作业3.

首先搜索作业3在X集合中的插入位置,使得X集合中的元素按作业的截止时限的非减次序排序,因为d6=2,d2=4,而d3=3所以,可将作业3插在作业6的后面,作业2的前面,得到X=(6,3,2),

X:

6

3

2

0123456

k

考虑X中的作业能否均如期完成?

因为d6=2>=1,d3=3>=2,d2=4>=3所以,X中作业均能如期完成,将作业2加入子集X中.子集X中的最大可用下标k=k+1=2

X:

6

3

2

 

考虑作业5.

首先搜索作业5在X集合中的插入位置,使得X集合中的元素按作业的截止时限的非减次序排序,因为d6=2,d2=4,d3=3而d5=1所以,可将作业5插在作业6的前面,得到X=(5,6,3,2),

X:

5

6

3

2

 

考虑X中的作业能否均如期完成?

因为d5=1>=1,d6=2>=2,d3=3>=3,d2=4>=4所以,X中作业均能如期完成,将作业5加入子集X中.子集X中的最大可用下标k=k+1=3

X:

5

6

3

2

考虑作业1.

首先搜索作业1在X集合中的插入位置,使得X集合中的元素按作业的截止时限的非减次序排序,因为d5=1,d6=2,d3=3,d2=4,而d1=3所以,可将作业1插在作业2的前面,作业3的后面,得到X=(5,6,3,1,2),

X:

5

6

3

1

2

 

考虑X中的作业能否均如期完成?

因为d5=1>=1,d6=2>=2,d3=3>=3,d1=3<4所以,X中1作业不能如期完成,所以,不能将作业1加入子集X.

X:

5

6

3

2

 

接着考虑作业0,4均不能加入子集X,

故,执行JS得到的最优解为X=(5,6,3,2),最大收益为P=p5+p6+p3+p2=30+20+18+6=74

6-17,最佳装载问题是将一批集装箱装上一艘载重为C的轮船,其中集装箱i的重量为wi(0<=i<=n-1),最优装载问题是指在装载体积不受限制的情况下,求使得装箱数目最多的装载方案.

(1)按贪心策略的要求,给出关于上述最优化问题的形式化描述.

(2)给出贪心法求解这一问题的最优量度标准;

(3)讨论其最优解的最优子结构.

(4)编写装箱问题的贪心算法;

(5)设有重量为(4,6,3,5,7,2,9)的7个集装箱,轮船载重为26,求最优解.

解;

(1),形式化描述如下:

给定C>0,wi>0

求X=(

)使得

并且使

最大

(2)以重量作为最优量度标准,以重量最轻者先装来选择集装箱装上船

(3)设(x0,x1,----xn-1)是最优装载问题的最优解,则易知(x1,x2,----xn-1)是轮船载重为C-x0w0且待装船的集装箱为{1,3----n-1}时相应最优装载问题的一个最优解,即最优装载问题具有最优子结构特性。

否则,假设(x1,x2,----xn-1)不是子问题的最优解,假设有另一个解Z=(z1,z2,----zn-1)是子问题的最优解,则有:

则:

,即(x0,z1,z2,--zn-1)是最优装载问题的最优解,与(x0,x1,----xn-1)是最优装载问题的最优解矛盾,所以,(x1,x2,----xn-1)是子问题的最优解,故最优装载问题具有最优子结构特性。

(4)参考程序1

/*箱子信息结构体*/

structgoodinfo

{

floatw;/*箱子重量*/

intX;/*箱子存放的状态*/

intflag;/*箱子编号*/

};

/*按物品重量做升序排列*/

voidsort(goodinfogoods[],intn)

{

intj,i;

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

{

goods[0]=goods[j];

i=j-1;

while(goods[0].w

{

goods[i+1]=goods[i];

i--;

}

goods[i+1]=goods[0];

}

}

/*用贪心法对物品进行选择装入*/

voidloading(goodinfogoods[],floatM,intn)

{

floatcu;

inti,j;

intA=0;/*对装入箱子进行计数*/

for(i=1;i<=n;i++)/*赋初值*/

goods[i].X=0;

cu=M;/*船的剩余载重*/

for(i=1;i

{

if(goods[i].w>cu)/*当该箱重量大于剩余载重跳出*/

break;

goods[i].X=1;

A++;

cu=cu-goods[i].w;/*确定船的剩余载重*/

}

for(j=2;j<=n;j++)/*对箱子按序号大小作升序排列*/

{

goods[0]=goods[j];

i=j-1;

while(goods[0].flag

{

goods[i+1]=goods[i];

i--;

}

goods[i+1]=goods[0];

}

cout<<"①最优解为:

"<

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

{

cout<<"第"<

";

cout<

}

cout<<"<0:

未装入;1:

装入>"<

cout<

cout<<"②最多能装入的箱子数为:

";

cout<

}

(5)

首先,选择最优量度标准为重量;

其次,依据集装箱重量的非减次序对输入(物品)进行排序

对集装箱的排序结果为:

5,2,0,3,1,4,6

最后,进行贪心选择:

X=(5)X=(5,2)X=(5,2,0)

(剩余载重)U=24U=21U=17

X=(5,2,0,3)X=(5,2,0,3,1)X=(5,2,0,3,1)

(剩余载重)U=12U=6

所以,最优解为X=(0,1,2,3,5),最优解值为5

参考程序2

•publicstaticfloatloading(floatc,float[]w,int[]x)

•{

•intn=;

•Element[]d=newElement[n];

•for(inti=0;i

•d[i]=newElement(w[i],i);

•(d);

•floatopt=0;

•for(inti=0;i

•for(inti=0;i

•x[d[i].i]=1;

•opt+=d[i].w;

•c-=d[i].w;

•}

•returnopt;

}

7-5设有4个矩阵连乘积ABCD:

A:

45*8,B:

8*40,C:

40*25,D:

25*10,,请求出它们的最优计算次序和计算量。

解:

p0=45,p1=8,p2=40,p3=25,p4=10

可只给出矩阵形式

计算m矩阵为:

m[0][1]=p0*p1*p2=45*8*40=14400;

m[1][2]=p1*p2*p3=8*40*25=8000;

m[2][3]=p2*p3*p4=40*25*10=11250;

m[0][2]=m[0][0]+m[1][2]+p0*p1*p3=8000+45*8*25=8000+9000=17000

=m[0][1]+m[2][2]+p0*p2*p3=14400+45*40*25=14400+45000

m[1][3]=m[1][1]+m[2][3]+p1*p2*p4=11250+8*40*10=11250+3200

=m[1][2]+m[3][3]+p1*p3*p4=8000+8*25*10=10000

m[0][3]=m[0][0]+m[1][3]+p0*p1*p4=10000+45*8*10=10000+3600=13600

=m[0][1]+m[2][3]+p0*p2*p4=14400+11250+45*40*10=

=m[0][2]+m[3][3]+p0*p3*p4=17000+45*25*10=17000+11250=28250

这4个矩阵相乘需要的最小数量乘法的次数=13600

最优计算次序A((BC)D)

7-9给定字符串A=“xzyzzyx”和B=“zxyyzxz”,使用LCS算法求最长公共子串,并给出一个最长公共子串。

提示:

从上到下,从左往右计算C矩阵,依据C矩阵,求得最长公共子序列

解:

计算求得C矩阵如下,

依矩阵C可求得两个最长公共子序列分别为xyzz和zyyx(求一个即可)

 

7-17设流水作业调度的实例为n=7,(a0,a1,a2,a3,a4,a5,a6)=(6,2,4,1,7,4,7),(b0,b1,b2,b3,b4,b5,b6)=(3,9,3,8,1,5,6).请使用流水作业调度的Johnson算法求使完成时间最小的最优调度,并求该最小完成时间。

提示:

依据调度规则,求得最优调度次序

解:

;令mi=min{ai,bi}0<=i<7

即得:

m0=b0=3,m1=a1=2,m2=b2=3,m3=a3=1,

m4=b4=1,m5=a5=4m6=b6=6

考虑mi,对其从小到大排序得(m3,m4,m1,m0,m2,m5,m6)

考虑mi序列(如果序列中下一个数mi是ai,则作业i放在最左的空位,否则,作业i放在最右的空位)得:

最优调度顺序(3,1,5,6,2,0,4)

依据最优调度在两台处理机上处理作业,最小完成时间:

36(画出如教材P170的图7-17的形式即可求得最小完成时间36)

8-2#include<>

#include<>

intcount=0;//记录可行解的个数

//先将书中的递归变为如下非递归函数,再在输出一个可行解之后,加上break;

intplace(intk,intxk,int*x)

{

for(intj=0;j

if(x[j]==xk||abs(x[j]-xk)==abs(j-k))//相互冲突,return0;

return0;

return1;//互不冲突,return1

}

voidNQueens(intn,int*x)

{

intk=0;

x[k]=-1;

while(k>=0)

{

x[k]=x[k]+1;

while(x[k]

place(k,x[k],x))//找安置第K个皇后的合法位置

x[k]=x[k]+1;

if(x[k]

if(k==n-1)//找到一个可行解,输出

{

cout<<"Thesolutionis:

";

for(intj=0;j

cout<

cout<

//break;//删除,则可输出所有可行解。

count++;

}

else//找到安

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

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2