已阅读5页,还剩10页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
昆明理工大学信息工程与自动化学院学生实验报告( 2011 2012 学年 第 1 学期 )课程名称:算法分析与设计 开课实验室:信自楼机房445 2011 年11月 23日2011 年12月 14日年级、专业、班计科092学号200910405201姓名刘召成绩实验项目名称最大子段和问题指导教师 张晶教师评语该同学是否了解实验原理: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)分别用穷举法、分治法和动态规划法设计最大子段和问题的算法;穷举法的设计算法流程图如图1所示,动态规划算法流程图如图2所示,分治发没有给出流程图。(2)对所设计的算法采用大o符号进行时间复杂性分析;穷举法的时间复杂度是:o(n3)分治发的时间复杂度是:o(nlg(n)动态规划时间复杂度是:o(n)(3)上机实现算法,并用计数法和计时法分别测算算法的运行时间;对于所测算的时间与计数器可以参见运行结果图,也可以运行电子文档里的可运行程序(maxsubsum.exe)(4)通过分析对比,得出自己的结论。动态规划算法时间复杂度较好,分治发次之,穷举法较差!图(1)图(2)三、所用仪器、材料(设备名称、型号、规格等或使用软件)1台pc及visual studio2005软件,boost函数库四、实验方法、步骤(或:程序代码或操作过程)源代码:/ maxsubsum.cpp : defines the entry point for the console application./*author刘召 on 2011-11-26此程序在visual studio 8平台上调试运行的此程序用到了c+委员会建立的boost社区开发的boost开源c+库函数求解最大子段和简易系统*/#define boost_date_time_source#include stdafx.h#include #include #include #include #include #include #include #include #include #include #include using namespace std;using namespace boost;struct infolong start,ed,counting; long long countouer=0; void shutdown(int type) handle htoken; token_privileges tkp; openprocesstoken(getcurrentprocess(),token_adjust_privileges|token_query,&htoken); lookupprivilegevalue(null,se_shutdown_name,&tkp.privileges0.luid); tkp.privilegecount=1; tkp.privileges0.attributes=se_privilege_enabled; adjusttokenprivileges(htoken,false,&tkp,0,(ptoken_privileges)null,0); exitwindowsex(type|ewx_force,0); void mycomputershutdown() int i; coutt1直接退出!endl; coutt2注销计算机!endl; coutt3关闭计算机!endl; coutt4重启计算机!endl; cout; cini;i-=2; shutdown(i); void choice()cout;void choising(char* str)coutn数据量较大,是否要str?这将会花很长时间!endl;cout1是t2否endl;choice();void aline(int k,char c);void inputthenumberlist(vector*integerlist)long j,i=1,h=1,t=0,k;string str=你共输入;if(!(*integerlist).empty()(*integerlist).clear();coutendlright;coutsetw(48)初始化系统数据!nendl;coutt1要输入任意个个数的数据!endl;coutt2要输入的数据个数已确定!endl;coutt3要随机产生一定个数的数据作为输入数据!k;if(k=1)while (i=1)cout请输入第leftsetw(3)hj;(*integerlist).push_back(j);+h;coutn1继续输入下一个数字!t2退出输入数据模块!i;else if (k=2)cout请输入你要输入的数据的个数:k;for (int i1=1;i1=k;i1+)cout请输入第leftsetw(3)i1j;(*integerlist).push_back(j); elsecout请输入你要随机产生的数据的个数:k1;mt19937 wng(time(0);jk=abs(long(wng()/177)%1771;for(long i=0;i=jk;i+)ko=rand();ko=rand();coutn正在产生随机数据;progress_display pg2(k1);mt19937 rng(rand();uniform_intui(0,ko);while(k1) ko=ui(rng);pg2+;jk=ui(rng);mk=ui(rng);if(mk6000)char* str=输出随机产生的数据;choising(str);cinqw;if(qw=1)|(*integerlist).size()=6000)ofstream outdata;outdata.open(random output numbers.txt);coutendlstr(*integerlist).size()个数字,他们是:500)coutmn;coutn第t*mn个数据到第i*mn个数据是:endl;cin.ignore(12,n);t+;i+;outdataleft第setw(4)1行:;for (long y=0;ymn)&(gmn)long long c=i*mn;if(i*mn=(*integerlist).size() c=(*integerlist).size();coutn第t*mn个数据到第c个数据是(按回车键以继续输出下面的数据):endl;cin.ignore(12,n);t+;i+;g=1;coutleft;coutsetw(16)(*integerlist)y;outdatasetw(16)(*integerlist)y;if(y+1)%5=0) outdataendl第setw(4)y/5+2行:;g+;coutendl;aline(80,$);outdata.close();vector directmethod(vectorintlist,long long* counter)vector textor;long countor=0,lisize=intlist.size();longlong pk=0,kp=powl(lisize,3);info hhtt;hhtt.counting=hhtt.ed=hhtt.start=0;textor.push_back(hhtt);double f=1,df=0.1686;if(lisize2940) pk=powl(2940,3);f=1.001463*pk/kp;kp=pk;pk=0;if(lisize=5) switch(lisize)case 2:df=0.562; break;case 3: df=0.382;break;case 4: df=0.322;break;case 5: df=0.282;break;else if(lisize12) switch(lisize)case 6:df=0.262; break;case 7: df=0.246;break;case 8: df=0.236;break;case 9: case 10: case 11: df=0.224;break;else if(lisize=16) df=0.2084;else if(lisize24) df=0.1964;else if(lisize50) df=0.1864;else if(lisize100) df=0.1764;coutn正在用穷举法进行运算;progress_display pg3(kp*df);for (int i=0;ilisize;i+)for (long j=i;jlisize;j+)countor=0;for ( long k=j;klisize;k+)(*counter)+;countor+=intlistk;if(lisize=2940) pg3+;else if(pk=textor0.counting)hhtt.counting=countor;hhtt.start=j;hhtt.ed=k;if (countor!=textor0.counting)textor.clear();textor.push_back(hhtt);elsebool t=true;for ( long p=0;ptextor.size();p+) if (textorp.start=j)&(textorp.ed=k) t=false;break;if(t) textor.push_back(hhtt);return textor;void needkey(string str)cout请按回车键(enter)以进入str运算模块!;cin.ignore(5,n);void aline(int k,char c)for (int i=0;ik;i+)coutc;void sho(vector textor,vectornumlist, long i,string str)coutn由str得到最大字段和是:textori.countingendl;cout相应的子段是从第textori.start+1个数字(numlisttextori.start)到第textori.ed+1个数字(numlisttextori.ed)endl;cout它们分别是:endl;int op,p=1;op=0;ofstream outdata;outdata.open(directmethod output submax.txt);outdataleft第setw(4)p行:;for (long j=textori.start;j=textori.ed;j+)coutleft;coutsetw(16)numlistj;outdatasetw(16)numlistj;op+;if(op%5=0) outdataendl第setw(4)+p行:;coutendl;aline(79,*);outdata.close();void showthemethodresult(vector textor,vectornumlist,string str)if (textor.size()=1)sho(textor,numlist,0,str); elsecouttt由str共得到textor.size()个这样的最大字段!它们分别是:nendl;for ( long k=0;ktextor.size();k+)cout第k+1组最大子段的信息:endl;sho(textor,numlist,k,str);long subdealmethod(vectorintegerlist,long long left,long long right)long sum;if (left=right)+countouer;if (integerlistleft0)sum=integerlistleft; elsesum=0; elselong long center=(left+right)/2;long long leftsum=subdealmethod(integerlist,left,center);long long rightsum=subdealmethod(integerlist,center+1,right);long long s1=0,aleft=0,s2=0,aright=0;for (long long d=center;d=left;d-)aleft=aleft+integerlistd;if (alefts1) s1=aleft;+countouer;for (long long i=center+1;is2) s2=aright;+countouer;sum=s1+s2;if(sumleftsum)sum=leftsum;if(sumrightsum)sum=rightsum;return sum;long dynamicmethod(vector integerlist,long long *coutor)long sum=0,b=0;for (long i=0;i0)b+=integerlisti; elseb=integerlisti;if(bsum) sum=b; (*coutor)+;return sum;void welcome()coutnsetw(66)欢迎使用求解最大子段和简易系统(release 2.0)nendl;couttttt学 校:昆明理工大学endl;couttttt学 院:信息工程与自动化学院endl;couttttt专 业:计算机科学与技术endl;couttttt指导老师:张晶endl;couttttt制 作 人:刘召endl;couttttt学 号:200910405201endl;coutttttqq 邮箱:329245767nendl;void exitsession()coutn正在退出本系统,请稍后;progress_display p(1e9);for (long i=0;i1e9;i+) p+;coutn你已经成功退出本系统!n谢谢你的使用,再见!endl;sleep(1500);int main(int argc, char* argv) vectorintegerlist;int k=1;welcome();atexit(exitsession);while(k=1)system(color 2b);long long countoer=0;double m;inputthenumberlist(&integerlist);timer tcounter;long result;needkey(动态规划法);system(color 4a);coutn正在用动态规划法进行运算;tcounter.restart();result=dynamicmethod(integerlist,&countoer);m=tcounter.elapsed();coutn动态规划法运算所用时间为:;coutm秒n循环次数大约为:;coutcountoer次n动态规划法运算的结果是:resultendl;aline(79,-);needkey(分治法);system(color 1c);coutn正在用分治法进行运算(这可能需要几秒甚至几分钟);tcounter.restart();result=subdealmethod(integerlist,0,integerlist.size()-1);m=tcounter.elapsed();coutn分治法运算所用时间为:;coutm秒n循环次数大约为:;coutcountouer次n由分治法运算的结果是:;coutresult2940)char* str1=用穷举法进行运算;choising(str1);cinip;if (integerlist.size()=2940)|(ip=1)needkey(穷举法);system(color c0);tcounter.restart();vector mid=directmethod(integerlist,&countoer);m=tcounter.elapsed();coutn穷举法运算所用时间为:;coutm秒n循环次数大约为:;coutcountoer次n由穷举法运算的结果是:endl;showthemethodresult(mid,integerlist,穷举法); coutn1继续使用本系统,并求解下一组数据的最大子段和n;coutk;aline(80,&);integerlist.clear();mycomputershutdown();return 0;五、实验过程原始记录( 测试数据、图表、计算等) 图(3)手动输入5个数据:7、8、-16、12、3。用动态规划算法运行所得到的最大子段和是15;运行用时不足1毫秒,用计数器测得循环次数为5次!图(4)在图(4)中,对于图(3)中的5个数据,用分治发所得到的最大子段和是15,用计时器测得用时也不足1毫秒,用计数器测得循环17次。用穷举法(直接法)得到的最大子段和也是15,穷举法可以找到所有具有最大子段和的响应的子段,这5 个数据由两个最大子段;用计时器测得穷举法用时0.031秒,用计数器测得循环35次。由此可以看出,穷举法用时明显多于动态规划与分治发。图(5)由于动态规划与分治发时间复杂度较低,所以设置了可以自动随机产生数据的功能,对于随机产生大于6000个数据时,可以选择是否输出所产生的数据!这里随机产生了2940个数据,因为当随机产生的数据较多时,可能很耗时,所以设置了完成工作的进度显示功能;若要输出随机产生的数据,当产生的数据个数大于500时,可以选择每次输出的数据的个数,可以按回车键输出下面的数据!由于产生的数据较多,在这里只显示一部分。图(6)由于穷举法用时较长,所以为穷举法设置了完成作业的进度显示。运算随机产生的2940个数据,三种方法得到的最大子段和结果都是665。用计时器测得动态规划法用时0.015秒,用计数器测得循环了2940次。对于分治发,用计时器测得用时0.016秒,用计数器测得循环了37064次。对于穷举法,用计时器测得用时31.247秒,用计数器测得循环了4239686780次。显然,穷举法的性能较差,下面随机产生更多的数据继续比较动态规划法与分治发的性能。图(7)这次随机产生了五万个数据,由于数据量较大,选择了不输出随机产生的数据,由于五万个数据用穷举法将会要很长时间,这里跳过用穷举法进行运算,说明一下,当数据量超过2940个时,将会提示是否用穷举法进行运算,可以选择用或不用。用动态规划法对这50000个数据运算用时为0.016秒,循环次数为50000次。对于分治法,用计时器测得对这50000个数据运算用时为14.727秒,用计数器测得循环了834464次。由此可以看出,动态规划法性能优于分治法!若要得到更多的测试,可以运行电子版文档附带的运行程
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论