计算机算法实验3 贪心算法 报告.docx

上传人:b****6 文档编号:4685449 上传时间:2022-12-07 格式:DOCX 页数:15 大小:90.28KB
下载 相关 举报
计算机算法实验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/1/6

目录

1实验目的与要求1

2实验内容1

2.1基本题一:

多机调度问题1

2.1.1问题概述1

2.1.2实验截图1

2.2提高题一:

用贪心算法求解最小生成树2

2.2.1问题概述2

2.2.2实验截图2

2.3提高题二:

汽车加油问题3

2.3.1问题概述3

2.3.2实验截图3

3实验心得4

代码附后面

1实验目的与要求

1、熟悉多机调度问题的算法

2、初步掌握贪心算法

3、熟悉贪心算法的基本原理与适用范围

4、使用贪心算法编程,求解最小生成树问题

5、掌握汽车加油问题的算法

2实验内容

2.1基本题一:

多机调度问题

2.1.1问题概述

要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。

约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。

作业不能拆分成更小的子作业。

提示:

1、把作业按加工所用的时间从大到小排序

2、如果作业数目比机器的数目少或相等,则直接把作业分配下去

3、 如果作业数目比机器的数目多,则每台机器上先分配一个作业,如下的作业分配时,是选那个表头上s最小的链表加入新作业。

2.1.2实验截图

按照书本例题数据,7个作业分给3台机器,完成时间为17,实验结果如下:

2.2提高题一:

用贪心算法求解最小生成树

2.2.1问题概述

任选一种贪心算法(Prim或Kruskal),求解最小生成树。

对算法进行描述和复杂性分析。

编程实现,并给出测试实例

2.2.2实验截图

算法为Kruskal,选用书本例题数据,六个定点,十条边,求解结果如下:

2.3提高题二:

汽车加油问题

2.3.1问题概述

一辆汽车加满油后可以行驶N千米。

旅途中有若干个加油站。

若要使沿途的加油次数最少,设计一个有效的算法,指出应在那些加油站停靠加油。

并证明你的算法能产生一个最优解。

把两加油站的距离放在数组中,a[1..n]表示从起始位置开始跑,经过n个加油站,a[k]表示第k-1个加油站到第k个加油站的距离。

汽车在运行的过程中如果能跑到下一个站则不加油,否则要加油。

2.3.2实验截图

输入3代表加油站段目,50代表加油后最大行驶距离结果如下:

再换一个例子:

3实验心得

这次算法实验的主要内容是贪心算法的使用,包括多机调度问题,最小生成树问题(采用Kruskal算法),汽车加油问题。

贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。

用贪婪法设计算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,它省去了为找最优解要穷尽所有可能而必须耗费的大量时间,它采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。

贪心算法是算法的重要内容之一,可以高效地解决许多问题。

采用贪心算法会比动态规划高效方便,如果都能解决某个问题的话。

现在我学习贪心算法的时间还不长,理解还很浅显,以后要多加练习,这样才能做到熟练运用。

基本题一:

多机调度问题

#include

usingnamespacestd;

#defineN10

typedefstructnode{

intID,time;//作业所需时间

}jobnode;

typedefstructNode{

intID,avail;//ID机器编号avail每次作业的初始时间

}manode;

manodemachine[N];jobnodejob[N];/*

找出下个作业执行机器*/

manode*Find_min(manodea[],intm){

manode*temp=&a[0];

for(inti=1;i

if(a[i].availavail)

temp=&a[i];

}

returntemp;

}/*

对作业时间由大到小进行排序*/

voidSort(jobnodet[],intn){

jobnodetemp;

for(inti=0;i

for(intj=n-1;j>i;j--){

if(job[j].time>job[j-1].time){

temp=job[j];

job[j]=job[j-1];

job[j-1]=temp;

}

}

}

voidmain(){

intn,m,temp,i;manode*ma;

printf("输入作业数目(作业编号按输入顺序处理)\n");

cin>>n;

printf("输入相应作业所需处理时间:

\n");for(i=0;i

cin>>job[i].time;job[i].ID=i+1;

}

printf("输入机器数目(机器编号按输入顺序处理)\n");

cin>>m;

for(i=0;i

{

machine[i].ID=i+1;machine[i].avail=0;

}

putchar('\n');if(n<=m){

printf("为每个作业分配一台机器,可完成任务!

\n");return;

}

Sort(job,n);

for(i=0;i

ma=Find_min(machine,m);

printf("将机器:

M%d从%d----->%d的时间段分配给作业:

%d\n",

ma->ID,ma->avail,ma->avail+job[i].time,job[i].ID);

ma->avail+=job[i].time;}

temp=machine[0].avail;for(i=1;i

if(machine[i].avail>temp)temp=machine[i].avail;

}

putchar('\n');

printf("该批作业处理完成所需加工时间为:

%d\n",temp);

}

2提高题一:

用贪心算法求解最小生成树

/*****************************************************

该程序用贪心算法来求解最小生成树问题

采用贪婪准则:

每次选择边权值最小边。

如果该边加入后

不构成环,则加入。

*******************************************************/

#include

#include

usingnamespacestd;

intconstCNST_Numgrphedge=100;

structTTreeEdge//最小生成树的边类型

{

longv1,v2;//边的起点与终点编号

floatweight;//边权

};

/**************************

全局变量

***************************/

intty=0;//纪录返回边的个数(作为引用参数中数组的下标)

/******************************************************

该函数通过贪心算法求出最小生成树,返回值为最小生成树中

的边(起点与终点编号与边权),通过引用参数edge返回值

*******************************************************/

voidminspanningTree(TTreeEdgetreeedge[],intn,inte,TTreeEdge*edge)

{

/********************************************

treeedge[]为图最初的起点与终点编号与边权

n为顶点数

e为边数

引用参数edge[]为最小最小生成树中的边(起点

与终点编号与边权)

********************************************/

inti,j,u,v,p;

inttempa[CNST_Numgrphedge];//临时数组,该数组存储连通变量

longtemp1,temp2;//改进的冒泡排序中所用参数

floattemp3;//改进的冒泡排序中所用参数

intm,kk;//改进的冒泡排序中所用参数

/**********************************************

按照边的权值从小到大排序(采用改进的冒泡排序)

***********************************************/

m=e-1;

while(m>0)

{

kk=0;

for(j=0;j

if(treeedge[j].weight>treeedge[j+1].weight)

{

temp1=treeedge[j].v1;

treeedge[j].v1=treeedge[j+1].v1;

treeedge[j+1].v1=temp1;

temp2=treeedge[j].v2;

treeedge[j].v2=treeedge[j+1].v2;

treeedge[j+1].v2=temp2;

temp3=treeedge[j].weight;

treeedge[j].weight=treeedge[j+1].weight;

treeedge[j+1].weight=temp3;

kk=j;

}

m=kk;

}//while

/******************************************

初始化临时数组,该数组存储连通变量

*******************************************/

for(i=0;i

tempa[i]=i;

p=1;

for(j=0;p

{

u=treeedge[j].v1;//边的起点

v=treeedge[j].v2;//边的终点

/*************************************************

如果起点与终点的连通变量不相等,则加入,将这条边

的起点与终点编号与边权存入引用参数edge中,并改变

临时数组的值

************************************************/

if(tempa[u]!

=tempa[v])

{

edge[ty].v1=u;//将选中边的起点编号存入引用参数edge中

edge[ty].v2=v;//将选中边的终点编号存入引用参数edge中

edge[ty].weight=treeedge[j].weight;//将选中边的边权存入引用参数edge中

ty++;//边数加1

p++;//边数加1

for(i=0;i

if(tempa[i]==tempa[v])

tempa[i]=tempa[u];//改变临时数组的值

}

}

}

voidmain()

{

inti,e,n;

intb;

intAgain=0;

charyn;

TTreeEdgetreeedge[CNST_Numgrphedge];

TTreeEdgeedge[CNST_Numgrphedge];

cout<<"****************************************************"<

cout<<"该程序用贪心算法来求解最小生成树问题。

"<

cout<<"采用贪婪准则:

每次选择边权值最小边。

"<

cout<<"如果该边加入后不构成环,则加入。

"<

cout<<"****************************************************"<

while(!

Again)

{

cout<<"----------------------------------------------------"<

cout<<"请输入图的顶点数:

";

cin>>n;

/****************************************

判断输入图的顶点数的合法性!

****************************************/

b=0;

while(!

b)

{

if(n<3)

{

cout<<"输入错误!

顶点数不能小于3个!

"<

cout<<"请重新输入图的顶点数:

";

cin>>n;

}

else

b=1;

}//while

cout<<"请输入图的边数(最多"<

";

cin>>e;

/****************************************

判断输入图的边数的合法性!

****************************************/

b=0;

while(!

b)

{

if(e>(n*(n-1))/2)

{

cout<<"输入错误!

顶点数为"<

"<

cout<<"请重新输入图的边数(最多"<

";

cin>>e;

}

else

b=1;

}//while

cout<<"请输入图的各条边的起点位置、终点位置、边权(起/终点位置用数字输入):

"<

for(i=0;i

{

cin>>treeedge[i].v1>>treeedge[i].v2>>treeedge[i].weight;

/********************************************************

判断输入图的各条边的起点位置、终点位置、边权的合法性!

*********************************************************/

b=0;

while(!

b)

{

if(treeedge[i].v1<0|treeedge[i].v2<0|treeedge[i].weight<0)

{

cout<<"输入错误!

边的起点位置、终点位置、边权不能小于0!

"<

cout<<"请重新输入该条边的起点位置、终点位置、边权(起/终点位置用数字输入):

"<

cin>>treeedge[i].v1>>treeedge[i].v2>>treeedge[i].weight;

}

else

b=1;

}//while

}

/********************

调用函数

*********************/

minspanningTree(treeedge,n,e,edge);

/*******************************************************

输出引用参数edge[]中存储的边的起点位置、终点位置、边权

********************************************************/

cout<<"最小生成树所包含的边为:

(依次为边的起点位置、终点位置、边权)"<

for(i=0;i

cout<

/********************************************

是否进行下一个最小生成树问题的求解

*********************************************/

cout<<"\n继续进行另一个最小生成树问题的解答吗?

(Y/N)";

cin>>yn;

if(yn=='Y'||yn=='y')

Again=0;

else

if(yn=='N'||yn=='n')

Again=1;

elsebreak;

}

}

3提高题二:

汽车加油问题

#include

usingnamespacestd;

intmain()

{

intOilStationNum;//加油站的数目

intMaxDist;//汽车加满油以后行驶的最大距离

intDiscOfCar;//汽车一次加油后已经行驶的距离

intCount;

int*OilStationDist;

printf("请输入加油站的段数(用整数表示):

");

cin>>OilStationNum;

printf("汽车加满油以后行驶的最大距离(用整数表示):

");

cin>>MaxDist;

OilStationDist=newint[OilStationNum-1];

printf("请输入各加油站之间的距离(假设不能有环路):

\n");

for(Count=0;Count<=OilStationNum-1;)

{

cin>>OilStationDist[Count];

if(OilStationDist[Count]<=MaxDist)Count++;

else

printf("你输入的加油站之间的距离大于汽车加满油以后行驶的最大距离,请重新输入当前距离!

\n");

}

DiscOfCar=0;

Count=0;

while

(1)

{

if(DiscOfCar<=MaxDist)

{

DiscOfCar+=OilStationDist[Count];

Count++;

}

else

{

Count--;

printf("当前汽车需要在%d号加油站处加油,此时汽车行驶了%d公里\n",Count,DiscOfCar-OilStationDist[Count]);

DiscOfCar=0;

}

if(Count>OilStationNum)

{

//printf("当前汽车到达终点,此时汽车距上一次加油行驶了%d公里\n",DiscOfCar);

break;

}

}

return0;

}

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

当前位置:首页 > 工作范文 > 行政公文

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

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