流水作业调度 johnson法则

问题描述:

       N个作业{1,2,………,n}要在由两台机器M1和M2组成的流水线上完成加工。每个作业加工的顺序都是先在M1上加工,然后在M2上加工。M1和M2加工作业i所需的时间分别为ai和bi,1≤i≤n。
流水作业高度问题要求确定这n个作业的最优加工顺序,使得从第一个作业在机器M1上开始加工,到最后一个作业在机器M2上加工完成所需的时间最少。


算法分析:

M1作业是连续作业的主要是看M2 ,M2要么空闲,要么作业积压。

因此得到一个贪心的性质:让(a,b)中a比较小的尽可能先执行,(a,b)中b比较小的尽可能后执行!

Johnson贪心算法,步骤如下:

    

   (1)将所有作业按M1,M2的时间分为两组,a[i]<=b[i]的为N1,a[i]>=b[i]为N2

    (2)N1按a[n]的递增排序,N2的作业按b[n]的递减排序

  

     (3)按顺序先执行N1 ,再执行N2 的作业,得到的就是耗时最少的最优调度。

 

代码展示:

#include <iostream>
#include <algorithm>//用于下面的排序函数sort()库函数的调用
using namespace std;
class JOB
{
public:
 int key,index;
 bool job;
};
int cmp(JOB a,JOB b)
{
 return a.key<b.key;
}
//算法的最主要的部分
int fun(int n,int a[],int b[],int c[])
{
 int i,j,k;
 JOB *d =new JOB[n];//开辟一个空间大小为n的JOB,即有n个的JOB对象
 for(i=0;i<n;i++)
 {
  if(a[i]<b[i])
   {
    d[i].key = a[i];
    d[i].job = true;
   }
  else
   {
    d[i].key = b[i];
    d[i].job = false;
  }
 d[i].index = i;
 }
sort(d,n+d,cmp);//对n个对象按key的大小进行排序
j=0;
k=n-1;
//下面的for()对上面对key进行排好的序再按job为真的key升排序,job
//为假降序排列,分别将它们的最先排的次序存到c[]数组中。
for(i=0;i<n;i++)
 {
 if(d[i].job == true)c[j++]=d[i].index ;
 else c[k--]=d[i].index ;
 }
j=a[c[0]];
k=j+b[c[0]];
//下面这个for()就是将最短的时间输出
for(i=1;i<n;i++)
{
  j=j+a[c[i]];
  k= j<k ? k+b[c[i]] : j+b[c[i]];
 //前一个作业的时间与前一个作业的第一个时间和第二个作业的时间相
  //比,k为那个较大的
 }
 delete d;
 return k;
}
//如下是主函数主要是用例的输入和函数调用
int main()
{
 int i,m,n,a[100],b[100],c[100];
cin>>m;
while(m--)
{
 cin>>n;
 for(i=0;i<n;i++)cin>>a[i]>>b[i];
 cout<<fun(n,a,b,c)<<endl;
 }
 return 0;
}
 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@居安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值