机器调度问题

确定如何调度才能使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;
}

测试结果:

你可能感兴趣的:(机器调度问题)