流水作业调度问题

问题描述

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

基本思路

  1. 将每个作业按照加工时间分组
    对于作业i,若a[i]<=b[i],则分到N1组。若a[i]>b[i],则分到N2组。
  2. 进行加工排序
    所有N1组(a[i]<=b[i])的作业都在N2组之前加工,对于N1组(a[i]>b[i])的作业,按照b[i] (在M2上加工时间)升序排列。对于N2组的作业,按照a[i] (在M1上加工时间)降序排列。排列完成即得到加工顺序

示例

在这里插入图片描述
N1按b[i]升叙排列:0、5、1、3
N2按a[i]降叙排列:2、4
最优加工顺序:0、5、1、3、2、4

代码

如果想要了解编程思路,好好看注释

//3d9 动态规划 流水作业调度问题
#include <iostream> 
using namespace std; 
 
const int N = 6;
 
class Jobtype
{
	public:
		int key;//key记录a[i]、b[i]的较大者
		int index;//作业的编号
		bool job;//作业的分组 
};
 
int FlowShop(int n,int a[],int b[],int c[]);
void BubbleSort(Jobtype *d,int n);
 
int main()
{
	int a[] = {2,5,7,10,5,2};
	int b[] = {3,8,4,11,3,4};
	int c[N];//c[]记录加工顺序 
 
	int minTime =  FlowShop(N,a,b,c);
 
	cout<<"作业在机器1上的运行时间为:"<<endl;
	for(int i=0; i<N; i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	cout<<"作业在机器2上的运行时间为:"<<endl;
	for(int i=0; i<N; i++)
	{
		cout<<b[i]<<" ";
	}
	cout<<endl;
 
	cout<<"完成作业的最短时间为:"<<minTime<<endl;
	cout<<"编号从0开始,作业调度的顺序为:"<<endl;
	for(int i=0; i<N; i++)
	{
		cout<<c[i]<<" ";
	}
	cout<<endl;
	return 0;
}
 
int FlowShop(int n,int a[],int b[],int c[])
{
	Jobtype *d = new Jobtype[n];//总共有n个作业 
	for(int i=0; i<n; i++)
	{
		d[i].key = a[i]>b[i]?b[i]:a[i];//按Johnson法则分别取对应的b[i]或a[i]值作为关键字,关键字是记录加工顺序的标准 
		d[i].job = a[i]<=b[i];//分组,给符合条件a[i]<=b[i]的放入到N1子集标记为true
		d[i].index = i; 
	}
 
	BubbleSort(d,n);//对数组d按关键字升序进行排序
 
	int j = 0,k = n-1;
 
/*
	如果作业分在N1集合中(说明a[i]<=b[i]),按b[i]进行升序排列
	如果作业分在N2集合中(说明a[i]>b[i]),按a[i]进行降序排列
*/
	for(int i=0; i<n; i++)
	{
		if(d[i].job)//c[]记录加工顺序 
		{
			c[j++] = d[i].index;//将排过序的数组d,取其中作业序号属于N1的从前面进入
		}
		else
		{
			c[k--] = d[i].index;//属于N2的从后面进入,从而实现N1的非减序排序,N2的非增序排序
		}
	}

//下面构造最优值(最短加工时间) 
	j = a[c[0]];
	k = j+b[c[0]];
	for(int i=1; i<n; i++)
	{
		j += a[c[i]];
		k = j<k?k+b[c[i]]:j+b[c[i]];
	/*
M1在执行c[i]作业的同时,M2在执行c[i-1]号作业,最短执行时间取决于M1与M2谁后执行完。
只有M1将第i个作业加工完且M2将第i-1个作业加工完,M2才能加工第i个作业。
 所以k取j和k中的较大者+第i个做的在M2上的加工时间
	*/
	}
	delete d;
	return k;
}
 
/*
按关键字key升序排列
在N1集合(a[i]<=b[i])中,key=b[i]
在N2集合(a[i]>b[i])中,key=a[i]
*/
void BubbleSort(Jobtype *d,int n)
{
	int i,j,flag; 
	Jobtype temp;
	for(i=0;i<n;i++)
	{  
		flag = 0;  
		for(j=0;j<n-i;j++)
		{  
			//如果前一个数大于后一个数,则交换  
			if(d[j].key>=d[j+1].key)
			{   
				temp = d[j];  
				d[j] = d[j+1];  
				d[j+1] = temp;  
				flag = 1;  
			}  
		}  
		//如果本次循环没有进行一次交换,则break,减少了执行时间。  
		if(flag == 0){  
			break;  
		}  
	}
}

运行结果
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bugcoder-9905

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

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

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

打赏作者

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

抵扣说明:

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

余额充值