问题描述:考察一个机械厂,其中有 m 台一模一样的机器。现有 n 个作业需要处理,设作业 i 的处理时间为ti,这个时间为从将作业放入机器直到从机器上取下作业的时间。所谓调度(s c h e d u l e)是指按作业在机器上的运行时间对作业进行分配,使得:
• 一台机器在同一时间内只能处理一个作业。
• 一个作业不能同时在两台机器上处理。
• 作业i 一旦运行,则需要ti个时间单位。
我们的任务是写一个程序,以便确定如何进行调度才能使在 m 台机器上执行给定的n 个作
业时所需要的处理时间最短。建立这种调度非常难。实际上,没有人能够设计一个具有多项
式时间复杂性的算法(即一个复杂性为 O (nk ml ) 的算法, k 和l 为常数)来解决最小调度时间
问题。
在调度问题中,采用了一个称为最长处理时间优先( longest processing time first, LPT)的
简单调度策略,它可以帮助我们获得一个较理想的调度长度,该长度为最优调度长度的 4 / 3 -
1 / ( 3m)。在L P T算法中,作业按它们所需处理时间的递减顺序排列。在分配一个作业时,总是
将其分配给最先变为空闲的机器。
利用堆可在 O (nl o gn) 时间内建立L P T调度方案。首先,当 n≤m时,只需要将作业 i在0~ti 时刻内分配到机器 i 上去处理。当n >m时,可以首先利用H e a p S o r t将作业按处理时间递增的顺序排列。为了建立L P T调度,作业按相反次序进行分配。
实现:
1 #ifndef LPT_H 2 #define LPT_H 3 #include "MinHeap.h" 4 #include "MaxHeap.h" 5 using namespace std; 6 template<typename T> 7 void HeapSort(T a[], int n); 8 9 class JobNode 10 { 11 friend void LPT(JobNode*, int, int); 12 friend void HeapSort<>(JobNode a[], int n); 13 friend bool operator< (const JobNode& lhs,const JobNode& rhs) 14 { 15 return lhs.time < rhs.time ? true : false; 16 } 17 friend bool operator> (const JobNode& lhs, const JobNode& rhs) 18 { 19 return lhs.time > rhs.time ? true : false; 20 } 21 friend bool operator== (const JobNode& lhs, const JobNode& rhs) 22 { 23 return lhs.time == rhs.time ? true : false; 24 } 25 public: 26 JobNode() :ID(0), time(0){}; 27 JobNode(const int& id, const int& t) :ID(id), time(t){}; 28 operator int() const{ return time; } 29 operator int*() { 30 return &time; } 31 32 33 private: 34 int ID; 35 int time; 36 }; 37 38 class MachineNode 39 { 40 friend void LPT(JobNode*, int, int); 41 friend bool operator< (const MachineNode& lhs, const MachineNode& rhs) 42 { 43 return lhs.avail < rhs.avail ? true : false; 44 } 45 friend bool operator> (const MachineNode& lhs, const MachineNode& rhs) 46 { 47 return lhs.avail > rhs.avail ? true : false; 48 } 49 friend bool operator== (const MachineNode& lhs, const MachineNode& rhs) 50 { 51 return lhs.avail == rhs.avail ? true : false; 52 } 53 public: 54 operator int() const{ return avail; } 55 private: 56 int ID; 57 int avail; 58 }; 59 60 61 template<typename T> 62 void HeapSort(T a[], int n) 63 { 64 if (a == NULL || n <= 0) 65 { 66 throw exception("Invalid input"); 67 } 68 69 MaxHeap<T> H(1); 70 H.Initialize(a, n, n); 71 72 for (int i = 0; i < n; ++i) 73 { 74 H.DeleteMax(a[i]); 75 } 76 } 77 78 //n为作业数,m为机器数 79 void LPT(JobNode a[], int n, int m) 80 { 81 82 if (n <= m) 83 { 84 cout << "Schedule one job per machine" << endl; 85 return; 86 } 87 88 HeapSort(a, n);//将作业时长从大到小排序 89 90 //初始化机器堆 91 MinHeap<MachineNode> H(m); 92 MachineNode x; 93 for (int i = 1; i <= m; ++i) 94 { 95 x.avail = 0; 96 x.ID = i; 97 H.Insert(x); 98 } 99 100 for (int i = 0; i < n; ++i) 101 { 102 H.DeleteMin(x);//取出第一个空闲的机器 103 cout << "Schedule job " << a[i].ID << " on machine" 104 << x.ID << " from " << x.avail << " to " << (x.avail + a[i].time) << endl; 105 106 x.avail += a[i].time; 107 H.Insert(x); 108 } 109 } 110 111 #endif