动态规划算法解决流水作业调度

   日期:2020-07-07     浏览:114    评论:0    
核心提示:这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好! 这是你第一次使用 Markdown编辑器#动态规划算法解决流水作业调度所展示的欢

流水作业调度问题

  • 1、问题描述
  • 2、算法分析
    • 2.1 思路分析如下:
    • 2.2 代码分析流程图如下:
    • 2.3 代码如下:
    • 2.4 运行结果:
  • 3、时空效率分析

1、问题描述

有n个作业(编号为1~n)要在由两台机器M1和M2组成的流水线上完成加工。每个作业加工的顺序都是先在M1上加工,然后在M2上加工。M1和M2加工作业i所需的时间分别为ai和bi(1≤i≤n)。
流水作业调度问题要求确定这n个作业的最优加工顺序,使得从第一个作业在机器M1上开始加工,到最后一个作业在机器M2上加工完成所需的时间最少。可以假定任何作业一旦开始加工,就不允许被中断,直到该作业被完成,即非优先调度。
输入格式:输入包含若干个用例。每个用例第一行是作业数n(1≤n≤1000),接下来n行,每行两个非负整数,第i行的两个整数分别表示在第i个作业在第一台机器和第二台机器上加工时间。以输入n=0结束。
输出格式:每个用例输出一行,表示采用最优调度所用的总时间,即从第一台机器开始到第二台机器结束的时间。
输入样例:
4
5 6
12 2
4 14
8 7
0
输出样例:
33

2、算法分析

2.1 思路分析如下:

流水作业调度问题的Johnson算法:
(1)N1={i|t[i,1]<t[i,2]},N2={i|t[i,1]>=t[i,2]};
(2)将N1 中作业依t[i,1]的非减序排列;将N2中作业依t[i,2]的非增序排列;
问题分析:
当输入的作业数目为4时:
每个作业在M1上执行的时间为t[i,1],在M2上执行的时间为t[i,2],输入的数据为:

算法按照t[i,1]<t[i,2]先执行的作业,保证M2机器上没有等待,本例中作业1,3满足条件,被选择先执行。当选择第一个作业时,算法选择让M2第一次等待时间最少的那个,本例中作业3的t[i,1]最小,这样就可以让M2第一次等待最少。所以在t[i,1]<t[i,2]的集合中,t[i,1]越小越靠前执行。
当执行t[i,1]>t[i,2]的作业时,要保证最后一个作业在M2上的执行时间最短,所以作业2,4是按照t[i,2]非增序排列,保证了作业2的t[i,2]是它们两个当中最小的一个。
算法在计算执行时间的过程如下图所示:

作业执行次序为:3,1,4,2
1)执行3时:M1上运行4个时间后交给M2,这时M2空闲了4个时间并开始工作。
所以此时要想将3做完需要18(4+14)个时间。
2)执行1时:M1上运行5个时间后,M2还在继续运行3,并没有结束。M1结束时间为9,而M2结束1的时间为24,即<9,24>。
所以此时要想把3,1做完,需要24(6+18)个时间。
3)执行4时:M1上运行8个时间后,M2还在继续运行3,并没有结束。M1的结束时间为17,而M2结束4的时间为31,即<17,31>
所以此时要想把3,1,4做完,需要31(7+24)个时间。
4)执行2时:M1上运行12个时间后,M2还在继续运行4,并没有结束。M1的结束时间为29,而M2结束2的时间为33,即<29,33>.
所以此时要想把3,1,4,2做完,需要33(2+31)个时间。

所以,根据运行结果,作业执行时间为33. 作业执行次序为3,1,4,2

2.2 代码分析流程图如下:


2.3 代码如下:


#include<stdio.h>
#include<string.h>
#include
#define N 100
using namespace std;

struct node {
int time;//执行时间
int index;//作业序号
bool group;//1代表第一个机器,0代表第二个机器
};

bool cmp(node a,node b)
{//升序排序
return a.time<b.time;
}
int main()
{
int i,j,k,n;
int a[N]={0},b[N]={0};
int best[N];//最优调度序列
node c[N];
scanf("%d",&n);
for(i=0;i<n;i++) {
scanf("%d%d",&a[i],&b[i]);
}
for(i=0;i<n;i++) { //n个作业中,每个作业的最小加工时间
c[i].time=a[i]>b[i]?b[i]:a[i];
c[i].index=i;
c[i].group=a[i]<b[i];//给符合条件a[i]<b[i]的放入到N1子集标记为true
}
sort(c,c+n,cmp);//按照c[]中作业时间增序排序
j=0,k=n-1;
for(i=0;i<n;i++) {
if(c[i].group) { //第一组,从i=0开始放入到best[]中
best[j++]=c[i].index;//将排过序的数组c,取其中作业序号属于N1的从前面进入,实现N1的非减序排序
}
else {
best[k–]=c[i].index;//将排过序的数组c,取其中作业序号属于N2的从后面进入,实现N2的非增序排序
}
}
j=a[best[0]];//最优调度序列下的消耗总时间,第一个选取M1上的工作时间最少的
k=j+b[best[0]];
for(i=1;i<n;i++) {
j+=a[best[i]];
k=j<k?(k+b[best[i]]):j+b[best[i]];//消耗总时间的最大值
}
printf("%d\n",k);
for(i=0;i<n;i++) {
printf("%d “,best[i]+1); //输出最优序列
}
printf(”\n");
return 0;
}

2.4 运行结果:

3、时空效率分析

算法的主要计算时间在对作业集的排序上,在本算法中,我们使用冒泡排序法(sort),因此,在最坏情况下算法所需要计算的时间为O(nlogn)。所需要的空间为O(n)。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服