回溯法--批處理作業排程
阿新 • • 發佈:2018-12-09
http://www.cnblogs.com/xing901022/archive/2012/10/23/2734983.html
問題描述:
給定n個作業,集合J=(J1,J2,J3)。每一個作業Ji都有兩項任務分別在2臺機器上完成。每個作業必須先有機器1處理,然後再由機器2處理。作業Ji需要機器j的處理時間為tji。對於一個確定的作業排程,設Fji是作業i在機器j上完成處理時間。則所有作業在機器2上完成處理時間和f=F2i,稱為該作業排程的完成時間和。
簡單描述:
對於給定的n個作業,指定最佳作業排程方案,使其完成時間和達到最小。
演算法設計:
從n個作業中找出有最小完成時間和的作業排程,所以批處理作業排程問題的解空間是一棵排列樹。
類Flowshop的資料成員記錄解空間的結點資訊,M輸入作業時間,bestf記錄當前最小完成時間和,bestx記錄相應的當前最佳作業排程。
在遞迴函式Backtrack中,
當i>n時,演算法搜尋至葉子結點,得到一個新的作業排程方案。此時演算法適時更新當前最優值和相應的當前最佳排程。
當i<n時,當前擴充套件結點在i-1層,以深度優先方式,遞迴的對相應子樹進行搜尋,對不滿足上界約束的結點,則剪去相應的子樹。
演算法描述:
class Flowshop { friend Flow(int* *,int,int[]); private: void Backtrack(int i); int * * M, * x, * bestx, * f2, f1, f, bestf, n; }; void Flowshop::Backtrack(int i) { if(i>n) { for(int j=1;j<=n;j++) bestx[j] = x[j]; bestf = f; }else { for(int j=i;j<=n;j++) { f1+=M[x[j]][i]; f2=((f2[i-1]>f1)?f2[i-1]:f1)+M[x[j]][2]; f+=f2[i]; if(f<bestf) { Swap(x[i],x[j]); Backtrack(i+1); Swap(x[i],x[j]); } f1 -= M[x[j]][1]; f -= f2[i]; } } } int Flow(int * * M,int n,int bestx[]) { int ub = INT_AMX; Flowshop X; X.x = new int [n+1]; X.f2 = new int [n+1]; X.M = M; X.n = n; X.bestf = ub; X.bestx = bestx; X.f1 = 0; X.f = 0; for(int i=0;i<=n;i++) { X.f2[i] = 0; X.x[i] i; } X.Backtrack(1); delete [] X x; delete [] X f2; return X.bestf; }
例項程式碼:
#include <iostream> using namespace std; #define MAX 200 int* x1;//作業Ji在機器1上的工作時間; int* x2;//作業Ji在機器2上的工作時間; int number=0;//作業的數目; int* xOrder;//作業順序; int* bestOrder;//最優的作業順序; int bestValue=MAX;//最優的時間; int xValue=0;//當前完成用的時間; int f1=0;//機器1完成的處理時間; int* f2;//第i階段機器2完成的時間; void BackTrace(int k) { if (k>number) { for (int i=1;i<=number;i++) { bestOrder[i]=xOrder[i]; } bestValue=xValue; } else { for (int i=k;i<=number;i++) { f1+=x1[xOrder[i]]; f2[k]=(f2[k-1]>f1?f2[k-1]:f1)+x2[xOrder[i]]; xValue+=f2[k]; swap(xOrder[i],xOrder[k]); if (xValue<bestValue) { BackTrace(k+1); } swap(xOrder[i],xOrder[k]); xValue-=f2[k]; f1-=x1[xOrder[i]]; } } } int main() { cout<<"請輸入作業數目:"; cin>>number; x1=new int[number+1]; x2=new int[number+1]; xOrder=new int[number+1]; bestOrder=new int[number+1]; f2=new int[number+1]; x1[0]=0; x2[0]=0; xOrder[0]=0; bestOrder[0]=0; f2[0]=0; cout<<"請輸入每個作業在機器1上所用的時間:"<<endl; for (int i=1;i<=number;i++) { cout<<"第"<<i<<"個作業="; cin>>x1[i]; } cout<<"請輸入每個作業在機器2上所用的時間:"<<endl; for (i=1;i<=number;i++) { cout<<"第"<<i<<"個作業="; cin>>x2[i]; } for (i=1;i<=number;i++) { xOrder[i]=i; } BackTrace(1); cout<<"最節省的時間為:"<<bestValue; cout<<endl; cout<<"對應的方案為:"; for (i=1;i<=number;i++) { cout<<bestOrder[i]<<" "; } return 0; }