批處理作業調度-回溯法


問題描述:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM