贪心选择-多机调度问题

        问题描述:设有 n 个独立的作业[1,2.., n ,由 m 台相同的机器进行加工处理。作业 i所需时间为 T .约定:任何作业可以在任何一台机器上加工处理,但未完工前不允许中断处理,任何作业不能拆分成更小的子作业.要求给出一种作业调度方案,使所给的 n 个作业在尽可能短的时间内由 m 台机器加工处理完成。

        在解决这道问题时,根据我们的日常思维来看,肯定是要分成两种情况的:

        1、当n<=m时,直接进行分配,然后再比较出m台机器中处理任务所需时间最大的就可以了;

        2、当n>m时,为了便于理解,因此,我们来举例子来说明:

     假设我们有8个独立作业,由3台机器加工处理,完成这些独立作业所需要的时间为[16,14,3,5,6,8,3,13,11]。

        (1)、我们先按日常思维来看,将任务平均分配给三台机器,所需要的总时间为33。

机器

作业数

完成时间

M1

1,2,3

33

M2

4,5,6

14

m3

7,8

24

表1-1

        这种方法思路很简单,就是把任务平均分配一下,最后看那个机器用的时间最长。但是这种算法忽略了一个问题,那就是没有考虑到时间的节省,只是单纯的按照任务次序进行的,导致时间相差较大。如果我们假设所需完成时间最长的集中在1,2,3这三个任务里其他的顺序表不变,[16,14,13,3,5,6,8,11]:

 

机器

作业数

完成时间

M1

1,2,3

43

M2

4,5,6

14

M3

7,8

19

表1-2

        那根据我们给的例子便会发现M1需要的时间为43,多么令人震惊的时长,而其他的两台机器如M3需要的时间为19,而M2就更夸张了,只需要14,这就好比有三只羊,其他两只就薅一点羊毛,就逮着一只羊使劲而薅,这羊毛不早晚被薅完吗。同样的,机器要考虑磨损效率等问题,那坑定不能只指着一个机器玩儿命工作,因此,我们需要更为效率高的算法。

        (2)、既然第一种方法效率太差,没有考虑到时间节省的问题,那我们就应该考虑如何将机器运用更充分,这一次我们同样的运用上面的例子:[16,14,3,5,6,8,3,13,11],这一次我们就考虑从(时间最长的任务+时间最短的任务+时间次短的任务)这一角度出发:

机器

作业数

完成时间

M1

1,2,3

24

M2

6,4,5

28

M3

7,8

25

表2-1

        现在我们发现,当我们从(时间最长的任务+时间最短的任务+时间次短的任务)这一角度出发时,完成所有任务所需要的随短时间为28,要比第一种方法所需要的时间更短,但同时我们小组也发现三台机器之间相差的时间趋势是缩短了的,这就表明我们的想法大方向是对的,因为三台机器都在充分的开始调用起来,但同时,我们小组发现在M1和M3完成任务后,M2仍然需要接着工作4,其他两台机器仍需要等待很长时间,这要是在工作中,这样安排会使其他员工也跟着一起等待才能开始下一个任务,大大的影响了公司的工作进度。因此, 我们小组继续探讨并上网查询,学习到了这样一种算法:“贪心算法”。

        (3)那么什么是贪心算法呢:所谓贪心算法就是“贪心选择和最优子结构”,贪心选择就是通过局部最优解来达到整体最优解,最优子结构就是一个问题的最优解包含其子问题的最优解,贪心算法通俗点将就是只顾当前的利益,不考虑以后的问题。

        而对于这道题来说,为了使完成所有任务的时间最短,我们肯定要优先安排所需时间最长的任务进行安排,即把所需完成时间的任务按照从大到小进行排序,然后先把完成时间较长的m个任务分配给m台机器,接着将剩下的任务中所需时间最长的任务安排给m个机器中最先空闲的机器,以此类推,最后通过比较m台机器中处理时间最长的机器,它的处理时间就是m台机器中处理时间最短的时间。我们还是举一开始的例子[16,14,3,5,6,8,3,13,11],因为要先选出所需时间最长的任务,我们先按时间排序[16,14,13,11,8,6,5,3],还是3台机器,我们选出时间最长的三个任务[16,14,13]将它们分给三个机器:

机器1:16

机器2:14

机器3:13

        然后将剩下的任务中时间最短的分配给最先结束的机器:

机器1:16

机器2:14

机器3:13,11

以此类推:

机器1:16,6

机器2:14,8

机器3:13,11

        此时应该注意最先完成的机器是完成两个任务的时间和,应该将剩下的任务[4,2]中的4分配给机器2:

机器1:16,6,3   --------------  25

机器2:14,8,5   --------------  27

机器3:13,11       --------------  24

此时最短的时间为27,27<28<33,为三种方法中耗时最短的。

#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#define x 10 
#define y 10 
#define N 5
#define M 3
int d[x];
int c[x];
int S[x][y];
struct work{
 int hour;
 int number;
};
work t[x];
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 m=M,n=N,j;
	printf("请输入作业需要处理的时间:");
	srand((unsigned)time(NULL));
	work t[x];
	for(int i=0;i<N;i++)
	{
		t[i].number=i+1;
		t[i].hour=rand()%50+1;
		printf("%d号作业需要%d分钟\n",t[i].number,t[i].hour);
	}
	bubble_sort(t, n);
	for(j=0;j<m;j++)
	{
		d[j]=t[j].hour;
	}
	MultiMachine(t, n, d, m);
}
void MultiMachine(work t[], int n, int d[], int m){
	int rear[x];
	int i, j, k,max;
	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");

 }
	for(i=0;i<m;i++){
	printf("%d",d[i]);
	printf("\n");
	max=d[0];
	if(d[i]>=max){
	max=d[i];
	}
 }
	printf("最短完工需要%d",max);
	
}

 

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值