非单位时间任务安排问题
算法设计与分析第二版(王晓东)
算法实现题4-18 非单位时间任务安排问题(习题4-15)
问题描述:
具有截止时间和误时惩罚的任务安排问题可描述如下。
(1) 给定n个任务的集合S={1,2,…,n};
(2) 完成任务i 需要ti 时间,1 <= i <= n;
(3) 任务i的截止时间i d ,1≤i≤n,即要求任务i在时间i d 之前结束;
(4) 任务i 的误时惩罚i w ,1≤i≤n,即任务i 未在时间i d 之前结束将招致i w 的惩罚;
若按时完成则无惩罚。
任务安排问题要求确定S 的一个时间表(最优时间表)使得总误时惩罚达到最小。
编程任务:
对于给定的n个任务,编程计算总误时惩罚最小的最优时间表。
数据输入:
由文件input.txt给出输入数据。第1行是1 个正整数n,表示任务数。接下来的n行中,
每行有3 个正整数a,b,c,表示完成相应任务需要时间a,截止时间为b,误时惩罚为c。
结果输出:
将编程计算出的总误时惩罚输出到文件output.txt。
输入文件示例 输出文件示例
input.txt
7
1 4 70
2 2 60
1 4 50
1 3 40
1 1 30
1 4 20
3 6 80
output.txt
110
算法动态规划的实现:
环境:VS2010, 使用语言: C++
/***************************************************************************** File name: task_dynamic Description: 用于解决非单位时间任务安排问题 Author: MadShaw Version: 0.1 Date: 2014/11/10 History: 输入文件,第一行,表示有多少组数据,第二行 N 表示任务数,接下来 N 行中,每行有3个正整数 a, b, c, 分别表示完成相应任务需要时间 a,截止时间 b,误时惩罚 c。 1 7 1 4 70 2 2 60 1 4 50 1 3 40 1 1 30 1 4 20 3 6 80 *****************************************************************************/ #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; #define inf 655535 struct task{ int time; int deadline; int cost; }; /**************************************************************************** Function: cmp Description: 作为调用STL的sort函数的比较因子 Calls: 无 Called By: sort,sort 由 init 调用 Input: const struct task &one 比较的第一个数 const struct task &other 比较的第二个数 Output: 无 Return: 0, 表示第一个数小于第二数 1,表示第一个数不小于第二个数 Others: 无 ***************************************************************************/ int cmp(const struct task &one , const struct task &other) { return one.deadline < other.deadline; } /**************************************************************************** Function: init Description: 从文件中读取任务序列,将其存入vector中,并按任务的截止日期非降序 排列,注意更改文件读取路径 Calls: cmp, sort Called By: main Input: vector<struct task> &job 任务序列 vector< vector<int> > &map 最小误时惩罚表 int &max_deadline 所有任务的最大截止时间 Output: 无 Return: 无 Others: 无 ***************************************************************************/ void init(fstream &file, vector<struct task> &job, vector< vector<int> > &map, int &max_deadline){ //fstream file; int lines=0; //file.open(path, ios::in); file >> lines; struct task one; for(int i=0; i<lines; i++){ file >> one.time >> one.deadline >> one.cost; job.push_back(one); } sort(job.begin(), job.end(), cmp); max_deadline = (job.at(job.size()-1)).deadline; map.resize(lines, vector<int>(max_deadline+1)); for(int i=0; i<lines; i++){ for(int j=0; j<max_deadline; j++){ map[i][j] = inf; } } //file.close(); } /**************************************************************************** Function: dynamic Description: 算法的动态规划部分 Calls: 无 Called By: main Input: vector<struct task> &job 任务序列 vector< vector<int> > &map 最小误时惩罚表 int &max_deadline 所有任务的最大截止时间 Output: 已填写完成的最小误时惩罚表 Return: 无 Others: 无 ***************************************************************************/ void dynamic(vector<struct task> &job, vector< vector<int> > &map, const int &max_deadline){ vector<struct task>::iterator iter = job.begin(); for(; iter!=job.end(); iter++){ cout<<(*iter).time<<" "<<(*iter).deadline<<" "<<(*iter).cost<<endl; } for(int i=0; i<= max_deadline; i++){ if( job.at(0).time <= i ){ map[0][i] = 0; }else{ map[0][i] = job[0].cost; } } int cur_min = 0; int flag =0; for(int i=1; i<job.size(); i++){ for(int j=0; j<=max_deadline; j++){ flag =0; map[i][j] = map[i-1][j] + job.at(i).cost; cur_min = job.at(i).deadline > j ? j:job.at(i).deadline; if( ( cur_min >= job.at(i).time ) && ( map[i][j] > map[i-1][cur_min - job.at(i).time]) ){ map[i][j] = map[i-1][cur_min - job.at(i).time]; flag =1; } } } } /**************************************************************************** Function: read_map Description: 从动态规划的表中读取任务安排 Calls: 无 Called By: main Input: vector<struct task> &job 任务序列 vector< vector<int> > &map 最小误时惩罚表 int job_size 任务数 int max_deadline 所有任务的最大截止时间 Output: 及时任务安排表,误时任务安排表 Return: 无 Others: 无 ***************************************************************************/ void read_map(vector<struct task> &job, vector < vector<int> > &map, int job_size, int max_deadline){ cout<<endl<<"最小误时惩罚:"<<map[job_size-1][max_deadline]<<endl; int job_id=0; int deadline=0; vector<bool> seq(job_size, true); job_id= job_size-1; deadline = max_deadline; int first_punish = 0; int second_punish = 0; int min_deadline = 0; while( (job_id>=1) && (deadline>=0) ){ first_punish = map[job_id-1][deadline] + job[job_id].cost; min_deadline = deadline > job[job_id].deadline ? job[job_id].deadline : deadline; if(deadline>0){ second_punish = map[job_id-1][min_deadline - job[job_id].time]; } if( deadline !=0 ){ if(first_punish < second_punish){ seq[job_id] = false; }else{ deadline = min_deadline - job[job_id].time; } }else{ if( first_punish == map[job_id][deadline]){ seq[job_id] = false; } } job_id--; } //查找第一个及时任务 int first_instance = 0; for(int i=1; i!=job.size(); i++){ if(!seq[i]){ first_instance = i; break; } } //确定第一个任务是否为误时任务 int cur_time = 0; for(int i=first_instance; i!=job.size(); i++){ cur_time += job[i].time; if( job[0].time + cur_time> job[i].deadline){ seq[0] = false; break; } } cout<<endl<<"及时任务:"<<endl; for(int i=0; i!=job.size(); i++){ if(seq[i]){ cout<<job[i].time<<" "<<job[i].deadline<<" "<<job[i].cost<<endl; } } cout<<"已误时任务:"<<endl; for(int i=0; i!=job.size(); i++){ if(!seq[i]){ cout<<job[i].time<<" "<<job[i].deadline<<" "<<job[i].cost<<endl; } } } int main(){ vector<struct task> job; vector < vector<int> > map; int max_deadline=0; string path="C:\\Users\\MadShaw\\Desktop\\input.txt"; int count = 0; fstream file; file.open(path, ios::in); file >> count; for(int i=0; i<count; i++){ cout<<"***********第"<<i+1<<"组数据********"<<endl<<endl; init(file, job, map, max_deadline); dynamic(job, map, max_deadline); read_map(job, map, job.size(), max_deadline); cout<<endl; job.clear(); map.clear(); } file.close(); system("pause"); return 0; }
时空复杂度:


浙公网安备 33010602011771号