问题描述:设有 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);
}