带期限的作业排序问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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

相关文档
最新文档