第五章【回溯法】批处理作业调度问题

 http://blog.csdn.net/yuanyu5237/article/details/6595305

给定n个作业的集合J=(J1,J2,...,Jn)。每一个作业Ji都有两项任务分别在2台机器上完成。每个作业必须先由机器1处理,然后再由机器2处理。作业Ji需要机器j的处理时间为tji;i=1,2,...n;j=1,2。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。则所有作业在机器2上完成处理的时间和f=F21+F21+...+F2n成为该作业调度的完成时间和。

批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最小。

分析:批处理作业调度问题要从n个作业的所有排列中找出最小完成时间和的作业调度,所以批处理作业调度的解空间是一颗排列树。按照回溯法搜索排列树的算法框架,设开始时x=[1,2,...,n]是所给的n个作业,则相应的排列树由x[1:n]的所有排列构成。

递归回溯

[cpp]  view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class Flowshop;  
  5. int Flow(int **,intint []);  
  6.   
  7. void Swap(int &a, int &b)  
  8. {  
  9.     int temp=a;  
  10.     a=b;  
  11.     b=temp;  
  12. }  
  13.   
  14. class Flowshop  
  15. {  
  16.     friend int Flow(int **,intint []);  
  17. private:  
  18.     void Backtrack(int i);  
  19.     int **M,        //各作业所需的处理时间  
  20.         *x,         //当前作业调度  
  21.         *bestx,     //当前最优作业调度  
  22.         *f2,        //机器2完成处理的时间  
  23.         f1,         //机器1完成处理的时间  
  24.         f,          //完成时间和  
  25.         bestf,      //当前最优值  
  26.         n;          //作业数  
  27. };  
  28.   
  29. void Flowshop::Backtrack(int i)  
  30. {  
  31.     if(i>n)  
  32.     {//到达叶子结点  
  33.         for(int j=1; j<=n; ++j)  
  34.             bestx[j]=x[j];  
  35.         bestf = f;  
  36.     }else  
  37.         for(int j=i; j<=n; ++j)  // 因为问题的解空间是一颗由x[1:n]的所有排列构成的排列树  
  38.         { // 所以第i次所调度的作业是从序号为i到n的作业中选择一个座位子树分支  
  39.             f1 += M[x[j]][1]; // +第i次所调度的作业在机器1上的处理时间  
  40.             f2[i] = ((f2[i-1]>f1) ? f2[i-1] : f1) + M[x[j]][2];  
  41.             f += f2[i];      //  +第i次所调度的作业在机器2上的处理时间  
  42.             if(f<bestf)  
  43.             {  
  44.                 Swap(x[i], x[j]);  
  45.                 Backtrack(i+1);  
  46.                 Swap(x[i], x[j]);  
  47.             }  
  48.             f1 -= M[x[j]][1]; // -第i次所调度的作业在机器1上的处理时间  
  49.             f -= f2[i];       // -第i次所调度的作业在机器2上的处理时间  
  50.         }  
  51. }  
  52.   
  53. int Flow(int **M, int n, int bestx[])  
  54. {  
  55.     int ub=INT_MAX;  
  56.     Flowshop X;  
  57.     X.x = new int[n+1];  
  58.     X.f2 = new int[n+1];  
  59.     X.M = M;  
  60.     X.n = n;  
  61.     X.bestx = bestx;  
  62.     X.bestf = ub;  
  63.     X.f1 = 0;  
  64.     X.f = 0;  
  65.     for(int i=0; i<=n; i++)  
  66.     {  
  67.         X.f2[i]=0;  
  68.         X.x[i]=i;  
  69.     }  
  70.     X.Backtrack(1);  
  71.     delete [] X.x;  
  72.     delete [] X.f2;  
  73.     return X.bestf;  
  74. }  
  75.   
  76. int main(int argc, char *argv[])  
  77. {  
  78.     int **M = new int*[4];  
  79.     for(int i=0; i<=3; ++i)  
  80.         M[i] = new int[3];  
  81.     M[1][1] = 2; M[1][2]=1;  
  82.     M[2][1] = 3; M[2][2]=1;  
  83.     M[3][1] = 2; M[3][2]=3;  
  84.     int *bestx = new int[4];  
  85.   
  86.     for(int m=1; m<=3; m++)  
  87.     {  
  88.         for(int n=1; n<=2; n++)  
  89.             cout << M[m][n] << " ";  
  90.         cout << endl;  
  91.     }  
  92.   
  93.     cout << Flow(M, 3, bestx) << endl;  
  94.     for(int i=1; i<=3; ++i)  
  95.         cout << bestx[i] << ",";  
  96.   
  97.     cout << "Press the enter key to exit";  
  98.     cin.ignore(cin.rdbuf()->in_avail()+1);  
  99.     return 0;  
  100. }  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值