昆明理工大学 算法分析与设计 实验3.docx
- 文档编号:12645350
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:15
- 大小:153.51KB
昆明理工大学 算法分析与设计 实验3.docx
《昆明理工大学 算法分析与设计 实验3.docx》由会员分享,可在线阅读,更多相关《昆明理工大学 算法分析与设计 实验3.docx(15页珍藏版)》请在冰豆网上搜索。
昆明理工大学算法分析与设计实验3
昆明理工大学信息工程与自动化学院学生实验报告
(2014—2015学年第1学期)
课程名称:
算法设计与分析开课实验室:
信自楼4452014年12月17日
年级、专业、班
计科122班
学号
201210405204
姓名
邹华宇
成绩
实验项目名称
最大子段和问题
指导教师
吴晟
教师评语
该同学是否了解实验原理:
A.了解□B.基本了解□C.不了解□
该同学的实验能力:
A.强□B.中等□C.差□
该同学的实验是否达到要求:
A.达到□B.基本达到□C.未达到□
实验报告是否规范:
A.规范□B.基本规范□C.不规范□
实验过程是否详细记录:
A.详细□B.一般□C.没有□
教师签名:
年月日
一、上机目的及内容
1.上机内容
给定有n个整数(可能有负整数)组成的序列(a1,a2,…,an),求改序列形如
的子段和的最大值,当所有整数均为负整数时,其最大子段和为0。
2.上机目的
(1)复习数据结构课程的相关知识,实现课程间的平滑过渡;
(2)掌握并应用算法的数学分析和后验分析方法;
(3)理解这样一个观点:
不同的算法能够解决相同的问题,这些算法的解题思路不同,复杂程度不同,解题效率也不同。
二、实验原理及基本技术路线图(方框原理图或程序流程图)
(1)分别用穷举法、分治法和动态规划法设计最大子段和问题的算法;
穷举法(蛮力法)设计原理:
利用3个for的嵌套(实现从第1个数开始计算子段长度为1,2,3…n的子段和,同理计算出第2个数开始的长度为1,2,3…n-1的子段和,依次类推到第n个数开始计算的长为1的子段和)和一个if(用来比较大小),将其所有子段的和计算出来并将最大子段和赋值给summax1。
用了3个for嵌套所以时间复杂性为
;
穷举法(蛮力法)流程图:
分治法设计原理:
1)划分:
按照平衡子问题的原则,将序列
划分成长度相同的两个字序列
和
。
2)求解子问题:
对于划分阶段的情况分别的两段可用递归求解,如果最大子段和在两端之间需要分别计算
,
,则
为最大子段和。
若然只在左边或右边,那就好办了,前者视
为summax1,后者视
为summax2。
3)合并:
比较在划分阶段的3种情况下的最大子段和,取三者之中的较大者为原问题的解。
4)时间复杂性分析:
,最后为
。
分治法设计流程图:
动态规划法设计原理:
(关键是要确定动态规划函数。
)
记
则
由
的定义,当
是
,否则,
。
时间复杂性为:
。
动态规划法流程图:
(2)对所设计的算法采用大O符号进行时间复杂性分析;
蛮力法:
T(n)=O(n3);
分治法:
T(n)=O(nlog(n));
动态规划法:
T(n)=O(n)。
(3)上机实现算法,并用计数法和计时法分别测算算法的运行时间;
(4)通过分析对比,得出自己的结论。
结论:
穷举法只可以处理小理的数据。
当数据量超过10000时,由穷举法要等很久才输出,所以数据量超过10000时,就比较分治法和动态规划法。
由实验结果可知,动态规划法所用的时间要少。
三、所用仪器、材料(设备名称、型号、规格等或使用软件)
1台PC及VISUALC++6.0软件
四、实验方法、步骤(或:
程序代码或操作过程)
部分重要代码说明:
#include
#include
intgetMaxSum1(intiarray[],intn)/*蛮力法函数*/
intgetMaxSum2(intiarray[],intstartIndex,intendIndex)//分治法函数
intgetMaxSum3(intiarray[],intn)/*动态规划方法函数*/
intOUT_PRINTF()//输出最大字段求解的函数
intmain()//主函数
程序源代码:
#include
#include
#include
usingnamespacestd;
/*蛮力法*/
intgetMaxSum1(intiarray[],intn)
{
intmaxSum=0;//初始化maxSum
for(inti=0;i { for(intj=i;j { inttmp=0;//初始化tmp(子段和) for(intk=i;k<=j;++k) { tmp+=iarray[k]; } if(tmp>maxSum)//比较子段和,得出最大的子段和maxSum { maxSum=tmp; } } } returnmaxSum; } /*分治递归方法*/ intgetMaxSum2(intiarray[],intstartIndex,intendIndex) { if(endIndex==startIndex)//只有一个元素 { returniarray[startIndex]; } if(endIndex-startIndex==1)//两个元素时 { inttmp=iarray[startIndex]+iarray[endIndex]; tmp=tmp>iarray[startIndex]? tmp: iarray[startIndex]; tmp=tmp>iarray[endIndex]? tmp: iarray[endIndex]; returntmp; } //左边一半序列的最大子段和leftMaxSum intleftMaxSum=getMaxSum2(iarray,startIndex,(startIndex+endIndex)/2); //右边一半序列的最大子段和rightMaxSum intrightMaxSum=getMaxSum2(iarray,(startIndex+endIndex)/2+1,endIndex); ints1=0; ints2=0; inttmp=0; for(inti=(startIndex+endIndex)/2;i>=startIndex;--i)//左子段和 { tmp=tmp+iarray[i]; if(tmp>s1) { s1=tmp; } } tmp=0; for(i=(startIndex+endIndex)/2+1;i<=endIndex;++i)//右子段和 { tmp=tmp+iarray[i]; if(tmp>s2) { s2=tmp; } } intmiddleMaxSum=s1+s2; intmaxSum=leftMaxSum>rightMaxSum? leftMaxSum: rightMaxSum; maxSum=maxSum>middleMaxSum? maxSum: middleMaxSum; returnmaxSum; } /*动态规划方法*/ intgetMaxSum3(intiarray[],intn) { intmaxSum=0; intb=0; for(inti=0;i { if(b>0) { b=b+iarray[i]; } else { b=iarray[i]; } if(b>maxSum) { maxSum=b;} } returnmaxSum; } intOUT_PRINTF()//输出最大字段求解的函数 { intn,i,cho; clock_tt1,t2,t3,t4,t5,t6; cout<<"求最大字段和问题\n"; cout< cout<<"手动输入请按1,随机输入请2\n"; cin>>cho; cout<<"请输入序列的长度"< cin>>n; int*iarray=newint[n]; if(cho==2) { srand((unsigned)time(NULL)); //cout<<"随机序列为: "< for(i=1;i<=n;i++) { iarray[i]=(rand()/13-1129); //cout<<""< } } else { cout<<"请输入序列"< for(i=0;i cin>>iarray[i]; } t1=clock();//使用蛮力法求解的开始时间 intmaxSum1=getMaxSum1(iarray,n); t2=clock();//蛮力法求解的结束时间 cout< cout<<"--------------------------------------------------\n"; cout<<"蛮力法最大子段和为: "< cout<<"时间: "< t3=clock();//分治法求解的开始时间 intmaxSum2=getMaxSum2(iarray,0,n-1); t4=clock();//分治法求解的结束时间 cout<<"--------------------------------------------------\n"; cout<<"分治法最大子段和为: "< cout<<"时间: "< t5=clock();//动态规划法求解的开始时间 intmaxSum3=getMaxSum3(iarray,n); t6=clock();//动态规划法求解的结束时间 cout<<"--------------------------------------------------\n"; cout<<"动态规划法最大子段和为: "< cout<<"时间: "< return0; } intmain()//主函数 { inti; chara,y,Y,b; OUT_PRINTF();//调用输出函数 for(i=1;i<10;i++) { cout<<"是否继续输入? Y/N"< cin>>a; if(a=='y'||a=='Y') { OUT_PRINTF(); } if(a=='n'||a=='N') { return0; } } return0; } 五、实验过程原始记录(测试数据、图表、计算等) 输入选择的方式求最大子段和问题。 手动输入适合序列长度短的时候: 当要测试序列长度很大的时候,经过测试,蛮力法的输出时间太长,所以先省去蛮力法的测试。 当序列长度很大是,只调用动态规划法和分治法。 结果如下: 经过测试可知,动态规划法是最佳的选择。 六、实验结果、分析和结论(误差分析与数据处理、成果总结等。 其中,绘制曲线图时必须用计算纸或程序运行结果、改进、收获) 同样的问题可以用不同的方法解决,一个好的算法是反复努力和重新修正的结果。 虽然穷举法,分治法,动态规划法都可以解决最大子段和这个问题,但是这些方法的时间复杂度各不相同,时间复杂度越低,代表这个方法更优越。 不同的算法能够解决相同的问题,这些算法的解题思路不同,复杂程度不同,解题效率也不同。 通过这次实验,我对动态规划法有了深刻的理解,同时也对前面所学的蛮力法和分治法进行了复习,体会到算法设计技术的思想方法。 注: 教师必须按照上述各项内容严格要求,认真批改和评定学生成绩。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 昆明理工大学 算法分析与设计 实验3 昆明 理工大学 算法 分析 设计 实验