题目(Description):
要求给出一种作业调度方案,使所给的n个作业(假定作业数量n不超过20)在尽可能短的时间内由m台机器加工处理完成。约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。作业不能拆分成更小的子作业。
输入(Input):
(1)机器台数;
(2)作业数量;
(3)每个作业的完成时间。
输出(Output):
将机器Mi从time1到time2的时间段分配给作业Nj
示例1(Sample):
输入(Input):
3
5
2 14 6 16 3
输出(Output):
将机器1从0到16的时间段分配给作业4
将机器2从0到14的时间段分配给作业2
将机器3从0到6的时间段分配给作业3
将机器3从6到9的时间段分配给作业5
将机器3从9到11的时间段分配给作业1
示例2(Sample):
输入(Input):
7
3
6 8 18
输出(Output):
将机器1从0到18的时间段分配给作业3
将机器2从0到8的时间段分配给作业2
将机器3从0到6的时间段分配给作业1
思路
采用贪心策略:耗时最长的作业最先分配给最先空闲的机器
机器数量:m
作业数量:n
①
m
≥
n
m \ge n
m≥n,机器富余,只要将机器
i
i
i的时间区间
[
0
,
t
i
]
[0,t_i]
[0,ti]分配给作业
i
i
i即可
②
m
<
n
m<n
m<n,机器不足,需要轮流作业,首先将n个作业按照其耗时大小排序,依序将作业分配给最先空闲的机器
算法实现
#include <iostream>
#include <algorithm>
#define N 20
#define M 20
using namespace std;
struct node{
int value;
int index;
};
bool cmp(struct node &a, struct node &b) { return a.value > b.value; }
void multimachine(struct node t[], int n, int d[], int m) {
int S[M][N]; // M台机器 N个作业
int rear[M]; // S[i]为存储机器i处理作业的队列,rear[i] 是队尾下标
int i, j, k;
// 作业繁重 机器不足 轮流作业
if (n>m) {
cout << "\n机器\t" << "作业\t" << "开始\t" << "结束\t" << endl;
for (i=0; i<m; i++) {
S[i][0] = t[i].index;
rear[i] = 0;
d[i] = t[i].value;
cout <<i+1<<"\t"<<t[i].index<<"\t"<<0<<"\t"<<d[i]<<endl;
}
for(i=m; i<n; i++) {
for(j=0, k=1; k<m; k++) { //查找最先空闲的机器
if(d[k] < d[j]) j=k;
}
rear[j] ++;
S[j][rear[j]] = t[i].index; //将作业ti 插入队列S[j]
cout <<j+1<<"\t"<<t[i].index<<"\t"<<d[j]<<"\t"<< d[j]+t[i].value <<endl;
d[j] += t[i].value;
}
}
// 作业少 机器富余 直接分配
else {
for (i=0; i<n; i++) {
S[i][0] = t[i].index;
rear[i] = 0;
d[i] = t[i].value;
cout <<i+1<<"\t"<<t[i].index<<"\t"<<0<<"\t"<<d[i]<<endl;
}
}
}
int main()
{
int n, m, i;
int d[M];
struct node t[N]; //作业时间
cin >> m >> n; // 机器数量 作业数量
for(i=0; i<n; i++) {
cin >> t[i].value;
t[i].index = i+1;
}
sort(t,&t[n],cmp);
multimachine(t,n,d,m);
return 0;
}