春《计算机算法设计与分析》实验作业.docx

上传人:b****3 文档编号:12904494 上传时间:2023-04-22 格式:DOCX 页数:87 大小:184.06KB
下载 相关 举报
春《计算机算法设计与分析》实验作业.docx_第1页
第1页 / 共87页
春《计算机算法设计与分析》实验作业.docx_第2页
第2页 / 共87页
春《计算机算法设计与分析》实验作业.docx_第3页
第3页 / 共87页
春《计算机算法设计与分析》实验作业.docx_第4页
第4页 / 共87页
春《计算机算法设计与分析》实验作业.docx_第5页
第5页 / 共87页
点击查看更多>>
下载资源
资源描述

春《计算机算法设计与分析》实验作业.docx

《春《计算机算法设计与分析》实验作业.docx》由会员分享,可在线阅读,更多相关《春《计算机算法设计与分析》实验作业.docx(87页珍藏版)》请在冰豆网上搜索。

春《计算机算法设计与分析》实验作业.docx

春《计算机算法设计与分析》实验作业

实验报告

学院计算机科学与技术学院

专业计算机科学与技术

班级

课程算法分析与设计

教师

 

学号

姓名

学期2016年春季

实验1算法设计与分析基础

一、实验环境

操作系统:

WindowsXP或Windows\7及以上编程语言:

VisualC++6.0或VS2012

二、实验目的

了解算法描述的各种方法,重点学会使用自然语言与伪代码描述算法的方法。

养成先用自然语言或伪代码描述算法,然后再进行程序设计的习惯。

掌握进行算法复杂度分析的方法。

三、实验内容

1.1求两个整数的最大公约数。

1.2输出杨辉三角形前n行。

例如,杨辉三角形前5行如下:

1

11

121

1331

14641

1.3统计数字问题

1.4最多约数问题

四、实验开始

1.1求两个整数的最大公约数

1.1.1问题描述:

给定两个正整数m和n,求它们的最大公因子,即能同时整除m和n的最大整数。

1.1.2算法描述

方法1:

自然语言

欧几里德算法—辗转相除法:

①输入m和n;

②求m除以n的余数r;

③若r等于0,则n为最大公约数,输出结果n,算法结束;

否则执行第④步;

④将n的值放在m中,将r的值放在n中;

⑤返回第②步继续执行。

方法2:

伪代码表示

Begin(算法开始)

Read(m,n)

mmodn→r

whiler≠0do

{n→m

r→n

mmodn→r

}

write(n)

End(算法结束)

1.1.3程序设计与实现

方法1:

欧几里德算法的C语言描述如下:

#include

main()

{intm,n,r;

printf(“请输入两个正整数:

”);

scanf(“%d%d”,&m,&n);

printf(“\n%d和%d的最大公约数是:

”,m,n);

r=m%n;

while(r!

=0)

{m=n;n=r;

r=m%n;

}

printf(“%d\n”,n);

}

方法2:

欧几里德算法的C++语言描述如下:

#include

intCommonFactor(intm,intn)

{intr=m%n;

while(r!

=0)

{m=n;n=r;

r=m%n;

}

returnn;

}

voidmain()

{intm,n;

cout<<"请输入两个正整数:

";cin>>m>>n;

cout<

";

cout<

}

1.1.4测试数据及测试结果

运行程序:

请输入两个正整数:

1812

18与12的最大公约数是:

6

1.1.5算法复杂度分析

时间复杂度分析:

辗转相除法的循环次数与m、n的大小不成正比,∴时间复杂度为O

(1)

空间复杂度分析:

算法在执行过程中临时存储单元为1个(变量r),∴空间复杂度为O

(1)

1.2输出杨辉三角形前n行

1.2.1问题描述

1.2.2算法描述

1.2.3程序设计与实现

1.2.4测试数据及测试结果

1.2.5算法复杂度分析

1.3统计数字问题

1.3.1问题描述

一本书的页码从自然数1开始顺序编码直到自然数n。

书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。

例如,第6页用数字6表示,而不是06或006等。

数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2,…,9。

1.3.2算法分析与设计:

给定表示书的总页码的10进制整数n(1≤n≤109),计算书的全部页码中分别用到多少次数字0,1,2,…,9。

输入数据、输出结果示例

输入数据:

11

输出结果:

数字:

0123456789

用到次数:

1411111111

1.3.3算法描述

1.3.4程序设计与实现

1.3.5测试数据及测试结果

1.3.6算法复杂度分析

1.4最多约数问题

1.4.1问题描述

1.4.2算法分析与设计

1.4.3算法描述

1.4.4程序设计与实现

1.4.5测试数据及测试结果

1.4.6算法复杂度分析

实验2递归与分治

一、实验环境

操作系统:

WindowsXP编程语言:

VisualC++6.0或VS2012

二、实验目的

学习和了解递归与分治算法的概念和基本思想,熟悉对递归与分治问题的分析方法及其适用范围;

掌握递归与分治算法的设计思路和基本步骤,学会使用递归与分治算法解决实际问题。

三、实验内容

2.1求最大最小元问题

2.2归并排序

2.3快速排序

2.4众数问题

2.5*马的Hamilton周游路线问题

四、实验开始

2.1求最大最小元问题

2.1.1问题描述

2.1.2算法分析与设计

2.1.3算法描述

2.1.4程序设计与实现

2.1.5测试数据及测试结果

2.1.6算法复杂度分析

2.2归并排序(MergingSort)

2.2.1问题描述

“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。

利用归并的思想实现排序。

2-路归并排序:

设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2-路归并排序。

2.2.2算法分析与设计

例如图10.13为2-路归并排序的一个例子。

初始关键字[49][38][65][97][76][13][27]

一趟归并之后[3849][6597][1376][27]

二趟归并之后[38496597][132776]

三趟归并之后[13273849657697]

图10.132-路归并排序示例

2-路归并排序中的核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列。

2.2.3算法描述

2.2.4程序设计与实现

2.2.5测试数据及测试结果

2.2.6算法复杂度分析

2.3快速排序(QuickSort)

2.2.1问题描述

快速排序(QuickSort)是对起泡排序的一种改进。

它的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

2.2.2算法分析与设计

假设待排序的序列为{L.r[s],L.r[s+1],…,L.r[t]},首先任意选取一个记录(通常可选第一个记录L.r[s]作为枢轴(或支点)(pivot),然后按下述原则重新排列其余记录:

将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较它大的记录都安置在它的位置之后。

这个过程称作一趟快速排序(或一次划分)。

一趟快速排序的具体做法是:

附设两个指针low和high,它们的初值分别为low和high,设枢轴记录的关键字为pivotkey,则首先从high所指位置起向前搜索找到第一个关键字小于pivotkey的记录和枢轴记录互相交换,然后从low所指位置起向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录互相交换,重复这两步直至low=high为止。

2.2.3算法描述

2.2.4程序设计与实现

2.2.5测试数据及测试结果

2.2.6算法复杂度分析

2.4众数问题

2.4.1问题描述

2.4.2算法分析与设计

2.4.3算法描述

2.4.4程序设计与实现

2.4.5测试数据及测试结果

2.4.6算法复杂度分析

2.5*马的Hamilton周游路线问题

2.5.1问题描述

2.5.2算法分析与设计

2.5.3算法描述

2.5.4程序设计与实现

2.5.5测试数据及测试结果

2.5.6算法复杂度分析

实验3动态规划

一、实验环境

操作系统:

WindowsXP编程语言:

VisualC++6.0或VS2012

二、实验目的

1、学习和了解动态规划算法的概念和基本思想;

2、熟悉对动态规划问题的分析方法及其适用范围;

3、掌握动态规划算法的设计思路和基本步骤;

4、学会使用动态规划法解决实际问题。

三、实验内容

1.旅行家问题(TSP)

2.多段图的最短路径问题

3.0-1背包问题(knapsackproblem)。

4.最长公共子序列(LCS)问题

5.数塔问题

四、实验开始

3.1旅行家问题(TSP)

3.1.1问题描述

旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短。

3.1.2算法分析与设计

各个城市间的距离可以用代价矩阵来表示。

证明TSP问题满足最优性原理

设s,s1,s2,…,sp,s是从s出发的一条路径长度最短的简单回路,假设从s到下一个城市s1已经求出,则问题转化为求从s1到s的最短路径,显然s1,s2,…,sp,s一定构成一条从s1到s的最短路径。

如若不然,设s1,r1,r2,…,rq,s是一条从s1到s的最短路径且经过n-1个不同城市,则s,s1,r1,r2,…,rq,s将是一条从s出发的路径长度最短的简单回路且比s,s1,s2,…,sp,s要短,从而导致矛盾。

所以,TSP问题满足最优性原理。

假设从顶点i出发,令d(i,V')表示从顶点i出发经过V'中各个顶点一次且仅一次,最后回到出发点i的最短路径长度,开始时,V'=V-{i},于是,TSP问题的动态规划函数为:

d(i,V')=min{cik+d(k,V-{k})}(k∈V')

(1)

d(k,{})=cki(k≠i)

(2)

从城市0出发经城市1、2、3然后回到城市0的最短路径长度是:

d(0,{1,2,3})=min{c01+d(1,{2,3}),c02+d(2,{1,3}),c03+d(3,{1,2})}

这是最后一个阶段的决策,而:

d(1,{2,3})=min{c12+d(2,{3}),c13+d(3,{2})}

d(2,{1,3})=min{c21+d(1,{3}),c23+d(3,{1})}

d(3,{1,2})=min{c31+d(1,{2}),c32+d(2,{1})}

这一阶段的决策又依赖于下面的计算结果:

d(1,{2})=c12+d(2,{})d(2,{3})=c23+d(3,{})

d(3,{2})=c32+d(2,{})d(1,{3})=c13+d(3,{})

d(2,{1})=c21+d(1,{})d(3,{1})=c31+d(1,{})

而下式可以直接获得(括号中是该决策引起的状态转移):

d(1,{})=c10=5(1→0)d(2,{})=c20=6(2→0)d(3,{})=c30=3(3→0)

再向前倒推,有:

d(1,{2})=c12+d(2,{})=2+6=8(1→2)d(1,{3})=c13+d(3,{})=3+3=6(1→3)

d(2,{3})=c23+d(3,{})=2+3=5(2→3)d(2,{1})=c21+d(1,{})=4+5=9(2→1)

(3,{1})=c31+d(1,{})=7+5=12(3→1)d(3,{2})=c32+d(2,{})=5+6=11(3→2)

再向前倒退,有:

d(1,{2,3})=min{c12+d(2,{3}),c13+d(3,{2})}=min{2+5,3+11}=7(1→2)

d(2,{1,3})=min{c21+d(1,{3}),c23+d(3,{1})}=min{4+6,2+12}=10(2→1)

d(3,{1,2})=min{c31+d(1,{2}),c32+d(2,{1})}=min{7+8,5+9}=14(3→2)

最后有:

d(0,{1,2,3})=min{c01+d(1,{2,3}),c02+d(2,{1,3}),c03+d(3,{1,2})}

=min{3+7,6+10,7+14}=10(0→1)

所以,从顶点0出发的TSP问题的最短路径长度为10,最短路径是0→1→2→3→0。

动态规划法求解TSP问题的填表过程

假设n个顶点用0~n-1的数字编号,首先生成1~n-1个元素的子集存放在数组V[2n-1]中,设数组d[n][2n-1]存放迭代结果,其中d[i][j]表示从顶点i经过子集V[j]中的顶点一次且仅一次,最后回到出发点0的最短路径长度。

填表方法:

自底向上,逐步求值。

利用前一步求出的值计算出后一步的值填入表中,每一步结束后选择最小值作为子问题的最优值,最后一步为原问题的最优解。

j

i

{}

{1}

{2}

{3}

{1,2}

{1,3}

{2,3}

{1,2,3}

0

10

1

5

8

6

7

2

6

9

5

10

3

3

12

11

14

第1步

第2步

第3步

第4步

第1步:

填写第1列,

d(1,{})=c10=5(1→0);d(2,{})=c20=6(2→0);d(3,{})=c30=3(3→0)

第2步:

d(1,{2})=c12+d(2,{})=2+6=8(1→2)d(1,{3})=c13+d(3,{})=3+3=6(1→3)

d(2,{1})=c21+d(1,{})=4+5=9(2→1)d(2,{3})=c23+d(3,{})=2+3=5(2→3)

d(3,{1})=c31+d(1,{})=7+5=12(3→1)d(3,{2})=c32+d(2,{})=5+6=11(3→2)

第3步:

d(1,{2,3})=min{c12+d(2,{3}),c13+d(3,{2})}=min{2+5,3+11}=7(1→2)

d(2,{1,3})=min{c21+d(1,{3}),c23+d(3,{1})}=min{4+6,2+12}=10(2→1)

d(3,{1,2})=min{c31+d(1,{2}),c32+d(2,{1})}=min{7+8,5+9}=14(3→2)

第4步:

d(0,{1,2,3})=min{c01+d(1,{2,3}),c02+d(2,{1,3}),c03+d(3,{1,2})}

=min{3+7,6+10,7+14}=10(0→1)

最优解为:

0→1、1→2、2→3、3→0,

即,最短路径为:

0→1→2→3→0,最短路径长度为:

10

设顶点之间的代价存放在数组c[n][n]中,动态规划法求解TSP问题的算法如下:

3.3.3算法描述

算法3.1——TSP问题

1.for(i=1;i

d[i][0]=c[i][0];

2.for(j=1;j<2n-1-1;j++)

for(i=1;i

if(子集V[j]中不包含i)

对V[j]中的每个元素k,计算d[i][j]=min(c[i][k]+d[k][j-1]);

3.对V[2n-1-1]中的每一个元素k,计算d[0][2n-1-1]=min(c[0][k]+d[k][2n-1-2]);

4.输出最短路径长度d[0][2n-1-1];

3.1.4程序实现

3.1.5测试数据及测试结果

3.1.6算法复杂度分析

显然,算法3.1的时间复杂性为O(2n)。

和蛮力法相比,动态规划法求解TSP问题,把原来的时间复杂性是O(n!

)的排列问题,转化为组合问题,从而降低了算法的时间复杂性,但它仍需要指数时间。

3.2多段图的最短路径问题

3.2.1问题描述

设图G=(V,E)是一个带权有向连通图,如果把顶点集合V划分成k个互不相交的子集Vi(2≤k≤n,1≤i≤k),使得E中的任何一条边(u,v),必有u∈Vi,v∈Vi+m(1≤i<k,1<i+m≤k),则称图G为多段图,称s∈V1为源点,t∈Vk为终点。

多段图的最短路径问题是求从源点到终点的最小代价路径。

举例:

3.2.2算法分析与设计

3.2.3算法描述

3.2.4程序实现

3.2.5测试数据及测试结果

3.2.6算法复杂度分析

3.30-1背包问题(knapsackproblem)

3.3.1问题描述

0-1背包问题(knapsackproblem),某商店有n个物品,第i个物品价值为vi,重量(或称权值)为wi,其中vi和wi为非负数,背包的容量为W,W为一非负数。

目标是如何选择装入背包的物品,使装入背包的物品总价值最大,所选商品的一个可行解即所选商品的序列如何?

3.3.2算法分析与设计

可将这个问题形式描述如下:

约束条件为:

举例:

若商店一共有5类商品,重量分别为:

34789

价值分别为:

45101113

背包容量为:

17

则:

所选商品的一个序列为:

00011

所选商品的最大价值为24

3.3.3算法描述

3.3.4程序设计与实现

#include

#include

#include

intmin(intw,intc)

{//求2个数中的最小值

return(w

w:

c);

}

intmax(intw,intc)

{//求2个数中的最大值

return(w>c?

w:

c);

}

voidknapsack(intv[],intw[],intc,intn,int**m)//求最优值

{//

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

for(intj=0;j<=jmax;j++)m[n][j]=0;

for(intjj=w[n];jj<=c;jj++)m[n][jj]=v[n];

for(inti=n-1;i>1;i--)

{//递归部分

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

for(intj=0;j<=jmax;j++)m[i][j]=m[i+1][j];

for(intjj=w[i];jj<=c;jj++)m[i][jj]=max(m[i+1][jj],m[i+1][jj-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]);

cout<<"最优值:

"<

cout<<"*******************************************"<

}

inttraceback(int**m,intw[],intc,intn,intx[])//回代,求最优解

{//

cout<<"得到的一组最优解如下:

"<

for(inti=1;i

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

else{x[i]=1;c-=w[i];}

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

1:

0;

for(inty=1;y<=n;y++)cout<

cout<

returnx[n];

}

voidmain()

{intn,c;int**m;

cout<<"请输入物品个数和重量上限:

";cin>>n>>c;

int*v=newint[n+1];

cout<<"请输入价值(v[i]):

"<

for(inti=1;i<=n;i++)cin>>v[i];

int*w=newint[n+1];

cout<<"请输入重量(w[i]):

"<

for(intj=1;j<=n;j++)cin>>w[j];

int*x=newint[n+1];

m=newint*[n+1];//动态分配二维数组

for(intp=0;p

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

traceback(m,w,c,n,x);

}

3.3.5测试数据及测试结果

第1组测试数据及测试结果:

请输入物品个数和重量上限:

325

请输入价值(v[i]):

152026

请输入重量(w[i]):

101216

最优值:

35

*******************************************

得到的一组最优解如下:

110

第2组测试数据及测试结果:

请输入物品个数和重量上限:

517

请输入价值(v[i]):

34789

请输入重量(w[i]):

45101113

最优值:

12

*******************************************

得到的一组最优解如下:

01010

3.3.6算法复杂度分析

①时间复杂度分析

②空间复杂度分析

3.4最长公共子序列(LCS)问题

3.4.1问题描述

对给定序列X=(x1,x2,…,xm)和序列Z=(z1,z2,…,zk),Z是X的子序列当且仅当存在一个严格递增下标序列(i1,i2,…,ik),使得对于所有j=1,2,…,k,有zj=xij(1≤ij≤m)。

给定两个序列X和Y,当另一个序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。

最长公共子序列问题就是在序列X和Y的公共子序列中查找长度最长的公共子序列。

给定两个序列:

X={x1,x2,...,xm},Y={y1,y2,...,yn},求X和Y的一个最长公共子序列。

举例:

X={a,b,c,b,d,a,b}

Y={b,d,c,a,b,a}

编写一个程序求一个最长公共子序列,求得结果应为:

最长公共子序列为:

LSC={b,c,b,a}

3.4.2算法分析与设计

3.4.3算法描述

3.4.4程序实现

3.35测试数据及测试结果

3.36算法复杂度分

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

当前位置:首页 > 外语学习 > 英语考试

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

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