实验活动安排物联1301班刘悦08080112.docx
- 文档编号:24770908
- 上传时间:2023-06-01
- 格式:DOCX
- 页数:17
- 大小:118.19KB
实验活动安排物联1301班刘悦08080112.docx
《实验活动安排物联1301班刘悦08080112.docx》由会员分享,可在线阅读,更多相关《实验活动安排物联1301班刘悦08080112.docx(17页珍藏版)》请在冰豆网上搜索。
实验活动安排物联1301班刘悦08080112
算法分析与设计实验报告
第X次实验
姓名
刘悦
学号
201308080112
班级
物联1301班
时间
11.14上午
地点
工训楼C栋309
实验名称
贪心算法实验(求活动安排问题)
实验目的
通过上机实验,要求掌握贪心算法的问题描述、算法设计思想、程序设计。
实验原理
每次选择使剩余时间最多的活动进行安排。
1依贪心选择策略,将尽可能多的结束时间最小的活动安排。
2若此活动的开始时间比前面活动的结束时间大,则此活动相容,否则此活动不相容。
3依此策略一直地进行下去,直到所有活动均被判断是否相容。
实验步骤
1将活动按结束时间升序排列。
2默认第一个活动是相容的。
3从第二个活动开始,若当前活动的开始时间比前一个活动的结束时间大,则此活动是相容的,否则此活动不相容。
4安排下一个活动。
5将所有活动判断完是否相容后,将活动按编号升序排列,方便查询相容在活动的编号。
关键代码
/*=================================================================
定义结构体来存储某活动的信息。
num代表活动的编号。
s代表活动开始的时间。
f代表活动结束的时间。
A代表活动是否相容。
=================================================================*/
structactivity
{
intnum;
floats;
floatf;
boolA;
}task[999999];
/*=================================================================
count函数是用来计算有多少个活动相容的函数。
遍历所有活动的A,若为1则被安排,计数值num加一,若为0则不被安排,计数值num不加一。
输入所有待安排的活动和活动的个数。
返回为相容活动的个数。
=================================================================*/
intcount(activitytask[],intn)
{
intnum=0;
for(inti=1;i<=n;i++)
{
if(task[i].A==1)
num++;
}
returnnum;
}
/*=================================================================
sort函数使用选择排序实现排序。
选择排序即每次从未排好序的数里面选择最大/小的放到已排好序的数的最后面。
调用此函数后,实现了对task数组的排序。
********************************************************************************
flag代表是按哪个值排序,1代表按活动结束时间升序排列,2代表按编号升序排列。
n代表待安排活动的总数。
task[i].s代表活动i的开始时间。
task[i].f代表活动i的结束时间。
task[i].A代表活动i是否相容,1代表相容,0代表不相容。
=================================================================*/
voidsort(intn,activitytask[],intflag)
{
activitytemp;
if(flag==1)
{
//对除第一个活动外的所有活动按结束时间从小到大排序。
for(inti=3;i<=n;i++)
for(intj=i;(j>1)&&(task[j].f { temp=task[j]; task[j]=task[j-1]; task[j-1]=temp; } } if(flag==2) { //对所有活动按编号从小到大排序。 for(inti=2;i<=n;i++) for(intj=i;(j>1)&&(task[j].num { temp=task[j]; task[j]=task[j-1]; task[j-1]=temp; } } } /*================================================================= GreedySelector函数是用来贪心算法求解。 贪心算法即每次选择结束时间最小的活动进行安排。 首先对活动按结束时间升序排列,第一个活动默认相容。 从第二个活动开始,当前活动的开始时间比前一个活动的结束时间大,则当前活动与之前的活动相容; 否则就不相容,然后看下一个活动。 ******************************************************************* n代表待安排活动的总数。 task[i].s代表活动i的开始时间。 task[i].f代表活动i的结束时间。 task[i].A代表活动i是否相容,1代表相容,0代表不相容。 =================================================================*/ voidGreedySelector(intn,activitytask[]) { sort(n,task,1); task[1].A=true; intj=1; for(inti=2;i<=n;i++) { if(task[i].s>=task[j].f) { task[i].A=true; j=i; } elsetask[i].A=false; } sort(n,task,2); } 测试结果 1首先需要验证函数的编写是否正确,故使用一组可人为判断结果是否正确的数据进行测量。 给定待安排活动总数为11,时间为(s,f)={(1,4),(3,5),(0,6),(5,7),(3,8),(5,9),(2,13),(6,10),(8,11),(8,12),(12,14)},计算之后第1、4、9、11个活动被安排,共4个活动被安排。 程序运行结果如下,可以知道结果正确。 2然后进行多组数据比较测试,这里选取了10组数据进行测试,10组数据是随机生成的,设置为每个随机数均小于等于100,测试结果如下。 3由上面的结果可以看出,不管是大数据还是小数据的时候,此算法的性能都较好,所用时间都比较小。 实验心得 怕自己上课时间做不完实验,所以就提前在寝室做了很久,没想到竟然提前做完了之前的两个实验,鉴于还有很多时间,代码不怕敲得多,所以就编写了一下求活动安排的代码。 这里为了解决多组数据、大数据和验证函数正确性的问题,使用与之前的实验类似的写两个主函数的方法,每次运行其中一个而注释掉另外一个。 这个实验与前面的贪心算法求背包问题是类似的,要解决的问题也都是类似的。 因为在背包问题中都已经将问题解决,所以这里并没有耗费多少时间。 这个问题较背包问题,我又进行了进一步改进,增加了求解被安排在活动数量的函数,进一步方便了输出。 这个实验中对大数据进行测试的时候,由于数据较大的时候被安排在的活动数量较多,若把别安排的活动编号输出会使输出不那么清晰,所以只有在不大于100个活动被安排的时候输出被安排的活动的编号。 进过这两个贪心算法的代码的编写,可以意识到,贪心算法有较好的时间复杂度,为线性时间。 通过此代码的编写,使我可以更加熟练的使用贪心算法。 相信在以后的学习工作中,一定可以熟练使用贪心算法求解问题。 实验得分 助教签名 附录: 完整代码 #include #include #include #include usingnamespacestd; /*============================================================================ 定义结构体来存储某活动的信息。 num代表活动的编号。 s代表活动开始的时间。 f代表活动结束的时间。 A代表活动是否相容。 ============================================================================*/ structactivity { intnum; floats; floatf; boolA; }task[999999]; /*============================================================================ ran函数是产生随机数的函数,产生的数据范围为0-100。 此函数用于大数据测试时产生数据以供使用。 无输入,产生一个单精度型的实数,并返回。 ============================================================================*/ floatran() { floata; srand(time(0)); while (1) { a=rand(); if(a<100) break; } returna; } /*============================================================================ count函数是用来计算有多少个活动相容的函数。 遍历所有活动的A,若为1则被安排,计数值num加一,若为0则不被安排,计数值num不加一。 输入所有待安排的活动和活动的个数。 返回为相容活动的个数。 ============================================================================*/ intcount(activitytask[],intn) { intnum=0; for(inti=1;i<=n;i++) { if(task[i].A==1) num++; } returnnum; } /*============================================================================ sort函数使用选择排序实现排序。 选择排序即每次从未排好序的数里面选择最大/小的放到已排好序的数的最后面。 调用此函数后,实现了对task数组的排序。 ******************************************************************************** flag代表是按哪个值排序,1代表按活动结束时间升序排列,2代表按编号升序排列。 n代表待安排活动的总数。 task[i].s代表活动i的开始时间。 task[i].f代表活动i的结束时间。 task[i].A代表活动i是否相容,1代表相容,0代表不相容。 ============================================================================*/ voidsort(intn,activitytask[],intflag) { activitytemp; if(flag==1) { //对除第一个活动外的所有活动按结束时间从小到大排序。 for(inti=3;i<=n;i++) for(intj=i;(j>1)&&(task[j].f { temp=task[j]; task[j]=task[j-1]; task[j-1]=temp; } } if(flag==2) { //对所有活动按编号从小到大排序。 for(inti=2;i<=n;i++) for(intj=i;(j>1)&&(task[j].num { temp=task[j]; task[j]=task[j-1]; task[j-1]=temp; } } } /*============================================================================ GreedySelector函数是用来贪心算法求解。 贪心算法即每次选择结束时间最小的活动进行安排。 首先对活动按结束时间升序排列,第一个活动默认相容。 从第二个活动开始,当前活动的开始时间比前一个活动的结束时间大,则当前活动与之前的活动相容; 否则就不相容,然后看下一个活动。 ****************************************************************************** n代表待安排活动的总数。 task[i].s代表活动i的开始时间。 task[i].f代表活动i的结束时间。 task[i].A代表活动i是否相容,1代表相容,0代表不相容。 ============================================================================*/ voidGreedySelector(intn,activitytask[]) { sort(n,task,1); task[1].A=true; intj=1; for(inti=2;i<=n;i++) { if(task[i].s>=task[j].f) { task[i].A=true; j=i; } elsetask[i].A=false; } sort(n,task,2); } /*============================================================================ main函数(可选)是主函数。 实现输入输出,调用贪心算法函数。 这个主函数是为了测试多组数据,所以使用随机数产生数据。 一共生成5组测试数据,包括大数据和小数据。 ****************************************************************************** n代表待安排活动的总数。 task[i].s代表活动i的开始时间。 task[i].f代表活动i的结束时间。 task[i].A代表活动i是否相容,1代表相容,0代表不相容。 ============================================================================*/ /*intmain() { intn[6]={4,10,99,999,9999,99999}; inti; cout<<"----------------------贪心算法求活动安排-------------------"< for(i=0;i<6;i++) { for(intj=0;j<=n[i];j++) { task[j].num=j; task[j].s=ran(); task[j].f=ran(); } clock_tstart,end,over; start=clock(); end=clock(); over=end-start; start=clock(); //调用贪心算法求解的函数 GreedySelector(n[i],task); end=clock(); cout<<"待安排活动的总数: "< cout<<"共有"< "< if((count(task,n[i])! =0)&&(count(task,n[i])<=100)) { cout<<"最大相容活动的编号: "< for(intj=1;j<=n[i];j++) if(task[j].A==1) cout< cout< } printf("Thetimeis%6.3f\n",(double)(end-start-over)/CLK_TCK); cout<<"---------------------------------------------------------"< } return0; }*/ /*============================================================================ main函数(可选)是主函数。 实现输入输出,调用之前的贪心算法函数。 这个主函数给定单组数据,用来检测调用函数是否有问题。 用来验证结果的正确性,这里选用一组可人为判断的数据进行验证。 ****************************************************************************** n代表待安排活动的总数。 task[i].s代表活动i的开始时间。 task[i].f代表活动i的结束时间。 task[i].A代表活动i是否相容,1代表相容,0代表不相容。 ============================================================================*/ intmain() { intn; cout<<"待安排活动总数: "; cin>>n; task[0].num=0; task[0].s=0; task[0].f=0; cout<<"待安排活动开始时间结束时间: "< for(inti=1;i<=n;i++) { task[i].num=i; cin>>task[i].s; cin>>task[i].f; } clock_tstart,end,over; start=clock(); end=clock(); over=end-start; start=clock(); GreedySelector(n,task); end=clock(); cout<<"安排后..........."< cout<<"待安排活动的总数: "< cout<<"编号\t活动开始时间\t活动结束时间\t是否被相容"< for(inti=1;i<=n;i++) { cout< cout< cout< cout< } cout<<"共有"< "< printf("Thetimeis%6.3f\n",(double)(end-start-over)/CLK_TCK); return0; } /*测试数据 11 14 35 06 57 38 59 213 610 811 812 1214 */
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 活动 安排 1301 班刘悦 08080112