1、0018算法笔记【动态规划】流水作业调度问题与Johnson法则1、问题描述:n个作业1,2,n要在由2台机器M1和M2组成的流水线上完毕加工。每个作业加工的顺序都是先在M1上加工,然后在M2上加工。M1和M2加工作业i所需的时间分别为ai和bi。流水作业调度问题规定拟定这n个作业的最优加工顺序,使得从第一个作业在机器M1上开始加工,到最后一个作业在机器M2上加工完毕所需的时间最少。2、问题分析直观上,一个最优调度应使机器M1没有空闲时间,且机器M2的空闲时间最少。在一般情况下,机器M2上会有机器空闲和作业积压2种情况。设所有作业的集合为N=1,2,n。S是N的作业子集。在一般情况下,机器M1
2、开始加工S中作业时,机器M2还在加工其他作业,要等时间t后才可运用。将这种情况下完毕S中作业所需的最短时间记为T(S,t)。流水作业调度问题的最优值为T(N,0)。 设是所给n个流水作业的一个最优调度,它所需的加工时间为 a(1)+T。其中T是在机器M2的等待时间为b(1)时,安排作业(2),(n)所需的时间。 记S=N-(1),则有T=T(S,b(1)。 证明:事实上,由T的定义知T=T(S,b(1)。若TT(S,b(1),设是作业集S在机器M2的等待时间为b(1)情况下的一个最优调度。则(1),(2),(n)是N的一个调度,且该调度所需的时间为a(1)+T(S,b(1)a(1)+T。这与是
3、N的最优调度矛盾。故T=T(S,b(1)。从而T=T(S,b(1)。这就证明了流水作业调度问题具有最优子结构的性质。 由流水作业调度问题的最优子结构性质可知:从公式(1)可以看出,该问题类似一个排列问题,求N个作业的最优调度问题,运用其子结构性质,对集合中的每一个作业进行试调度,在所有的试调度中,取其中加工时间最短的作业做为选择方案。将问题规模缩小。公式(2)说明一般情况下,对作业集S进行调度,在M2机器上的等待时间,除了需要等该部件在M1机器上完毕时间,还要抵冲一部分本来的等待时间,假如抵冲已成负值,自然仍需等待M1将作业做完,所以公式取maxt-ai,0。3、动态规划法求解思绪 假设有一组
4、作业需要在M1和M2 两台机器上进行流水作业,他们在M1和M2上的作业时间如下表:问题是如何安排他们的加工顺序,使得,到最后一个作业在机器M2上加工完毕所需要的时间最少。也就是所有作业在两台机器所有加工完毕所需的时间最少。思绪如下:考虑假如只有一个作业的情况,肯定所需时间就是它自身需要在M1和M2 上的加工时间总和;假如有两个作业就要考虑在两种不同的加工顺序下选取最优的一种作为候选,三个作业的时会出现三种组合情况(0,(1,2); (1,(0,2); (2,(0,1),拿第一种为例,它表达先加工作业0,然后再按照作业1和作业2的优化顺序加工;将三种的作业时间计算出来,取最小值,即为三个作业的优
5、化结果,同理可对更多的作业进行排序优化。具体做法是,用类似矩阵连乘的办法,自底向上将所有能的情况计算出来,并产生一个表,供后面的计算查用,减少反复计算的工作量。对于j1 作业M2 的等待时间为b0,事实上在M2加工j0作业的同时,M1 并行加工j1,实际它需要等待b1-a0时间。2+4+(5-4)+2=9从J0和J1两个作业的加工顺序,可以看出,先加工J0后J1,所用时间最短为9,将其填入表中,依此类推,即可得出最优解。a4+a0+a2+a1+a3+(b4+b0+b1+b2)-(a0+a1+a2+a3)+b3 =1+2+3+4+6+(7+5+2+3)-(2+4+3+6)+1 =16+17-15
6、+1=19选其中加工时间短的作为候选方案;在具体计算时非最优子集不必考虑,这样可以减少计算次数。4、流水作业调度的Johnson法则 设兀是作业集S在机器M2的等待时间为t时的任一最优调度。若在这个调度中,安排在最前面的两个作业分别是i 和j ,即(1)=I,(2)=j。则有动态规划递归式可得 其中假如作业i和j满足minbi,aj minbj,ai,则称作业i和j满足Johnson不等式。假如作业i和j 不满足Johnson不等式,则互换作业i和j满足Johnson不等式。 证明 :在作业集S中,对于机器M2 的等待时间为t的调度,互换作业i和j 的加工顺序,得到作业集S 的另一个调度,它所
7、需的加工时间为 当作业i和j 满足Johnson 不等式 minbi,aj minbj,ai时,有从而由此可得因此,对任意t 有从而,tijtji,由此可见,换句话说,当作业i 和j不满足Johnson 不等式时,互换它们的加工顺序后,作业i和j满足Johnson 不等式,且不增长加工时间。由此可知,对于流水作业调度问题,必存在最优调度,使得作业(i)和(i+1)满足Johnson 不等式:这样的调度称为满足Johnson 法则的调度。进一步还可以证明,调度满足Johnson 法则当且仅当对任意ij 有: 由此可知,任意两个满足Johnson 法则的调度具有相同的加工时间,从而所有满足John
8、son 法则的调度均为最优调度。5、流水作业调度问题Johnson算法从上面的分析可知,流水作业调度问题一定存在满足Johnson法则的最优调度,且容易由下面的算法拟定: 流水作业调度问题的Johnson算法: (1)令N1=i|ai=bi;(2)将N1中作业按ai的非减序排序;将N2中作业按bi的非增序排序; (3)N1中作业接N2中作业构成满足Johnson法则的最优调度。 Johnson算法中分类及排序的作用(验证不等式)设数组c为排序后的作业排列,排序结果如下: 红线左侧满足 aci=bci 和 aci=min(bci+1,aci)其调度顺序最优; 红线右侧满足 bci=bci+1 符
9、合johnson 不等式,min(bci,aci+1)=min(bci+1,aci)其调度顺序最优; 中间过渡部分横向比较,左侧aci bci 右侧bci+1=min(bci+1,aci)其调度顺序也最优; 程序具体代码如下:cppview plaincopy1. /3d9动态规划流水作业调度问题2. #includestdafx.h3. #include4. usingnamespacestd;5. 6. constintN=5;7. 8. classJobtype9. 10. public:11. intoperator=(Jobtypea)const12. 13. return(key=
10、a.key);14. 15. intkey,index;16. booljob;17. ;18. 19. intFlowShop(intn,inta,intb,intc);20. voidBubbleSort(Jobtype*d,intn);/本例采用冒泡排序21. 22. intmain()23. 24. inta=2,4,3,6,1;25. intb=5,2,3,1,7;26. intcN;27. 28. intminTime=FlowShop(N,a,b,c);29. 30. cout作业在机器1上的运营时间为:endl;31. for(inti=0;iN;i+)32. 33. cout
11、ai;34. 35. coutendl;36. cout作业在机器2上的运营时间为:endl;37. for(inti=0;iN;i+)38. 39. coutbi;40. 41. coutendl;42. 43. cout完毕作业的最短时间为:minTimeendl;44. cout编号从0开始,作业调度的顺序为:endl;45. for(inti=0;iN;i+)46. 47. coutci;48. 49. coutendl;50. return0;51. 52. 53. intFlowShop(intn,inta,intb,intc)54. 55. Jobtype*d=newJobtyp
12、en;56. for(inti=0;ibi?bi:ai;/按Johnson法则分别取相应的bi或ai值作为关键字59. di.job=ai=bi;/给符合条件aibi的放入到N1子集标记为true60. di.index=i;61. 62. 63. BubbleSort(d,n);/对数组d按关键字升序进行排序64. 65. intj=0,k=n-1;66. 67. for(inti=0;in;i+)68. 69. if(di.job)70. 71. cj+=di.index;/将排过序的数组d,取其中作业序号属于N1的从前面进入72. 73. else74. 75. ck-=di.index
13、;/属于N2的从后面进入,从而实现N1的非减序排序,N2的非增序排序76. 77. 78. 79. j=ac0;80. k=j+bc0;81. for(inti=1;in;i+)82. 83. j+=aci;/M1在执行ci作业的同时,M2在执行ci-1号作业,最短执行时间取决于M1与M2谁后执行完84. k=jk?k+bci:j+bci;/计算最优加工时间85. 86. 87. deleted;88. returnk;89. 90. 91. /冒泡排序92. voidBubbleSort(Jobtype*d,intn)93. 94. inti,j,flag;95. Jobtypetemp;96. 97. for(i=0;ii;j-)100. /假如前一个数大于后一个数,则互换101. if(dj=dj-1)102. temp=dj;103. dj=dj-1;104. dj-1=temp;105. flag=1;106. 107. 108. /假如本次排序没有进行一次互换,则break,减少了执行之间。109. if(flag=0)110. break;111. 112. 113. 运营结果如下: