分支限界法-批处理调度问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【分支限界法】批处理作业调度问题
问题描述
给定n个作业的集合{J1,J2,…,Jn}。每个作业必须先由机器1处理,然后由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。所有作业在机器2上完成处理的时间和称为该作业调度的完成时间和。
批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最小。
例:设n=3,考虑以下实例:
这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。
限界函数
批处理作业调度问题要从n个作业的所有排列中找出具有最小完成时间和的作业调度,所以如图,批处理作业调度问题的解空间是一颗排列树。
在作业调度问相应的排列空间树中,每一个节点E都对应于一个已安排的作业集。以该节点为根的子树中所含叶节点的完成时间和可表示为:
设|M|=r,且L是以节点E为根的子树中的叶节点,相应的作业调度为{pk,k=1,2,……n},其中pk是第k个安排的作业。如果从节点E到叶节点L的路上,每一个作业pk在机器1上完成处理后都能立
即在机器2上开始处理,即从p r+1开始,机器1没有空闲时间,则对于该叶节点L有:
注:(n-k+1)t1pk,因为是完成时间和,所以,后续的(n-k+1)个作业完成时间和都得算上t1pk。
如果不能做到上面这一点,则s1只会增加,从而有:
。
类似地,如果从节点E开始到节点L的路上,从作业p r+1开始,机器2没有空闲时间,则:
同理可知,s2是的下界。由此得到在节点E处相应子树中叶节点完成时间和的下界是:
注意到如果选择Pk,使t1pk在k>=r+1时依非减序排列,S1则取得极小值。同理如果选择Pk使t2pk依非减序排列,则S2取得极小值。
这可以作为优先队列式分支限界法中的限界函数。
算法描述
算法中用最小堆表示活节点优先队列。最小堆中元素类型是MinHeapNode。每一个MinHeapNode类型的节点包含域x,用来表示节点所相应的作业调度。s表示该作业已安排的作业时x[1:s]。f1表示当前已安排的作业在机器1上的最后完成时间;f2表示当前已安排作业在机器2上的完成时间;sf2表示当前已安排的作业在机器2上的完成时间和;bb表示当前完成时间和下界。二维数组M表示所给的n个作业在机器1和机器2所需的处理时间。在类Flowshop中用二维数组b 存储排好序的作业处理时间。数组a表示数组M和b的对应关系。算法Sort实现对各作业在机器1和2上所需时间排序。函数Bound用于计算完成时间和下界。
函数BBFlow中while循环完成对排列树部结点的有序扩展。在while循环体算法依次从活结点优先队列中取出具有最小bb值(完成时间和下界)的结点作为当前扩展结点,并加以扩展。算法将当前扩展节点E分两种情形处理:
1)首先考虑E.s=n的情形,当前扩展结点E是排列树中的叶结点。
E.sf2是相应于该叶结点的完成时间和。当E.sf2 < bestc时更新当前最优值bestc和相应的当前最优解bestx。
2)当E.s 算法具体实现如下: 1.#include 2. 3.template 4.class Graph; 5. 6.template 7.class MinHeap 8.{ 9.template 10.friend class Graph; 11.public: 12.MinHeap(int maxheapsize = 10); 13.~MinHeap(){delete[]heap;} 14. 15.int Size() const{return currentsize;} 16.T Max(){if(currentsize) return heap[1];} 17. 18.MinHeap 19.MinHeap 20. 21.void Initialize(T x[], int size, int ArraySize); 22.void Deactivate(); 23.void output(T a[],int n); 24.private: 25.int currentsize, maxsize; 26.T *heap; 27.}; 28. 29.template 30.void MinHeap 31.{ 32.for(int i = 1; i <= n; i++) 33.cout << a[i] << " "; 34.cout << endl; 35.} 36. 37.template 38.MinHeap 39.{ 40.maxsize = maxheapsize; 41.heap = new T[maxsize + 1]; 42.currentsize = 0; 43.} 44. 45.template 46.MinHeap 47.{ 48.if(currentsize == maxsize) 49.{ 50.return*this; 51.} 52.int i = ++currentsize; 53.while(i != 1 && x < heap[i/2]) 54.{ 55.heap[i] = heap[i/2]; 56.i /= 2; 57.} 58. 59.heap[i] = x; 60.return*this; 61.} 62. 63.template 64.MinHeap 65.{ 66.if(currentsize == 0) 67.{ 68.cout<<"Empty heap!"< 69.return*this; 70.}