回溯法之流水作业调度问题

1.问题:流水作业调度问题:每一个作业Ji都有两项任务分别在2台机器上完成。每个作业必须先有机器1处理,然后再由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理时间。则所有作业在机器2上完成处理时间和f=F2i,称为该作业调度的完成时间和。

作业编号

1

2

3

4

M1

5

12

4

8

M2

6

2

14

7

2.设计思路:每一个作业需要先在M1(机器1)上进行求解,M1上的时间是连续的,也就是每一个作业在M1上的执行不需要等待;而作业在M2(机器2)上的执行时间需要判断是否进行等待:如果作业j在M1上的执行时间<作业i在M2上的执行时间,也就是说作业j在M1上执行完成了,而作业i还在使用M2,此时需要等待;否则直接在M2上执行作业j,Max(f1,f2[i])+b[x[i]];其中f1是当前作业在M1上的执行时间,f2数组是作业在M2上的执行时间,所有的时间都是包括前面作业的执行时间,数组a是作业在M1上的执行时间,数组b是作业在M2上的执行时间,如上图;每遍历完一个解空间就要回溯,也就是撤销对当前作业的选择,以便再选择其他作业:

 3.代码;

/*回溯法之流水作业调度问题*/
#include <stdio.h>
#include <string.h>
#define MAX 1000
#define max(x,y) ((x)>(y)? (x):(y))		//自定义max函数,求解x,y中的最大值
int n=4;								//作业数
int a[MAX]={0,5,12,4,8} ;				//作业在M1上的执行时间,从数组下标1开始
int b[MAX]={0,6,2,14,7} ;				//作业在M2上的执行时间,从数组下标1开始
int bestf;								//存放最优的调度时间
int f1;
int f2[MAX];
int x[MAX];								//当前的调度方案 
int bestx[MAX];							//存放当前作业的最优调度方案 
void swap(int &x,int &y)				//交换x,y
{
	int temp=x;
	x=y;
	y=temp;
 }
void dfs(int i)						//从第i层开始使用深度优先遍历
{
	if(i>n)							//达到叶子节点,产生一种调度方案 
	{
		if(f2[n]<bestf)
		{
			bestf=f2[n];
			for(int j=1;j<=n;j++)
			{
				bestx[j]=x[j];
			}
		 } 
	 }
	else{
		for(int j=i;j<=n;j++)			//未达到叶子节点,考虑其他方案 
		{
			swap(x[i],x[j]);
			f1+=a[x[i]];				//在第i层选择执行作业x[i],在M1上的执行时间 
			f2[i]=max(f1,f2[i-1])+b[x[i]]; 
			if(f2[i]<bestf)
			{
				dfs(i+1);				//仅仅扩展调度时间小于bestf(最优调度时间)的节点 
			 } 
			f1-=a[x[i]];				//回溯,撤销对作业x[i]的选择,重新考虑其他作业
			swap(x[i],x[j]); 
		}
	} 
 } 
int main()
{
	f1=0;
	bestf=0x3f3f3f3f;					//初始时的作业最优调度时间为无穷大
	memset(f2,0,sizeof(f1));			//初始f2数组中的执行时间为0
	for(int k=1;k<=n;k++)				//初始时作业的执行顺序:1,2、、、n 
	{
		x[k]=k;
	 } 
	dfs(1);								//从作业1开始调度
	printf("最优调度时间为:%d,\n最优调度方案为:",bestf);
	for(int j=1;j<=n;j++)
	{
		printf("%d ",bestx[j]);
	 }
	printf("\n");
	return 0;
}

4.运行结果:

 

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值