• 堆的应用:机器调度


    问题描述:考察一个机械厂,其中有 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调度方案。首先,当 nm时,只需要将作业 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
    View Code

    最大堆:

      1 #ifndef MAXHEAP_H
      2 #define MAXHEAP_H
      3 
      4 #include<iostream>
      5 #include<algorithm>
      6 #include "exceptionerror.h"
      7 using namespace std;
      8 
      9 template<typename T>
     10 class MaxHeap
     11 {
     12 public:
     13     MaxHeap(int MaxHeapSize = 10);
     14     ~MaxHeap()
     15     {
     16         if (heap!=NULL)
     17         {
     18             delete[] heap;
     19             heap = NULL;
     20         }
     21     }
     22 
     23     int Size() const{ return CurrentSize; }
     24     T Max()
     25     {
     26         if (CurrentSize==0)
     27         {
     28             throw OutofBounds();
     29         }
     30 
     31         return heap[1];
     32     }
     33 
     34     MaxHeap<T>& Insert(const T& x);
     35     MaxHeap<T>& DeleteMax(T& x);
     36     void Initialize(T a[], int size, int ArraySize);
     37 private:
     38     int CurrentSize;
     39     int MaxSize;
     40     T* heap;
     41 };
     42 
     43 template<typename T>
     44 MaxHeap<T>::MaxHeap(int MaxHeapSize=10):MaxSize(MaxHeapSize),CurrentSize(0)
     45 {
     46     heap = new T[MaxSize + 1];
     47 }
     48 
     49 template<typename T>
     50 MaxHeap<T>& MaxHeap<T>::Insert(const T& x)
     51 {
     52     size_t index = ++CurrentSize;
     53     while (index!=1&&x>heap[index/2])
     54     {
     55         heap[index] = heap[index / 2];
     56         index = index / 2;//移向父节点
     57     }
     58 
     59     heap[index] = x;
     60 
     61     return *this;
     62 }
     63 
     64 template<typename T>
     65 MaxHeap<T>& MaxHeap<T>::DeleteMax(T& x)
     66 {
     67     if (CurrentSize==0)
     68     {
     69         throw OutofBounds();
     70     }
     71 
     72     x = heap[1];
     73     T temp = heap[CurrentSize--];
     74     size_t index = 1;
     75     size_t cindex = 2;
     76     while(cindex<=CurrentSize)
     77     {
     78         if (cindex<CurrentSize&&heap[cindex]<heap[cindex+1])
     79         {
     80             ++cindex;
     81         }
     82 
     83         if (temp>heap[cindex])
     84         {
     85             break;
     86         }
     87 
     88         heap[index] = heap[cindex];//move down
     89         index = cindex;
     90         cindex *= 2;
     91     }
     92 
     93     heap[index] = temp;
     94     return *this;
     95 }
     96 
     97 template<typename T>
     98 void MaxHeap<T>::Initialize(T a[], int size, int ArraySize)
     99 {
    100     delete[] heap;
    101     heap = new T[ArraySize + 1];
    102     MaxSize = ArraySize;
    103     CurrentSize = size;
    104 
    105     memcpy(heap+1, a, (CurrentSize)*sizeof(T));
    106     size_t cindex;
    107     for (size_t index = CurrentSize / 2; index >= 1;--index)
    108     {
    109         T temp = heap[index];
    110 
    111         cindex = 2 * index;
    112         while (cindex<=CurrentSize)
    113         {
    114             if (cindex<CurrentSize&&heap[cindex + 1]>heap[cindex])
    115             {
    116                 ++cindex;
    117             }
    118 
    119             if (temp>heap[cindex])
    120             {
    121                 break;
    122             }
    123 
    124             heap[cindex/2] = heap[cindex];
    125             cindex *= 2;
    126         }
    127         
    128         heap[cindex / 2] = temp;        
    129     }
    130 
    131 }
    132 #endif
    View Code

    最小堆:

      1 #ifndef MinHeap_H
      2 #define MinHeap_H
      3 
      4 #include<iostream>
      5 #include<algorithm>
      6 #include "exceptionerror.h"
      7 using namespace std;
      8 
      9 template<typename T>
     10 class MinHeap
     11 {
     12 public:
     13     MinHeap(int MaxHeapSize = 10);
     14     ~MinHeap()
     15     {
     16         if (heap!=NULL)
     17         {
     18             delete[] heap;
     19             heap = NULL;
     20         }
     21     }
     22 
     23     int Size() const{ return CurrentSize; }
     24     T Min()
     25     {
     26         if (CurrentSize==0)
     27         {
     28             throw OutofBounds();
     29         }
     30 
     31         return heap[1];
     32     }
     33 
     34     MinHeap<T>& Insert(const T& x);
     35     MinHeap<T>& DeleteMin(T& x);
     36     void Initialize(T a[], int size, int ArraySize);
     37 private:
     38     int CurrentSize;
     39     int MaxSize;
     40     T* heap;
     41 };
     42 
     43 template<typename T>
     44 MinHeap<T>::MinHeap(int MaxHeapSize=10):MaxSize(MaxHeapSize),CurrentSize(0)
     45 {
     46     heap = new T[MaxSize + 1];
     47 }
     48 
     49 template<typename T>
     50 MinHeap<T>& MinHeap<T>::Insert(const T& x)
     51 {
     52     size_t index = ++CurrentSize;
     53     while (index!=1&&x<heap[index/2])
     54     {
     55         heap[index] = heap[index / 2];
     56         index = index / 2;//移向父节点
     57     }
     58 
     59     heap[index] = x;
     60 
     61     return *this;
     62 }
     63 
     64 template<typename T>
     65 MinHeap<T>& MinHeap<T>::DeleteMin(T& x)
     66 {
     67     if (CurrentSize==0)
     68     {
     69         throw OutofBounds();
     70     }
     71 
     72     x = heap[1];
     73     T temp = heap[CurrentSize--];
     74     size_t index = 1;
     75     size_t cindex = 2;
     76     while(cindex<=CurrentSize)
     77     {
     78         if (cindex<CurrentSize&&heap[cindex]>heap[cindex+1])
     79         {
     80             ++cindex;
     81         }
     82 
     83         if (temp<heap[cindex])
     84         {
     85             break;
     86         }
     87 
     88         heap[index] = heap[cindex];//move down
     89         index = cindex;
     90         cindex *= 2;
     91     }
     92 
     93     heap[index] = temp;
     94     return *this;
     95 }
     96 
     97 template<typename T>
     98 void MinHeap<T>::Initialize(T a[], int size, int ArraySize)
     99 {
    100     delete[] heap;
    101     heap = new T[ArraySize + 1];
    102     MaxSize = ArraySize;
    103     CurrentSize = size;
    104 
    105     memcpy(heap+1, a, (CurrentSize)*sizeof(T));
    106     size_t cindex;
    107     for (size_t index = CurrentSize / 2; index >= 1;--index)
    108     {
    109         T temp = heap[index];
    110 
    111         cindex = 2 * index;
    112         while (cindex<=CurrentSize)
    113         {
    114             if (cindex<CurrentSize&&heap[cindex + 1]<heap[cindex])
    115             {
    116                 ++cindex;
    117             }
    118 
    119             if (temp<heap[cindex])
    120             {
    121                 break;
    122             }
    123 
    124             heap[cindex/2] = heap[cindex];
    125             cindex *= 2;
    126         }
    127         
    128         heap[cindex / 2] = temp;        
    129     }
    130 
    131 }
    132 #endif
    View Code

    运行:

     1 #include <iostream>
     2 #include "LPT.h"
     3 using namespace std;
     4 
     5 
     6 int main()
     7 {
     8     JobNode a[10];
     9     for (int i = 0; i < 10;++i)
    10     {
    11         JobNode x(i, i + 1);
    12 
    13         a[i] = x;
    14     }
    15 
    16     LPT(a, 10, 3);
    17 
    18     return 0;
    19 }
    View Code

  • 相关阅读:
    04_面向对象之多态
    03_面向对象之继承
    02_对象和对象封装
    01_什么是类
    01_函数对象
    python_IO操作之B模式介绍
    python_IO操作之rwa模式介绍
    python之初始IO操作01
    Flink基础(十七): Flink CEP 简介
    解决:UserBehavior is already defined as case class UserBehavior
  • 原文地址:https://www.cnblogs.com/haoliuhust/p/4371266.html
Copyright © 2020-2023  润新知