确定如何调度才能使m台机器上运行指定的n个作业的时间最短。
采用一个称为最长处理时间优先(Longest Processing Time first ,LPT)的调度策略,在LPT算法中,作业按他们所需处理时间的递减顺序排列。
由于在分配一个作业的时候,总要将其分配给最先变为空闲的机器,因此机器也按空闲的到来时刻生成一个递增序列。
//文件minheap.h #include <iostream> using namespace std; struct MachineNode { int ID; //机器号 int Valid; //机器空闲时时间 }; struct JobNoe { int ID; //作业编号 int time; //作业持续时间 }; bool operator < (const JobNoe &a,const JobNoe &b) { return (a.time<b.time); } bool operator < (const MachineNode &a,const MachineNode &b) { return (a.Valid<b.Valid); } bool operator > (const JobNoe &a,const JobNoe &b) { return (a.time>b.time); } bool operator > (const MachineNode &a,const MachineNode &b) { return (a.Valid>b.Valid); } template <class T> class MinHeap { private: T *heap; int CurSize; int MaxSize; public: MinHeap(int maxsize=10) { MaxSize=maxsize; CurSize=0; heap=new T[MaxSize+1]; } ~MinHeap() { delete[]heap; } int Get_Size() const { return CurSize; } T Get_Min() { if(CurSize==0) { cout<<"堆为空"<<endl; return 9999; } else { return heap[1]; } } MinHeap<T> &Insert(const T& x) { if(CurSize==MaxSize) { return *this; } //为x寻找应插入位置 //i从新的叶子结点开始,沿着树向上 int i=++CurSize; while(i!=1 && x<heap[i/2]) { heap[i]=heap[i/2]; //将元素下移 i/=2; //移向父节点 } heap[i]=x; return *this; } MinHeap<T> &DeleteMin(T& x) { //将最小元素放入x,并从堆中删除它 if(CurSize==0) { return *this; } x=heap[1]; //重构堆 heap[0]=heap[CurSize--]; //0号位置存放最后一个元素值,然后将该位置删除 //从根开始,为heap[0]寻找合适位置 int i=1; int ci=2; while(ci<=CurSize) { //ci是较小的孩子的位置 if(ci<CurSize && heap[ci]>heap[ci+1]) ci++; //判断是否可以放入heap[i]位置 if(heap[0]<heap[ci]) break; //不能 heap[i]=heap[ci]; i=ci; // 下移一层 ci*=2; } heap[i]=heap[0]; return *this; } void Init_heap(T a[],int size,int maxsize) { delete[]heap; heap=new T[maxsize+1]; CurSize=size; MaxSize=maxsize; for(int j=1;j<size+1;j++) heap[j]=a[j]; //产生一个最小堆 for(int i=CurSize/2;i>=1;i--) { T y=heap[i]; //子树的根 //寻找放置y的位置 int c=2*i; while(c<=CurSize) { if(c<CurSize && heap[c]>heap[c+1]) c++; if(y<=heap[c]) break; heap[c/2]=heap[c]; c*=2; } heap[c/2]=y; } } }; template<class T> void Heap_Sort(T a[],int n) { MinHeap<T> hp; for(int i=1;i<=n;i++) hp.Insert(a[i]); T x; for(i=1;i<=n;i++) { hp.DeleteMin(x); a[i]=x; } } void LPT(JobNoe a[],int n,int m) { //a[]是工作数组,n是工作数,m是机器数 if(n<=m) { cout<<"Schedule one job per machine"<<endl; return ; } Heap_Sort(a,n); //对m台机器及最小堆进行初始化 MinHeap<MachineNode> H; MachineNode x; for(int i=1;i<=m;i++) { x.ID=i; x.Valid=0; H.Insert(x); } //进行调度 for(i=n;i>=1;i--) { H.DeleteMin(x); cout<<"Schedule job "<<a[i].ID <<" on Machine "<<x.ID<<" from " <<x.Valid<<" to "<<(x.Valid+a[i].time)<<endl; x.Valid+=a[i].time; H.Insert(x); } }
测试函数:
#include "minheap.h" #include <iostream> using namespace std; int main() { JobNoe a[8]; for(int i=1;i<8;i++) { a[i].ID=i; } a[1].time=2; a[2].time=14; a[3].time=4; a[4].time=16; a[5].time=6; a[6].time=5; a[7].time=3; LPT(a,7,3); return 0; }
测试结果: