算法分析 | 回溯法 | 最佳加工顺序

一.问题分析

1.问题描述:

有n个机器零件,每个零件必须先由机器A处理,再由机器B处理。零件Pi需要机器1,2处理时间为P[i].Atime,P[i].Btime

如何安排零件加工顺序,使第一个零件从机器1上加工开始到最后一个零件在机器2上加工完成,所需的总加工时间最短?

 

2.A机可以连续不间断开动,B机第i个零件的加工完成时间为:

B_end_time[ i ]=max(B_end_time[ i - 1 ] , A_end_time[ i ]) + P[ i ].Btime

取决于B机处理完前一个零件A机处理完本零件的最晚时间

 

3.排列树的概念

回忆递归算法中数组全排列的内容:

a[N]的全排列 = for(0..N-1)将每个元素swap到a[0]一次 + a[N-1]的全排列

在解空间中,每递归深入一层,分支数-1 ,到叶结点时,解的数量=N*(N-1)*(N-2)*(N-3).......=N!

 

4.约束与限界函数

①约束函数禁止 "根本就不可能出现的情况"  ,本题中每一种排列方式都可以出现,所以没有约束函数

②限界函数禁止 "会出现但没必要再扩展的情况". 当目前的B_end_time小于已知的最优解bestn2时,可以试着进行递归

因此,最优解bestn2初始值=INT_MAX

 

二.代码实现

分为三个区:全局变量区/递归函数/调用递归函数的函数

//BPS is short of "Best Process Sequence"  最佳加工顺序 
//找出零件P[n]的一个最佳加工顺序  ,复习数组的全排列问题
//机器A的加工是可以连续不间断的
//机器B,第i个零件的开始加工时间=max(B[ i - 1 ] , A[ i ]) +Btime[ i ]
//将最后的B_end_time赋给bestn2.


struct product
{
	int Atime;	//记录A机器的加工时间
	int Btime; //记录B机器的加工时间
};
vector<product>P = {{5,7},{1,2},{8,2},{5,4},{3,7},{4,4}};
auto M2 = P.size();

int bestn2 = INT_MAX;				 //记录一次递归结束后的最优值
vector<int> bestx2(M2, 0);		//记录一次递归结束后的最优策略
vector<int> cx2(M2, 0);				//记录当前策略

int A_end_time;								//记录当前A机器的完成时间
int B_end_time;								//记录当前B机器(总体)的完成时间


void BPSbacktrack(int t)//t表示子问题的首位,首次递归时t=0
{
	if (t >= M2)		//说明遍历完0~M1-1个,此时可以记录一个最终最优值,并退出当前递归
	{
		bestx2 = cx2;
		bestn2 = B_end_time;
		return;
	}
	//每一种加工顺序都能得到解,不存在约束条件,只有限界条件
	for (int i = t; i < M2; i++)		//第一层循环M2次,之后每层--1;
	{
		A_end_time += P[cx2[i]].Atime;
		int temp = B_end_time;
		B_end_time = max(A_end_time, B_end_time) + P[cx2[i]].Btime;

		if (B_end_time < bestn2)			//限界条件
		{
			swap(cx2[i],cx2[t]);
			BPSbacktrack(t + 1);
			swap(cx2[i], cx2[t]);    //最优策略的回溯
		}
		                                //最优值的回溯
		A_end_time-= P[cx2[i]].Atime;		
		B_end_time = temp;
	}
}


void BPS()
{
	//初始化
	for (int i = 0; i < M2; i++)
	{
		cx2[i] = i;
	}
	A_end_time = 0;								//记录当前A机器的完成时间
	B_end_time = 0;

	BPSbacktrack(0);

	cout << "最优加工顺序:		";
	for (int i = 0; i < M2; i++)
	{
		cout << bestx2[i] << "	";
	}cout << endl;
	cout << "最短加工时间:		" << bestn2;
}
 

 

posted @ 2020-02-15 22:01  心碎人俱乐部  阅读(79)  评论(0)    收藏  举报