【贪心法】多机调度问题

题目(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):
将机器1016的时间段分配给作业4
将机器2014的时间段分配给作业2
将机器306的时间段分配给作业3
将机器369的时间段分配给作业5
将机器3911的时间段分配给作业1

示例2(Sample):

输入(Input):
7
3
6 8 18
输出(Output):
将机器1018的时间段分配给作业3
将机器208的时间段分配给作业2
将机器306的时间段分配给作业1

思路

采用贪心策略:耗时最长的作业最先分配给最先空闲的机器
机器数量:m
作业数量:n
m ≥ n m \ge n mn,机器富余,只要将机器 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值