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

一.問題分析

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;
}
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章