机器调度问题
来源:互联网 发布:druid slf4j打印sql 编辑:程序博客网 时间:2024/05/16 01:41
1)问题描述
机器调度是指有m台机器需要处理n个作业,设作业i的处理时间为ti,则对n个作业进行机器分配,使得:
(1) 一台机器在同一时间内只能处理一个作业;
(2) 一个作业不能同时在两台机器上处理;
(3) 作业i一旦运行,则需要ti个连续时间单位。
设计算法进行合理调度,使得在m台机器上处理n个作业所需要的处理时间最短。
2) 基本要求
(1) 建立问题模型,设计数据结构;
(2) 设计调度算法,为每个作业分配一台可用机器;
(3) 给出分配方案。
3) 设计思想
假设有七个作业,所需时间分别为{2, 14, 4, 16, 6, 5, 3},有三台机器,编号分别为m1、m2和m3。这七个作业在三台机器上进行调度的情形如图9所示,阴影区代表作业的运行区间。作业4在0到16时间被调度到机器1上运行,在这16个时间单位中,机器1完成了对作业4的处理;作业2在0到14时间被调度到机器2上处理,之后机器2在14到17时间处理作业7;在机器3上,作业5在0~6时间完成,作业6在6~11时间完成,作业3在11~15时间完成,作业1在15~17时间完成。注意到作业i只能在一台机器上从si时刻到si +ti时间完成且任何机器在同一时刻仅能处理一个作业,因此最短调度长度为17。
在上述处理中,采用了最长时间优先(LPT)的简单调度策略。在LPT算法中,作业按其所需时间的递减顺序排列,在分配一个作业时,将其分配给最先变为空闲的机器 下面设计完成LPT算法的存储结构。 · 为每个机器设计数据类型: struct MachineNode { int ID; //机器号 int avail; //机器可用时刻 }; · 为每个作业设计数据类型: struct JobNode { int ID; //作业号 int time; //处理时间 }; LPT算法用伪代码描述如下: 1. 如果作业数n≤机器数m,则 1.1 将作业i分配到机器i上; 1.2 最短调度长度等于n个作业中处理时间最大值; 2. 否则,重复执行以下操作,直到n个作业都被分配: 2.1 将n个作业按处理时间建成一个大根堆H1; 2.2 将m个机器按可用时刻建立一个小根堆H2; 2.3 将堆H1的堆顶作业分配给堆H2的堆顶机器; 2.4 将H2的堆顶机器加上H1的堆顶作业的处理时间重新插入h2中; 2.5 将堆H1的堆顶元素删除; 3. 堆H2的堆顶元素就是最短调度时间;
#include<iostream>
#define N 10 //限定机器数和作业数不超过N个,这里N取10
using namespace std;
//******************************************
struct MachineNode
{
int ID; //机器号
int avail; //机器可用时间
};
struct JobNode
{
int ID; //作业号
int time; //处理时间
};
//*******************************************
//建立大根堆
void SiftD(JobNode r[],int k,int m)
{
int i,j;
i=k;
j=2*i;
while(j<=m)
{
if(j<m&&r[j].time<r[j+1].time)j++;
if(r[i].time>r[j].time)break;
else
{
int temp1,temp2;
temp1=r[i].time;
r[i].time=r[j].time;
r[j].time=temp1;
temp2=r[i].ID;
r[i].ID=r[j].ID;
r[j].ID=temp2;
}
}
}
void HeapSortD(JobNode r[],int n)
{
for(int i=n/2;i>=1;i--)
SiftD(r,i,n);
}
//*********************************************
//*********************************************
//建立小根堆
void SiftX(MachineNode r[],int k,int m)
{
int i,j;
i=k;
j=2*i;
while(j<=m)
{
if(j<m&&r[j].avail>r[j+1].avail)j++;
if(r[i].avail<r[j].avail)break;
else
{
int temp1,temp2;
temp1=r[i].avail;
r[i].avail=r[j].avail;
r[j].avail=temp1;
temp2=r[i].ID;
r[i].ID=r[j].ID;
r[j].ID=temp2;
}
}
}
void HeapSortX(MachineNode r[],int n)
{
for(int i=n/2;i>=1;i--)
SiftX(r,i,n);
}
//**********************************************
void assign(MachineNode M[],JobNode J[],int m,int j) //完成任务分配
{
if(m>=j) //如果机器数m大于或等于作业数j
{
cout<<"一台机器完成一个作业,最大工作时间为:";
HeapSortD(J,j); //以各作业所需时间建立大根堆,堆顶元素即为最大耗时的作业
cout<<J[1].time<<endl; //最大工作时间即为最大耗时的作业的所需时间
}
else //如果机器数m小于作业数j
{
for(int i=1;i<=m;i++) //先为每台机器分配一个作业,先把所需时间最大的m个作业分配给m台机器。
{
HeapSortD(J,j); //建立大根堆求堆顶元素确定其中耗时最大的作业
M[i].avail=J[1].time; //机器i的处理时间即为作业的所需时间
cout<<"机器"<<M[i].ID<<"完成作业"<<J[1].ID<<endl;
for(int k=1;k<j;k++) //减去已分配的作业
J[k]=J[k+1];
j=j-1;
}
for(int q=j;j>=1;q--) //把剩余的j-m个作业分配下去(j=j-m)
{
HeapSortX(M,m); //将m机器个机器按可用时建立小根堆
HeapSortD(J,j); //将j个作业按处理时间建立大根堆
cout<<"机器"<<M[1].ID<<"完成作业"<<J[1].ID<<endl; //将大根堆的堆顶作业分配给小根堆的堆顶机器
M[1].avail+=J[1].time; //将小根堆的堆顶机器加上大根堆的堆顶作业的处理时间,重新插入小根堆(循环执行HeapSortX(M,m)时完成)
for(int k=1;k<j;k++) //减去已分配的作业
J[k]=J[k+1];
j=j-1;
}
cout<<"最短调度时间为:"<<M[1].avail<<endl; //小根堆的堆顶元素就是最短调用时间
}
}
void main()
{
int j=0; //作业个数
int m=0; //机器个数
int i;
MachineNode M[N]; //机器的结构体数组
JobNode J[N]; //作业的结构体数组
cout<<"请输入作业个数:";
cin>>j;
cout<<"请输入每个作业需要的处理时间:"<<endl;
for(i=1;i<=j;i++)
{
J[i].ID=i; //为每个作业确定序号
cout<<"第"<<i<<"个作业:" ;
cin>>J[i].time; //输入每个作业的用时
}
cout<<"请输入机器的个数:";
cin>>m;
for(i=1;i<=m;i++)
M[i].ID=i; //为每台机器确定序号
assign(M,J,m,j); //调用完成分配任务的函数
}
- 机器调度问题
- 机器调度问题
- 并行机器最短调度问题
- 【POJ1325】机器调度
- 机器工作调度
- 动态规划解机器调度问题——算法解题报告
- Poj1325 Machine Schedule机器调度
- 问题:飞行调度难题
- 任务调度问题
- 单机调度问题
- 多机调度问题
- 多机调度问题
- 线程的调度问题
- 流水作业调度问题(转)
- XEN cpu 调度问题
- Java---------银行业务调度问题
- 多机调度问题
- 车站调度问题
- 言+言
- SQL 高效通用分页存储过程(双向检索)
- 普通变量 在内存中栈式存储的证明
- 4miniutes
- web开发头标签meta
- 机器调度问题
- 行为模式(Behavioral Pattern)中的不变模式
- 要永远坚强
- CListCtrl
- Symbian S60 修改程序图标
- 自定义函数来处理Sql中的数组
- Using Web Deployment Projects with Visual Studio 2005
- 我啥也不会说,开个博客干什么?
- C# 判断指定字符串是否包含有汉字