1. 程式人生 > >回溯法--批處理作業排程

回溯法--批處理作業排程

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;
}
複製程式碼