带期限的作业排序问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
带期限的作业排序问题
(1)
答:c`(x)的设计思路:当x=1时,c`(x)为所有作业的罚款金额总和,某节点m的估计值为c`(x),并对其进行扩展时,其有效的子节点a的c`(x)为m的c`(x)-a的罚款金额。
对于u(x)初始时为作业罚款金额总和。之后,若队列中的某一节点b的c`(x)最小且小于u(x),则使u(x) =b. c`(x)
(2)
(3)当某节点的已经被罚款项即c(x)>U,则封杀此节点。
(4)当从根开始到当前要加入的节点这条路径中,共花费时间costtime ,最大截止期限为maxdeadtime,若maxdeadtime (5)主要结构及类型说明 node queue[1000];//存放状态空间树中的节点 Node结构在构造状态空间树时使用 struct node { int number;//所代表的作业在source[]的下标 int mayfine;//可能的罚款的金额即罚款金额的上限 int currentfine;//到此节点止已罚款的金额 bool iskilled;//是否被杀死 int timecost;//从根节点到此节点为止已花费的时间 int parent;//父节点在queue[]的下标 }; Tast结构在输入作业信息时使用 struct task { int number;//作业的序号 int fine;//罚款金额 int deadline;//截止期限 int time;//完成此作业所需的时间 }; int ans=0;//最小上界值在queue的下标 int minmayfine;//队列中活结点的罚款上限的最小值即U int activenumber=1;//活结点的数目 const int N = ?;//N表示作业数 int size = 1;//当前队列中的元素个数 程序代码 思想://使作业按截至期限的非降序排列,则对一个父节点s,要加入一个节点m,只要m 的截至期限大于等于s.timecost+m所代表的作业的time #include #include using namespace std; struct node int number;//选择的节点在source[]的下标 int mayfine;//可能的罚款的金额即罚款金额的上限 int currentfine;//到此节点止已罚款的金额 bool iskilled;//是否被杀死 int timecost;//从根节点到此节点为止已花费的时间 int parent;//父节点在queue[]的下标 }; struct task { int number;//作业的序号 int fine;//罚款金额 int deadline;//截止期限 int time;//完成此作业所需的时间 }; //节点被杀死的条件是已罚款的金额超过了最小罚款金额即currentfine>mayfine node queue[1000];//存放状态空间树 const int N = 4;//N表示作业数 task source[N+1] = {{0,0,0,0}, {1,5,1,1}, {2,10,3,2}, {3,6,2,1}, {4,3,1,1}};//作业集合 int ans=0;//最小上界值在queue的下标 int minmayfine;//队列中活结点的罚款上限的最小值 int activenumber=1;//活结点的数目 void init()//初始化队列 { for (int i =1; i <= N; i++) { minmayfine +=source[i].fine; } queue[0].mayfine = minmayfine; queue[0].currentfine =0; queue[0].iskilled =0; queue[0].number = 0;//作业的序号 queue[0].parent = -1; queue[0].timecost =0; } bool greater(task x,task y) { if (x.deadline <= y.deadline) return 1; else return 0; } //aloca为节点m在queue[]的下标,b为m的子节点x的作业在source[]的下标,获取x到目 前为止已罚款数 int getfine(int aloca,int b) { int a = queue[aloca].number;//a为节点m在source[]中的下标 int fine = queue[aloca].currentfine; for(int i = a+1;i fine += source[i].fine; return fine; } void construction() { sort(source+1,source+N+1,greater);//截止期限按非降序排列 int size = 1;//当前队列中的元素个数 int active =0;//正在扩展的活结点的下标 int a; int costtime; while (activenumber != 0) { //当一个节点已罚的款数大于最终罚款的上界的最小值,则杀死并查找下一个活结点 if(queue[active].currentfine > minmayfine ) { queue[active].iskilled = 1; active++; activenumber--;//活结点减少1 continue; } //向后选择作业,直到所有的组合都选择完 a=queue[active].number+1; while (a<=N) { costtime = queue[active].timecost+source[a].time; if (costtime <= source[a].deadline) { queue[size].currentfine = getfine(active,a);//a为在source[]中的下标 queue[size].iskilled =0; queue[size].mayfine = queue[active].mayfine - source[a].fine; queue[size].parent = active; queue[size].number = a; queue[size].timecost = costtime; //寻找队列中最终罚款的上限的最小值 if(queue[size].mayfine < minmayfine) { minmayfine = queue[size].mayfine;//答案节点的上界即U