带期限的作业调度问题的算法与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2010-2011 第二学期08通信专业
期末考查带期限的作业调度问题的算法与实现班级08通信一班学号14082300939姓名XXXX成绩分
一、设计目的
1.掌握FIFO和LIFO宽度优先检索原理;
2.掌握LC,FIFO分枝界限法;
3.进一步掌握分枝界限法的基本思想和算法设计方法;
二、设计内容
1.任务描述
(1)给定一个带期限的作业排序问题, n=5, (p1,p2,p3,p4,p5)=(6,3,4,8,5), (t1,t2,t3,t4,t5)=(2,1,2,1,1), (d1,d2,d3,d4,d5)= (3,1,4,2,4), 应用FIFOBB求使总罚款数最小的可行作业集J. 要求:
( 2 )设计任务简介
a)阐述c’(X)和u(X)的设计思路,U的初始值;
b)针对解向量变长格式, 画出FIFOBB的生成的部分状态空间树, 按活节点生成顺序给节点编号,在各节点位置给出c’(X)和U的值,给每条边标记选择的作业编号;
c)阐述c’(X)=U的处理方案, 可行解的判断方案;
d)阐述你程序中的主要数据类型、数据变量和功能模块。
e)、编成并上机实现FIFOBB程序, 实现对不同作业排序问题实例的求解,问题实例的输入数据存储在case.txt文件中,其格式为:
第一行问题规模(最多10个作业)
第二行各作业的罚款数,数据项之间用一个空格分隔
第三行各作业的截止期限,数据项之间用一个空格分隔
第四行各作业所需的运行时间,数据项之间用一个空格分隔
例如:
4
5 10
6 3
1 3
2 1
1 2 1 1
从屏幕直接输出最优作业集的序号,数据项之间用逗号分隔。
2.任务简答
(1)阐述c’(X)和u(X)的设计思路,U的初始值;
c’(X):为当前未选的作业的罚款数。
设计思路:定义一个估计罚款数c;用来记录当前估计数,当再有一个作业分配时,看分配过程中是否有损失的效益;如果有则将其损失值与父亲节点中的c相加记录在当前分配作业的节点c 中去;如果没有损失效益则当前的节点c还是为其父节点的c。
u(X):在当前所选作业中还有可能得到的罚款数的上限值。
设计思路:在计算估计罚款数时在计算当前已得到的罚款数与没有选的作业罚款数之和,同样是记录在节点中,用节点中u记录;每做一个作业时就将其父亲节点的u减去当前所做作业的得到的效益值。即罚款数的上限不断缩小。这样就可以用其来剪去不必要的树枝,也是FIFOBB算法的原理所在。
U的初始值:所有作业的效益值。
(2)针对解向量变长格式, 画出FIFOBB的生成的部分状态空间树, 按活节点生成顺序给节点编号,在各节点位置给出c’(X)和U的值,给每条边标记选择的作业编号;
图.FIFOBB的生成的部分状态空间树
(3)阐述c’(X)=U的处理方案, 可行解的判断方案;
在这个问题上我给出对c’(x)=U的处理是:因为在这个问题中U一直都是是一个纯粹估计的上界, 保留满足c’(X) ≤ U 的活节点X所以当两者相等时,直接让此节点进队列。
可行解的判断方案:判断节点的c’(x)是否小于等于当前的U;如果是就判断为可行解,并进队列;如果大于U则为非可行解,不进队列。
3.主要数据类型与变量
Typdef struct node
{int time; //记录所选作业的总时间
int parent;//记录节点的父亲节点
int x; //记录所选的作业序号
int u; //记录罚款上限
int c; //估计罚款
int date; //记录所选作业的最后截止期限
}F;F q[30]; //定义队列结构体
数据变量
int i,j; //控制队列进出指针
int max=1000;
4.算法或程序模块
void cost(int k,int E)/*估计成本函数*/
void inter(int k,int E)/*进队列函数并缩小上限罚款成本*/ int ynset()/*判断队列是否为空函数*/
int outQ()/*出队列函数*/
void FIFOBB(int E,int t)/*分支限界算法求作业最优解函数*/ 三.测试
2.方案
在VC6.0环境下,运行;
3.结果
在E盘下写入case.txt;
Case.txt
4
5 10
6 3
1 3
2 1
1 2 1 1
由图可知选2,3便可达到最优解。
当然也可以写入多组数据:如果在case.txt中写入以下二组数据:
4
5 10
6 3
1 3
2 1
1 2 1 1
5
1 3 4 5 10
2 4 8 11 2
3 4 7 9 13
由图可知,选4便可达到最优解。
四.总结与讨论
本次实验增强了我们自主动手编程能力,我在本次编程过程中,犯的比较大的错误就是把S=0放到了while循环的外面,导致循环出了问题。在for循环可能容易发现错误,但是在while 里面我经常弄错,这是以后要注意的。
这次实验主要是加深了我们对分枝限界法的理解,终于解决了以前我把它与回溯法的混淆问题。其实分支限界法与回溯法是有很大不同的,其一,在求解目标上,回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。基二,在搜索方式上,回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。再有一点比较深的体会是,我觉得分枝界限法的关键是确定一个合理的限界函数。
本实验的设想:我们都知道分枝界限法是寻找结构主要失效模式的一种常用方法,但由于涉及到联合概率的计算而使过程相当繁琐。我的设想是如果能够取消了限界操作,就可以大大简化了计算过程,具体方法目前没有想到,不过在网上看到有人提出用PNET法的思想引入到分枝限界法中,取消了限界操作的研究。
附:程序模块的源代码
#include
typedef struct node
{
int time; //记录所选作业的总时间
int parent; //记录节点的父亲节点
int x; //记录所选的作业序号
float u,c; //u,c分别记录罚款上限和估计罚款