算法设计与分析——回溯法——批处理作业调度

我就是我 2023-01-20 11:49 120阅读 0赞

问题描述:给定n个作业的集合{J1,J2,…,Jn}。每个作业必须先由机器1处理,然后由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。所有作业在机器2上完成处理的时间和称为该作业调度的完成时间和。

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

在这里插入图片描述

这3个作业的6种可能的调度方案是1,2,3;1,3,2;2,1,3;2,3,1;3,1,2;3,2,1;它们所相应的完成时间和分别是19,18,20,21,19,19。易见,最佳调度方案是1,3,2,其完成时间和为18。

以1,2,3为例:
作业1在机器1上完成的时间为2,在机器2上完成的时间为3
作业2在机器1上完成的时间为5,在机器2上完成的时间为6
作业3在机器1上完成的时间为7,在机器2上完成的时间为10
3+6+10=19,所以时间和为19。

以1,3,2为例:
作业1在机器1上完成的时间为2,在机器2上完成的时间为3
作业3在机器1上完成的时间为4,在机器2上完成的时间为7
作业2在机器1上完成的时间为7,在机器2上完成的时间为8
3+7+8=18,所以时间和为18。

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

算法分析:
在这里插入图片描述

在这里插入图片描述

  1. #include<iostream>
  2. #include<stdlib.h>
  3. using namespace std;
  4. class Flowshop
  5. {
  6. public:
  7. int **M;//各作业需要的处理时间
  8. int *x;//当前作业调度
  9. int *bestx;//当前最优作业调度
  10. int *f2;//机器2完成处理时间
  11. int f1;//机器1完成处理时间
  12. int f;//完成时间和
  13. int bestf;//当前最优值
  14. int n;//作业数量
  15. void Backtrack(int i);//回溯算法
  16. };
  17. void Flowshop::Backtrack(int i)
  18. {
  19. if(i>n)
  20. {
  21. for(int i=1;i<=n;i++)//记录路径
  22. {
  23. bestx[i]=x[i];
  24. }
  25. bestf = f;//因为到了叶子结点了,不需要判断了
  26. }
  27. else
  28. {
  29. for(int j=i;j<=n;j++)//分枝数
  30. {
  31. //设置作业在机器1完成的时间
  32. f1 +=M[x[j]][1];//回溯算法的关键
  33. f2[i]=((f2[i-1]>f1)? f2[i-1]:f1) +M[x[j]][2];
  34. f+=f2[i];//回溯算法的关键
  35. if(f<bestf)
  36. {
  37. swap(x[i],x[j]);
  38. Backtrack(i+1);
  39. swap(x[i],x[j]);
  40. }
  41. f1 -=M[x[j]][1];//回溯算法的关键
  42. f -=f2[i];//回溯算法的关键
  43. }
  44. }
  45. }
  46. int Flow(int **M,int n,int bestx[])//初始化
  47. {
  48. int ub = INT_MAX;
  49. Flowshop X;
  50. X.x = new int [n+1];
  51. X.f2 = new int [n+1];
  52. X.M=M;
  53. X.n=n;
  54. X.bestx=bestx;
  55. X.bestf = ub;
  56. X.f1 = 0;
  57. X.f = 0;
  58. for(int i=0;i<=n;i++)
  59. {
  60. X.f2[i]=0,X.x[i]=i;
  61. }
  62. X.Backtrack(1);
  63. delete[] X.x;
  64. delete[] X.f2;
  65. return X.bestf;
  66. }
  67. int main()
  68. {
  69. int n;
  70. cout<<"请输入要处理作业的数量:";
  71. cin>>n;
  72. int bestx[n+1];
  73. int **M =new int *[n+1];
  74. for(int i=0;i<n+1;i++)
  75. {
  76. M[i]= new int [3];
  77. }
  78. cout<<"请输入每个作业在两个机器上工作的处理时间序列:(如1 2):"<<endl;
  79. for(int i=1;i<=n;i++)
  80. {
  81. cin>>M[i][1]>>M[i][2];
  82. }
  83. cout<<"所有作业在机器2上的完成时间和(该作业调度的完成时间)为:"<<Flow(M,n,bestx);
  84. }

在这里插入图片描述
算法的时间复杂度为O(n!)

发表评论

表情:
评论列表 (有 0 条评论,120人围观)

还没有评论,来说两句吧...

相关阅读