2021-06-21

本文探讨了如何使用贪心算法解决多机调度问题,通过实例分析了将作业按处理时间从长到短分配给m台机器的不同策略,包括平均分配、按顺序分配及贪心策略,以期找到最短的总处理时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

求解多机调度问题 —— 贪心算法

  1. 问题分析
    设有n个独立的作业{1, 2, …, n},由m台相同的机器{M1, M2, …, Mm}进行加工处理,作业i所需的处理时间为ti(1≤i≤n),每个作业均可在任何一台机器上加工处理,但不可间断、拆分。多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。
  2. 问题的解决方法
    贪心算法求解多机调度问题的贪心策略是最长处理时间的作业优先,即把处理时间最长的作业分配给最先空闲的机器,这样可以保证处理时间长的作业优先处理,从而在整体上获得尽可能短的处理时间。

作业的个数为n,机器的数目为m
A: n<m
这种情况很简单,将n个作业分配给m个机器中的n个就可以了。
B: n>m
设7个独立作业{1, 2, 3, 4, 5, 6, 7}由3台机器{M1, M2, M3}加工处理,各作业所需的处理时间分别为{2, 14, 4, 16, 6, 5, 3}。这里给出三种解决办法:

(1)将作业平均分配给每个机器,所需的时间总共为22。
这样的算法思路简单,容易上手。但是没有考虑时间的节省问题,机器所运行的作业完全由作业的次序决定,当运行时间较长的作业集中在一起时,它们会被分配给同一个机器,效率较低。
如表1所示:

机器作业时间
M11,2,32+14+4=20
M24,516+6=22
M36,75+3=8
(2)将作业按从小到大的顺序依次分配给空闲的机器。
		 时间为:2,7,23。

这种算法实现较为方便,同时也有考虑到时间的安排。但是运行时间最长的作业一定是最后完成的,如果运行最长作业前,其他机器运行时间相差无几,就会造成几个机器等待一个机器的状况,这样机器的运行效率比较低。
如表2所示:

机器作业时间
M11,62+5+16=23
M27,53+6=9
M33,24+8=12

(3)通过对上面两种算法的思考,会想到把作业按从大到小的顺序一次分配给空闲的机器m 时,首先将 n 个作业依其所需的处理时间从大到小措序,然后依此顺序将作业分配给空闲的处理机,如图3所示。
按 贪心算法产生的作业调度如图。所需要的加工时间为17。

在这里插入图片描述
时间长为6, 11 ,15,17。这种算法很明显首先挑选了处理时间比较长的作业,这正是贪心算法的特点,总是做出在当前看来最好的选择,也就是说贪心算法并不从整体考虑,他所作出的选择只是在某种意义上局部最优的选择。

  1. 测试

在这里插入图片描述

  1. 结论
    对于多机调度问题的求解,首先我们需要把作业按加工所用的时间从大到小排序;然后如果作业数目比机器的数目少或相等,则直接把作业分配下去;最后如果作业数目比机器的数目多,则每台机器上先分配一个作业,如下的作业分配时,是选那个表头上最小的链表加入新作业。

  2. 源代码

#include<stdio.h>
#define MAXLENGTH 10
int d[MAXLENGTH];
int S[MAXLENGTH][MAXLENGTH];
struct work{
	int hour;
	int number;
};
work t[MAXLENGTH];
void bubble_sort(work a[], int n){
	int i, j;
	work temp;
	for (j = 0; j < n - 1; j++){
		for ( i = 0; i < n-1-j; i++)
		{
			if (a[i].hour<a[i+1].hour)
			{
				temp = a[i];
				a[i] = a[i + 1];
				a[i + 1] = temp;
			}
		}
	}
}
void MultiMachine(work t[], int n, int d[], int m);
int main(){
	int n;
	int m;
	int i;
	printf("请输入待处理的作业个数:");
	scanf("%d", &n);
	printf("请输入作业需要处理的时间:");
	for ( i = 0; i <n; i++)
	{
		scanf("%d", &t[i].hour);
		t[i].number = i + 1;
	}
	bubble_sort(t, n);
	printf("请输入机器的个数:");
	scanf("%d", &m);
	for ( i = 0; i < m; i++)
	{
		d[i] = 0;
	}
	MultiMachine(t, n, d, m);
	getchar();
	getchar();
	getchar();
}

void MultiMachine(work t[], int n, int d[], int m){
	int rear[MAXLENGTH];
	int i, j, k;
	for ( i = 0; i < m; i++)
	{
		S[i][0] = t[i].number;
		rear[i] = 0;
		d[i] = t[i].hour;
	}
	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].number;
		d[j] += t[i].hour;
	}
	for ( i = 0; i < m; i++)
	{
		printf("机器%d处理:", i + 1);
		for ( j = 0; S[i][j]>0; j++)
		{
			printf("作业%d\t", S[i][j]);
		}
		printf("处理时间:%d\n",d[i]);
		printf("\n");
	}
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值