《算法设计与分析》实验.docx
- 文档编号:28356736
- 上传时间:2023-07-10
- 格式:DOCX
- 页数:15
- 大小:31.48KB
《算法设计与分析》实验.docx
《《算法设计与分析》实验.docx》由会员分享,可在线阅读,更多相关《《算法设计与分析》实验.docx(15页珍藏版)》请在冰豆网上搜索。
《算法设计与分析》实验
实验1最大子段和(分治法)
一、实验内容
运用分治法,编制程序求解如下问题:
给定由n个整数(可能有负整数)组成的序列(a1,a2,…,an),最大子段和问题要求该序列形如
的最大值(1<=i<=j<=n),当序列中所有整数均为负整数时,其最大子段和为0。
二、实验要求
1.进一步掌握递归算法的设计思想以及递归程序的调式技术;
2.理解这样一个观点,分治与递归经常同时应用在算法设计之中。
三、主要仪器设备
装有TC或VisualC++的PC机
四、实验步骤
1.算法分析
最大子段和问题的分治策略是:
(1)划分:
按照平衡子问题的原则,将序列(a1,a2,…,an)划分成长度相同的两个子序列(a1,…,an/2)和(an/2+1,…,an),则会出现以下三种情况:
①a1,…,an的最大子段和=a1,…,an/2的最大子段和;
②a1,…,an的最大子段和=an/2+1,…,a的最大子段和;
③a1,…,an的最大子段和=
,且
(2)求解子问题:
对于划分阶段的情况①和②可递归求解,情况③需要分别计算:
,
则s1+s2为情况③的最大子段和。
(3)合并:
比较在划分阶段的三种情况下的最大子段和,取三者之中的较大者为原问题的解。
分析算法的时间性能,对应划分得到的情况①和②,需要分别递归求解,对应情况③,需要两个并列for循环,时间复杂性是O(n),所以,存在如下递推式:
时间复杂性为O(nlogn)。
2.参考代码
#include
intMaxSum(inta[],intleft,intright)
{
intsum=0,leftsum=0,rightsum=0;
intcenter,i,j;
ints1,s2,lefts,rights;
if(left==right)
{
//如果序列长度为1,直接求解
if(a[left]>0)sum=a[left];
elsesum=0;
}
else
{
center=(left+right)/2;//划分
//对应情况①,递归求解
leftsum=MaxSum(a,left,center);
//对应情况②,递归求解
rightsum=MaxSum(a,center+1,right);
//以下对应情况③,先求解s1
s1=0;lefts=0;
for(i=center;i>=left;i--)
{
lefts+=a[i];
if(lefts>s1)s1=lefts;
}
//再求解s2
s2=0;rights=0;
for(j=center+1;j<=right;j++)
{
rights+=a[j];
if(rights>s2)s2=rights;
}
sum=s1+s2;//计算情况③的最大子段和
//合并,在sum、leftsum和rightsum中取较大者
if(sum if(sum } returnsum; } intmain() { inta[]={-20,11,-4,13,-5,-2}; intleft=0,right=5; cout< return0; } 实验2最长公共子序列问题 一、实验内容 利用动态规划算法编制程序求解下面的问题: 若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有: zj=xij。 例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。 给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。 给定2个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列。 二、实验要求 1.熟悉最长公共子序列问题的算法; 2.初步掌握动态规划算法。 三、主要仪器设备 装有TC或VisualC++的PC机 四、实验步骤 1.算法分析 最长公共子序列问题具有最优子结构性质。 设X={x1,...,xm},Y={y1,...,yn},及它们的最长子序列Z={z1,...,zk},则: (1)若xm=yn,则zk=xm=yn,且Z[k-1]是X[m-1]和Y[n-1]的最长公共子序列 (2)若xm! =yn,且zk! =xm,则Z是X[m-1]和Y的最长公共子序列 (3)若xm! =yn,且zk! =yn,则Z是Y[n-1]和X的最长公共子序列 由性质导出子问题的递归结构 当i=0,j=0时,c[i][j]=0 当i,j>0;xi=yi时,c[i][j]=c[i-1][j-1]+1 当i,j>0;xi! =yi时,c[i][j]=max{c[i][j-1],c[i-1][j]} 2.参考代码 #include usingnamespacestd; #definemax100 intL[max][max];//长度矩阵 intS[max][max];//状态矩阵 intCommonOrder(intm,intn,charx[],chary[],charz[]) { inti,j,k; for(j=0;j<=n;j++) L[0][j]=0;//初始化第0行 for(i=0;i<=m;i++) L[i][0]=0;//初始化第0列 for(i=1;i<=m;i++) for(j=1;j<=n;j++) if(x[i]==y[j]) { L[i][j]=L[i-1][j-1]+1; S[i][j]=1; } elseif(L[i][j-1]>=L[i-1][j]) { L[i][j]=L[i][j-1]; S[i][j]=2; } else { L[i][j]=L[i-1][j]; S[i][j]=3; } i=m;j=n;k=L[m][n]; while(i>0&&j>0) { if(S[i][j]==1) { z[k]=x[i]; k--;i--;j--; } elseif(S[i][j]==2) j--; else i--; } returnL[m][n]; } intmain() { charx[max]={'x','a','b','c','b','d','b'}; chary[max]={'y','a','c','b','b','a','b','d','b','b'}; charz[max]; intm=6,n=9; intlen=0,i,j; cout<<"序列X: "< for(i=1;i<=m;i++) cout< cout< cout<<"序列Y: "< for(i=1;i<=n;i++) cout< cout< len=CommonOrder(m,n,x,y,z); cout<<"最长公共子序列长度: "< cout<<"最长公共子序列为: "< for(i=1;i<=len;i++) cout< cout< cout<<"长度矩阵: "< for(i=0;i<=m;i++) { for(j=0;j<=n;j++) cout< cout< } cout< cout<<"状态矩阵: "< for(i=0;i<=m;i++) { for(j=0;j<=n;j++) cout< cout< } cout< return0; } 实验3多机调度问题 一、实验内容 利用贪心法设计算法求解如下问题: 要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。 约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。 作业不能拆分成更小的子作业。 分析算法执行效率。 二、实验要求 1.了解多机调度问题,学会分析该问题,并设计相应算法; 2.掌握贪心算法设计思想。 三、主要仪器设备 装有TC或VisualC++的PC机 四、实验步骤 1.算法分析 这个问题是一个NP完全问题,到目前为止还没有一个有效的解法。 对于这一类问题,用贪心选择策略有时可以设计出较好的近似算法。 可以考虑以下的贪心策略: (1)最长处理时间作业优先的贪心选择策略。 (2)最短处理时间作业优先的贪心选择策略。 (3)作业到达时间优先的贪心选择策略。 2.运行VisualC++集成开发环境,建立控制台工程。 3.编写代码,实现一种贪心算法。 4.假设7个独立的作业由3台机器加工处理,各作业所需的处理时间为: {2,14,4,6,16,5,3},写出以上算法求解此问题的结果。 。 5.分析算法的运行效率。 6.参考代码: #include usingnamespacestd; voidGreedy(intt[],intn,intm); intmain() { intn=7,m=3,t[]={2,14,4,16,6,5,3};//待分配的工作 Greedy(t,n,m); return0; } voidGreedy(intt[],intn,intm) { intflagn,flagm; intM[]={0,0,0,0,0,0,0,0}; for(inti=0;i { intmax=0,min=10000; flagn=0; flagm=0; for(intj=0;j { if(max {max=t[j]; flagn=j; } } for(j=0;j { if(M[flagm]>M[j]) {flagm=j;} } M[flagm]=M[flagm]+t[flagn]; t[flagn]=0;//被选择过的机器时间调为0 cout< } } 五、注意事项 1.对作业进行排序可以使用C++提供的泛型函数sort()来实现。 2.实验报告中,算法分析需要写出算法实现的具体步骤。 3.实验报告中,只需要提供算法实现的主要代码。 实验40-1背包(贪心法) 一、实验内容 运用贪心法,设计贪心策略,编制程序求解如下问题: 给定n个物品和一个容量为C的背包,物品i的重量是Wi,其价值是Vi,0-1背包问题是如何选择装入背包的物品(物品不可以分割),使得装入背包中的物品的总价值最大? 二、实验要求 1.掌握贪心法的设计思想; 2.掌握贪心策略的设计方法以及如何针对特定问题,选取合适的贪心策略。 三、主要仪器设备: 装有TC或VisualC++的PC机 四、实验步骤 1.算法分析 这个问题是一个NP完全问题,到目前为止还没有一个有效的解法。 对于这一类问题,用贪心选择策略有时可以设计出较好的近似算法。 可以考虑以下的贪心策略: (1)重量最轻的物品优先的贪心选择策略。 (2)重量最重的物品优先优先的贪心选择策略。 (3)价值最大的物品优先的贪心选择策略。 (4)单位价值最大的物品优先的贪心选择策略。 2.运行VisualC++集成开发环境,建立控制台工程。 3.编写代码,实现一种贪心算法。 4.自定义n个物品的重量和价值,以及背包容量C,写出以上算法求解此问题的结果。 。 5.分析算法的运行效率。 6.参考代码: #include #definemax100//最多物品数 voidsort(intn,floata[max],floatb[max])//按价值密度排序 { intj,h,k; floatt1,t2,t3,c[max]; for(k=1;k<=n;k++) c[k]=a[k]/b[k]; for(h=1;h for(j=1;j<=n-h;j++) if(c[j] {t1=a[j];a[j]=a[j+1];a[j+1]=t1; t2=b[j];b[j]=b[j+1];b[j+1]=t2; t3=c[j];c[j]=c[j+1];c[j+1]=t3; } } voidknapsack(intn,floatlimitw,floatv[max],floatw[max],intx[max]) {floatc1;//c1为背包剩余可装载重量 inti; sort(n,v,w);//物品按价值密度排序 c1=limitw; for(i=1;i<=n;i++) { if(w[i]>c1)break; x[i]=1;//x[i]为1时,物品i在解中 c1=c1-w[i]; } } voidmain() {intn,i,x[max]; floatv[max],w[max],totalv=0,totalw=0,limitw; cout<<"请输入n和limitw: "; cin>>n>>limitw; for(i=1;i<=n;i++) x[i]=0;//物品选择情况表初始化为0 cout<<"请依次输入物品的价值: "< for(i=1;i<=n;i++) cin>>v[i]; cout< cout<<"请依次输入物品的重量: "< for(i=1;i<=n;i++) cin>>w[i]; cout< knapsack(n,limitw,v,w,x); cout<<"theselectionis: "; for(i=1;i<=n;i++) { cout< if(x[i]==1) totalw=totalw+w[i]; } cout< cout<<"背包的总重量为: "< cout<<"背包的总价值为: "< } 五、注意事项 1.排序可以使用C++提供的泛型函数sort()来实现。 2.实验报告中,算法分析需要写出算法实现的具体步骤。 3.实验报告中,只需要提供算法实现的主要代码。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法设计与分析 算法 设计 分析 实验