昆明理工大学 算法分析与设计 实验3.docx

上传人:b****3 文档编号:12645350 上传时间:2023-04-21 格式:DOCX 页数:15 大小:153.51KB
下载 相关 举报
昆明理工大学 算法分析与设计 实验3.docx_第1页
第1页 / 共15页
昆明理工大学 算法分析与设计 实验3.docx_第2页
第2页 / 共15页
昆明理工大学 算法分析与设计 实验3.docx_第3页
第3页 / 共15页
昆明理工大学 算法分析与设计 实验3.docx_第4页
第4页 / 共15页
昆明理工大学 算法分析与设计 实验3.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

昆明理工大学 算法分析与设计 实验3.docx

《昆明理工大学 算法分析与设计 实验3.docx》由会员分享,可在线阅读,更多相关《昆明理工大学 算法分析与设计 实验3.docx(15页珍藏版)》请在冰豆网上搜索。

昆明理工大学 算法分析与设计 实验3.docx

昆明理工大学算法分析与设计实验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;

}

五、实验过程原始记录(测试数据、图表、计算等)

输入选择的方式求最大子段和问题。

手动输入适合序列长度短的时候:

当要测试序列长度很大的时候,经过测试,蛮力法的输出时间太长,所以先省去蛮力法的测试。

当序列长度很大是,只调用动态规划法和分治法。

结果如下:

经过测试可知,动态规划法是最佳的选择。

六、实验结果、分析和结论(误差分析与数据处理、成果总结等。

其中,绘制曲线图时必须用计算纸或程序运行结果、改进、收获)

同样的问题可以用不同的方法解决,一个好的算法是反复努力和重新修正的结果。

虽然穷举法,分治法,动态规划法都可以解决最大子段和这个问题,但是这些方法的时间复杂度各不相同,时间复杂度越低,代表这个方法更优越。

不同的算法能够解决相同的问题,这些算法的解题思路不同,复杂程度不同,解题效率也不同。

通过这次实验,我对动态规划法有了深刻的理解,同时也对前面所学的蛮力法和分治法进行了复习,体会到算法设计技术的思想方法。

注:

教师必须按照上述各项内容严格要求,认真批改和评定学生成绩。

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

当前位置:首页 > 医药卫生 > 基础医学

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

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