prioritywork实验报告Word文件下载.docx
- 文档编号:22949177
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:23
- 大小:420.94KB
prioritywork实验报告Word文件下载.docx
《prioritywork实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《prioritywork实验报告Word文件下载.docx(23页珍藏版)》请在冰豆网上搜索。
✧优先级队列要求完成主要的功能,包括作业的插入、最小优先级作业的提取和删除、各个作业优先级的修改等;
;
✧要求源程序中有相应注释
✧要求测试例子要比较详尽,各种极限情况也要考虑到,测试的输出信息要详细易懂,表明各个功能的执行正确,包括何时作业进入,何时调度哪个作业,何时离开,每个作业等待多长时间,优先数的动态变化情况等;
设计分析:
●类的设计
Program:
自定义的作业类。
MinAdt:
自定义的最小堆,用于实现优先级队列
minPQ:
自定义的优先级队列,帮助工程类的实现
Work:
模拟作业调度系统定义的工程类,模拟处理作业的过程。
类的关系图
MinAdt
(最小堆类)
Work
(工程类)
实现工具
数据类型
Program
(作业类)
minPQ
(优先级队列类)
✧基本数据结构类的设计:
a.堆MinAdt(最小堆):
因为题目中的优先级是按照作业优先级数越小,优先级越高,所以设计最小堆即可用于实现优先级队列。
这里没有设计类模板,直接以Program(作业类为类型)
数据成员
vector<
Program>
programs
popHeap
pushHeap
adjustTop
size
top
empty
成员函数
makeHeap
⏹vector<
programs;
//储存二叉树的向量
⏹voidadjustTop(intbegin,intlast);
//根的下调操作,将一个近似堆调整为堆(近似堆:
即除根节点外其他节点满足对结构)
【以下代码是下调主要思路】
Ø
{
if(begin>
=0&
&
last>
begin)//一个元素就不用调整了
{
......
while(ptr<
=last)//ptr<
last表示目标节点可能还不在正确位置
if(ptr<
last&
programs[ptr]>
programs[ptr+1])//调整ptr的值,使ptr表示左右节点中较小元素的下标。
ptr=ptr+1;
if(programs[com]>
programs[ptr])//如果被调整元素比他的子节点元素大,则交换两个节点的值。
{......}
else//如果没有进行下调过程,则表示begin~last的元素满足堆结构,直接跳出函数。
return;
}}}
⏹boolempty();
//判断堆是否为空,即是否有元素存在
⏹intsize();
//返回堆中元素的个数
⏹voidpushHeap(Program&
pro);
//加入一个新的元素到堆中,调整为一个新的堆
this->
programs.push_back(pro);
//将新节点加到堆中
......//son表示需要作调整的节点的当前下标位置,father表示以此节点的根节点的当前下标位置
while(son>
0&
!
(this->
programs[son]>
=this->
programs[father]))////son=0,表示目标节点已经调整到根节点位置,跳出循环,或者子节点大于等于父节点的值
if(!
programs[father]))//如果子节点的值小于父节点的值,则交换两个节点的内容
}
}
⏹voidpopHeap();
//删除根节点元素,并将二叉树调整为新堆
intsize=programs.size();
programs[0]=this->
programs[size-1];
//将最后一个元素提到头结点的位置,0~size-2除根节点以外满足堆结构
adjustTop(0,size-2);
//将根节点调整到合适的位置,使0~size-2满足堆结构
......//删除向量中最后一个元素
⏹voidmakeHeap();
//将一个储存完全二叉树的向量调整为储存最小堆的的向量
if(programs.size()!
=1&
programs.size()!
=0)//先排除只有一个元素和空堆得情况
for(inti=programs.size()/2-1;
i>
=0;
i--)//从第一个不是叶节点的节点开始,从下往上依次做一次根节点下调过程
adjustTop(i,programs.size()-1);
b.minPQ(优先级队列):
利用自定义的最小堆实现优先级队列,实现主要的功能,包括作业的插入、最小优先级作业的提取和删除、各个作业优先级的修改等,优先级队列中储存的数据类型为Program。
MinAdtmi
changeRank
push
pop
⏹minPQ(vector<
//队列的构造函数
⏹voidpop();
//删除队列中优先级最高的项,并重新排列队列
⏹voidpush(Program&
//在队列中加入新项,并重新排列队列
⏹Programtop();
//返回优先级最高的项
⏹boolempty();
//判断队列知否为空
⏹intsize();
//返回队列的中元素的个数
⏹voidchangeRank();
//将队列中每一项的优先级减一
✧作业类以及工程类的设计
a.Program(作业类):
Staticintsum
Program
Intrank
Intlength
operator>
operator=
intnumber
⏹staticintsum;
//总的作业数
⏹intlength;
//作业的长度
⏹intrank;
//作业的等级
⏹intnumber;
//作业标号
⏹Program();
//无参构造函数,长度随机给定
⏹Program(intlen);
//有参构造函数,长度给定
⏹voidoperator=(constProgram&
//复制赋值函数
⏹booloperator>
(constProgram&
//Program的大小比较既要考虑rank的大小,也要考虑number的大小
if(this->
rank<
pro.rank)//优先考虑优先级的大小
return1;
elseif(this->
rank>
pro.rank)
return0;
else//如果优先级一样,则考虑作业的标号大小,实现优先级相同作业,先进先出
returnthis->
number<
pro.number;
⏹booloperator<
b.Work(工程类):
模拟优先级作业调度系统的运行的过程,并设计调试程序代码函数
inttime
minPQobjects
insertPro
showWork
startWork
⏹minPQobjects;
//储存作业组的堆
⏹inttime;
//工程运行的时间
⏹voidshowWork();
//显示当前工程内所有作业的详细情况
⏹voidinsertPro();
//随机产生1~3项新作业,并加入到工程中
intnum=rand()%3+1;
//新加入的作业个数可能是1~3中任意数
......//提示新作业即将显示
for(intj=1;
j<
=num;
j++)
Programpro;
//随机产生一个作业
objects.push(pro);
//这里sum多加了一份
......//显示新作业信息
showWork();
//将加入如新工程后的进程中的总项目展现出来
⏹voidstartWork();
●程序流程的设计:
整个程序的流程其实是在Work类中的starkWork()
✧startWork()
先新建一个作业组(作为工程初始时系统内待处理的工作组)
NO
此作业处理完毕
每运行1s,工程内所有作业优先级减一
If(待处理工作数<
MAX_SIZE)
YES
保证加入新工作后工程不会超出超出容量
用sleep函数模拟处理过程
按20%的概率,在1S工程运行结束的间隙,向工程内加入1~3个新作业
处理优先级最高的作业
If(工程内还有作业待处理)
作业处理完毕,关闭工程
将工作组加到工程中,等待处理。
。
//自动运作的工程
intsum=rand()%3+1;
//sum表示工程刚开始运行时,工程内存在的作业数,sum随机产生,在1~3之间
for(inti=0;
i<
sum;
i++)//随机产生sum个作业,放到储存作业组的优先级队列中。
Programcurr;
this->
objects.push(curr);
Programcurr=objects.top();
//curr优先级最高的作业副本
while(!
objects.empty())//作业还未处理完
......
objects.pop();
for(intt=curr.length;
t>
0;
t--)
{
Sleep(1000);
//处理每单位长度的作业,系统停止运行1000ms,模拟处理过程
time++;
//工程运行时间+1
this->
objects.changeRank();
//将工程中所有作业的优先级都减一
if(this->
objects.size()<
=MAX_SIZE&
rand()%5==0)//在队列中的作业组元素不超过MAX_SIZE的前提下,按20%的几率向工作组中加入新工作
this->
insertPro();
}
......;
curr=objects.top();
二、实验验证分析
✧输入的形式和输入值的范围:
1.输入形式及输入值得范围:
1 输入一组数据,作为初始作业组的长度,并输入-1表示输入结束
2 输入的作业不得超过10个
3 每个作业的长度范围:
0<
=length<
=4
输出样本
2.输出形式:
模拟系统运行过程,详细显示运行过程中系统内各个作业的信息,以及新加入作业组的信息,加入新作业后系统内作业组的信息。
每个作业运行结束,显示当前作业运行总时间,等待时间,和实际运行时间。
部分输出样本:
✧程序所能达到的结果:
能使模拟系统根据作业的优先级大小顺序处理作业,原始优先级只与作业的长度相关,但运行过程的优先级要根据系统运行的时间发生改变,以实现先入先出的原则。
运行过程中,系统会随机产生作业组加到系统中,系统将新的工作组按照优先级大小进行排序。
系统能随时提取出,当前正在处理的作业的详细信息,以及系统内正在等待处理的作业组的信息。
✧测试数据:
1.正确输入:
输入:
123-1
输出
2.错误输入
错误一:
输入作业数超过系统容量,及作业数>
10
1111111111-1
输出:
错误二:
作业长度不合理,及length<
0或length>
4
5,3,-1
输出
3、调试分析
✧基础问题
1.静态数据类型的使用:
:
sum的初始化
解决:
静态数据类型要在class外实现,且要放在cpp文件上声明。
2.vector的运用:
1 end()的误用
解决:
End()返回的向量中最后一个元素后面位置的指针
2 earse()函数的调用
函数括号内是指针值,不是元素值
3.rand()的用法
a+rand()%n
其中的a是起始值,n是整数的范围。
若要0~1的小数,则可以先取得0~10的整数,其它情况依此类推。
通常rand()产生的随机数在每次运行的时候都是与上一次相同的,这是有意这样设计的,是为了便于程序的调试。
4.sleep()的用法
1 Sleep函数//S要大写
2 头文件#include<
windows.h>
3 函数调用形式Sleep(5000);
//单位是毫秒
✧技术问题
1.作业关系大小的设计
错误理解:
以为只要比较作业的优先级就可以了,这样设计无法实现先进先出的原则
解决:
设计作业大小比较时,优先考虑作业的优先级,如果优先级一样的话,再根据作业的number值比较大小(即进入系统的先后顺序)
2.Sum值变化的异样
错误情况:
sum值的多加现象,会直接导致作业number值不正确,使作业运行顺序出现错误。
错误原因及解决方案:
1.每次工程结束之后没有没有将sum至0,导致第二次启动系统时,作业的number出现问题
只要在StartWork()函数最后将sum归0就好
2.在调用voidminPQ:
push(Program&
pro),sum会加两次
voidminPQ:
pro)
mi.pushHeap(pro);
//Program:
sum--;
//如果不把多加的sum减掉
错误导致(新加入的作业的number是错的)
加上Program:
sum--
正确运行结果
3.最小堆adjustTop()函数的设计
难点:
1 下标值以及number值得相互转化:
下标值与number相差一,所以在计算父节点的下标值时要考虑清楚
2 调整节点条件的分析
当二叉树只有一个节点时,不需要进行下调工作
因为进行下调操作的是一个近似堆,只要被调整元素比它的两个子节点多小,就可以直接跳出循环
节点比较不需要考虑相等的情况,因为每个作业的number值一定是不一样的,所以就算rank一样,也一定不会相等
4、测试结果分析:
✧程序的运行结果
加入新作业组后,系统内的所有作业情况。
这里显示的顺序貌似有问题,其实是因为,打印顺序是按照储存二叉树的向量的下标顺序打印的,是满足最小堆的顺序的。
显示神额时候有新作业组加入,以及作业组的信息,注意新作业的number值是跟着之前的nnmber值得。
显示什么时间开始运行哪个作业
已经根据优先级进行排序了
正确输入:
作业长度在合理范围内,作业数不超过容量
每个作业运行完成之后,会显示此作业在什么时候处理完毕,在系统总共消耗的时间,以及等待的时间。
作业长度
作业编号
满足先入先出原则
1
2
3
1
5
6
运行顺序
✧边界数据、或极端数据测试
1 调试优先队列是否满足先进先出原则
Programp1[10]={1,1,1,1,1,1,1,1,1,1};
vector<
test1(p1,p1+10);
Worktest11(test1);
test11.StartWork();
运行结果
7
8
9
由结果易知,验证正确
2 调试工程是否按照优先级队列运行工程
Programp2[5]={4,4,3,2,1};
//调试工程是否按照优先级队列运行工程
test2(p2,p2+5);
Worktest22(test2);
test22.StartWork();
5、附录
在“priority_work”文件夹中
✧Priority_work.h
✧Prority_work.cpp
✧Main_cpp
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- prioritywork 实验 报告