当前位置:文档之家› 独立任务最优调度

独立任务最优调度

参考资料1——独立任务最优调度问题:独立任务最优调度,又称双机调度问题:用两台处理机A和B处理n个作业。

设第i个作业交给机器A处理时所需要的时间是a[i],若由机器B来处理,则所需要的时间是b[i]。

现在要求每个作业只能由一台机器处理,每台机器都不能同时处理两个作业。

设计一个动态规划算法,使得这两台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总的时间)。

研究一个实例:n=6a = {2, 5, 7, 10, 5, 2};b = {3, 8, 4, 11, 3, 4}.分析:当完成k个作业,设机器A花费了x时间,机器B所花费时间的最小值肯定是x的一个函数,设F[k][x]表示机器B所花费时间的最小值(注意,这是B 机器所花费的时间,即当B机器停机时的时间点)。

则有F[k][x]=Min{ F[k-1][x]+b[k], F[k-1][x-a[k]] };其中,F[k-1][x]+b[k]表示第k个作业由机器B来处理(完成k-1个作业时机器A 花费的时间仍是x,前提就是A机器停机的时间是x),F[k-1][x-a[k]]表示第k个作业由机器A处理(完成k-1个作业时机器A花费的时间是x-a[k])。

那么x(表示A机器的停机时间)、F[k][x](表示B机器的停机时间)两者取最晚停机的时间,也就是两者中最大的时间,是在AB在此时间中完成k任务最终的时间:Max(x, F[k][x])。

而机器A花费的时间x在此期间是一个变量,其取值可以是即x=0,1,2……x(max),(理论上x的取值是离散的,但为编程方便,设为整数连续的)由此构成了点对较大值序列。

要求整体时间最短,取这些点对较大值序列中最小的即是。

理解难点在于B是A的函数表达式,也即动态规划所在。

花点时间,看懂表达式,加上思考,理解了这点一切OK,后面的编程实现完全依据这个思想。

先用前两个任务的枚举示例来帮助理解。

示例:前两个作业示例足矣。

初始化第一个作业:下标以0开始。

首先,机器A所花费时间的所有可能值范围:0 <= x <= a[0].设x<0时,设F[0][x]= ∞,则max(x, ∞)= ∞;记法意义见下。

x=0时,F[0][0]=3,则Max(0,3)=3,机器A花费0时间,机器B花费3时间,而此时两个机器所需时间为3;x=1时,F[0][1]=3,Max(1,3)=3;x=2时,F[0][2]=0,则Max(2,0)=2;那么上面的点对序列中,可以看出当x=2时,完成第一个作业两台机器花费最少的时间为2,此时机器A花费2时间,机器B花费0时间。

来看第二个作业:首先,x的取值范围是:0 <= x <= (a[0] + a[1]).当x<0时,记F[1][x] = ∞;这个记法编程使用,因为数组下标不能小于0。

在这里的实际含义是:x是代表完成前两个作业机器A的时间,a[1]是机器A完成第2个作业的时间,若x<a[1],则势必第2个作业由机器B来处理,即在Min()中取前者。

x=0,则F[1][0]= Min{ F[0][0]+b[2], F[0][0-a[1]] }= Min{3+8,∞}=11,进而Max(0,11)=11;x=1,则F[1][1]= Min{ F[0][1]+b[2], F[0][1-a[1]] }= Min{3+8,∞}=11,进而Max(11)=11;x=2,则F[1][2]= Min{ F[0][2]+b[2], F[0][2-a[1]] }= Min{0+8,∞}=8,进而Max(2,8)=8;x=3,则F[1][3]= Min{ F[0][3]+b[2], F[0][3-a[1]] }= Min{0+8,∞}=8,进而Max(3,8)=8;x=4,则F[1][4]= Min{ F[0][4]+b[2], F[0][4-a[1]] }= Min{0+8,∞}=8,进而Max(4,8)=8;x=5,则F[1][5]= Min{ F[0][5]+b[2], F[0][5-a[1]] }= Min{0+8,3}=3,进而Max(5,3)=5;x=6,则F[1][6]= Min{ F[0][6]+b[2], F[0][6-a[1]] }= Min{0+8,3}=3,进而Max(6,3)=6;x=7,则F[1][7]= Min{ F[0][7]+b[2], F[0][7-a[1]] }= Min{0+8,0}=0,进而Max(7,0)=7;那么上面的点对序列中,可以看出当x=5时,完成两个作业两台机器花费最少的时间为5,此时机器A花费5时间,机器B花费3时间。

程序代码如下:[csharp]view plaincopyprint?1.<span style="font-size: 16px;">using System;space zydd3.{4.class Program5.{6.//独立任务最优调度函数,参数为两组任务和任务个数,最优时间和顺序结果。

7.static void DlrwZydd(int[] a, int[] b, int n, int[] least, string[] result)8.{9.//首先给一个大值。

10.f or (int i = 0; i < n; i++)11.{12.l east[i] = 99;13.}14.15.//若任务只有一台机器完成,求得两个时间。

16.i nt aSum = 0, bSum = 0;17.f or (int i = 0; i < n; i++)18.{19.a Sum += a[i];20.b Sum += b[i];21.}22.//小值加1作为数组的列数,减少存储空间。

23.i nt Sum = 1 + Math.Min(aSum, bSum);24.25.//创建四个行数列数相同的数组,timeA存储机器A可能用的时间,timeB存储对应机器B用的时间,26.//timeMax记录两者共需的时间,即较大的那个;who则标识完成该任务的机器是A还是B。

27.i nt[,] timeA = new int[n, Sum];28.i nt[,] timeB = new int[n, Sum];29.i nt[,] timeMax = new int[n, Sum];30.c har[,] who = new char[n, Sum];31.c har[] tempRlt = new char[n];//tempRlt记录机器完成任务的机器顺序,并逐一赋值给result32.33.34.//先计算第1个任务相关值,记录在四个数组的第0行。

35.f or (int i = 0; i <= a[0]; i++)36.{37.t imeA[0, i] = i;38.i f (i < a[0])39.{40.t imeB[0, i] = b[0];41.w ho[0, i] = 'b';42.}43.e lse44.{45.t imeB[0, i] = 0;46.w ho[0, i] = 'a';47.}48.t imeMax[0, i] = Math.Max(timeA[0, i], timeB[0, i]);49.}50.51.//尽管像下面一样,直接比较即可得出完成第1项任务的最优时间,但由于使用动态规划,计算上述值是必需的。

52.i f (a[0] <= b[0])53.{54.l east[0] = a[0];55.t empRlt[0] = 'a';56.}57.e lse58.{59.l east[0] = b[0];60.t empRlt[0] = 'b';61.}62.r esult[0] = new String(tempRlt);63.64.//计算第2个至第n个任务,分别记录在四个数组相应行。

65.f or (int k = 1; k < n; k++)66.{67.68.//tempSum记录完成前k项任务机器A最多需要的时间,即全部由A完成需要的时间,亦即机器A所有可能的取值范围。

69.i nt tempSum = 0;70.f or (int temp = 0; temp <= k; temp++)71.{72.t empSum += a[temp];73.}74.//计算出所有可能的点对(timeA,timeB),并取值timeMax。

75.f or (int i = 0; i <= tempSum; i++)76.{77.//机器A在完成前k项任务时所花费的时间为i。

78.t imeA[k, i] = i;79.80.//i即timeA[k, i],若机器A完成前k项任务的时间小于它完成第k项的时间,可能吗?不可能,所以第k项任务肯定由机器B做。

81.i f (i < a[k])82.{83.t imeB[k, i] = timeB[k - 1, i] + b[k];84.w ho[k, i] = 'b';85.}86.//按照前述动态规划方式的思想,确定机器A在花费i时间时,机器B花费的最优时间。

87.e lse88.{89.i f ((timeB[k - 1, i] + b[k]) <= timeB[k - 1, i - a[k]])90.{91.t imeB[k, i] = timeB[k - 1, i] + b[k];92.w ho[k, i] = 'b';93.}94.e lse95.{96.t imeB[k, i] = timeB[k - 1, i - a[k]];97.w ho[k, i] = 'a';98.}99.}100.//两台机器花费时间较大的那个为总花费时间。

101.timeMax[k, i] = Math.Max(timeA[k, i], timeB[k, i]);102.}103.104.//处理数组tempSum后面的值。

机器A时间全部设为最大,此时机器B则无需花费时间。

105.for (int i = tempSum + 1; i < aSum; i++)106.{107.timeA[k, i] = tempSum;108.timeB[k, i] = 0;109.}110.111.//完成第k项任务后,在timeMax所有可能值中,选取最小值即最优值。

112.int flag = 0;//记录最优值所在的位置i值,同时也是机器A所花费的时间。

相关主题