描述:n个作业{1,2,3....,n}要在两台机器M1,M2组成的流水线上加工完成。每个作业的加工顺序都是先在M1上加工,然后在M2上作业加工。M1,M2加工作也i所需的时间分别为ai和bi(1<=i<=n)。流水作业调度问题要求确定这n个作业的最优加工顺序,使得从第一个作业在机器M1上开始加工,到最后一个作业在机器M2上加工完成所需的时间最少。

一个最优调度应该使机器M1没有空闲时间,且机器M2的空闲时间最少,一般情况下,机器M2上会出现 机器空闲 和 作业积压 两种情况。用m(a,b)表示m任务需要在M1机器加工a分钟,在M2上需要b分钟。更直观的看,上述情况可由下图体现出来。

如图所示,如果先加工m1后加工m2,需要时间9t;反过来,需要时间13t,因此第一种情况更优

一定要该清楚每个变量代表着什么意思,要不一会儿就懵了!

设全部作业集合N={1,2,3,...,m},SN是N 的作业子集,一般情况下,机器M1开始加工S中的作业时,机器M2还在加工其他作业,需要等时间t后才可利用。将这种情况下完成S中作业所需最短时间记为T(S,t)。该问题的最优值为T(N,0)。

下面开始动态规划的四个步骤进行分析:

1. 最优子结构

设π是所给n个流水作业的一个最优调度,所需的加工时间为aπ(1)+T`。其中,T`是在机器M2的等待时间为bπ(1)时,安排作业π(2),...,π(n)所需的时间。记S=N-{π(1)},则有T`=T(S,bπ(1))。可说明其具有最优子结构性质。

选题目中前三个为例,更直观的说明一下(反正我看这些表达式是懵的,还是举个例子比较清晰)

2. 递归计算最优值

由最优子结构性质可得T(N,0)=min{ai+T(N-{i},bi)} <1<=i<=n>推广到T(S,t),有:

T(S,t)=min{ai + T(S-{i},bi + max{t-ai},0) }(i∈S)

max{t-ai} 是由于机器M2上,作业i必须在max{t-ai}时间后才能开工。因此在机器M1上完成作业i之后,在机器上还需bi+max{t-ai}-ai=bi+max{t-ai, 0}时间,才能完成作业 i 的加工。(这个数学公式又是为什么呢?具体过程如下图所示。)

 虽然满足最优子结构性质,也在一定程度满足子问题重叠性质。N的每个非空子集S都计算一次,共次,达到了指数级。因此引入 Johnson法则 解决这个问题。

3. 流水调度的Johnson法则

这个推导过程看不懂没关系,只要知道:

如果作业i和j满足min{bi,ai}>=min{bj,ai},则称作业i,j满足Johnson不等式;如果i和j不满足不等式,则交换i,j的加工顺序后,既满足 Johnson不等式

这一大串分析只为了得出一个结论:流水作业调度问题一定存在满足Johnson法则的最优调度。

4. 算法描述

上面的推导实在看着头疼,记住结论就好:

将对应的ai和bi放在一起;将ai>bi的放在一起,ai<bi的放在一起;然后ai小的递增排,ai大得递减排就可了。(ai大小是相对bi来说的)

 来一个具体问题康康吧!

动态规划的思路,类似矩阵连乘

 Johnson算法:

1)先执行t[i,1]<t[i,2],保证M2上没有等待。选择第一个作业时,让M2选择第一次等待时间最少的,
即t[i,1]越小,越靠前执行;
2)执行t[i,1]>=t[i,2]时,要保证最后一个作业在M2上执行时间最短,所以按照减序排列

具体代码如下:

#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
const int N=50;class Job { //作业类
public:int index, time;//作业编号和时间bool M;//true代表机器M1, false代表机器M2
};bool cmp(Job a,Job b){ //升序排序return a.time<b.time;
}int* Johnson(int n,int a[],int b[],int best[]){ //best为最优调度的作业序号int i,j,k,t;Job *Min =new Job[n];//n个作业中,每个作业的最小加工时间for(i=0;i<n;i++){if(a[i]<b[i]){//ai<bi的分到N1组Min[i].M =true;Min[i].time =a[i];}else{//ai>=bi的分到N2组Min[i].M=false;Min[i].time=b[i];}Min[i].index=i;}sort(Min, Min+n, cmp);//增序排列j=0,k=n-1;for(i=0;i<n;i++){if(Min[i].M ==true)//将排过序的数组Min,取其中作业序号属于N1的从前面进入,实现N1递增排序best[j++]=Min[i].index;else//取其中序号属于N2的从后面进入,实现N2递减排序best[k--]=Min[i].index;}t=a[best[0]];//第一件事在M1上的作业时间k=t+b[best[0]];//第一段时间+最后一段时间for(j=1;j<n;j++){//通过举例找出其数学计算t=t+a[best[j]];k= t<k ? k+b[best[j]] : t+b[best[j]];}best[i+1]=k;delete Min;return best;//最优序列
}
int main()
{int i,n,a[N],b[N],best[N];ifstream infile;ofstream outfile;infile.open("input1.txt");infile>>n;for(i=0;i<n;i++)infile>>a[i];for(i=0;i<n;i++)infile>>b[i];infile.close();outfile.open("output1.txt");outfile<<"the best order is:"<<endl;Johnson(n,a,b,best);for(i=0;i<n;i++){outfile<<best[i]+1<<" ";}outfile<<endl<<"the best time is:"<<endl;outfile<<best[i+1];outfile.close();return 0;
}

读取的输入文件如下图所示:

运行后输出文件如下图所示:

时间复杂度分析:计算时间花在对作业的排序上,最坏情况下,为O(logn),空间0(n)

动态规划之流水作业调度问题相关推荐

  1. 【算法设计与分析】流水作业调度问题 动态规划算法与代码实现 超详细

    题目描述 "加工顺序问题"又被称为"批处理作业调度问题". 设有n个工件需要在机器M1和M2上加工,每个工件的加工顺序都是先在M1上加工,然后在M2上加工.t1 ...

  2. python 流水作业调度_流水作业调度问题

    1.问题描述: n个作业{1,2,-,n}要在由2台机器M1和M2组成的流水线上完成加工.每个作业加工的顺序都是先在M1上加工,然后在M2上加工.M1和M2加工作业i所需的时间分别为ai和bi.流水作 ...

  3. 贪心算法训练(七)——加工生产调度(流水作业调度问题)

    贪心算法训练(七)--加工生产调度(流水作业调度问题) 1. 问题描述 某工厂收到了 n 个产品的订单,这 n 个产品分别在 A.B 两个车间加工,并且必须先在 A 车间加工后才可以送到 B 车间.某 ...

  4. 【算法】优先队列的分枝限界算法的流水作业调度问题(C++源码)

    [算法]优先队列的分枝限界算法的流水作业调度问题(C++源码) 一.任务描述 二.步骤描述 三.运行结果截图 四.源代码(C++) 一.任务描述 有一个流水作业调度问题,n=4,a[]={5,10,9 ...

  5. 加工生产调度(Johnson算法 双机流水作业调度问题)

    加工生产调度 题目描述: 某工厂收到了n个产品的订单,这n个产品分别在A.B两个车间加工,并且必须先在A车间加工后才可以到B车间加工. 某个产品i在A.B两车间加工的时间分别为Ai.Bi.怎样安排这n ...

  6. 动态规划:任务调度问题(双塔问题)

    题目链接 两个CPU,处理N个任务,每个任务有一个处理时长(0~4096),要把这些任务全部处理完,如何调度才能最高效? N个圆柱,要搭建两个塔,要使这两个塔高度之差尽量小,问较高的那座塔多高? 需要 ...

  7. 加工生产调度(流水作业调度问题)——Johnson算法应用

    题目链接: linklink link 从分析到解决 (从看题到放弃) Step1 题意理解 简化下题目: nnn个作业,在M1, M2" role="presentation&q ...

  8. 《计算机算法设计与分析》题目汇总

    Github源码地址: https://github.com/hlk-1135/Data-Structures-and-Algorithms 递归与分治: 电路布线问题 有重复元素的排列问题 集合划分 ...

  9. 分支限界,流水作业问题 批处理作业调度

    为什么80%的码农都做不了架构师?>>>    最优流水调度问题 问题描述: 设有n个作业,每一个作业i均被分解为m项任务: Ti1, Ti2, ┅ , Tim(1≤i≤n,故共有n ...

  10. 流水作业调度(动态规划)

    题目: n个作业{1,2,-,n}要在由2台机器M1和M2组成的流水线上完成加工.每个作业加工的顺序都是先在M1上加工,然后在M2上加工.M1和M2加工作业i所需的时间分别为ai和bi 例如这个例子: ...

最新文章

  1. 清华旷视:让VGG再次伟大!
  2. CSS布局之品字布局
  3. webstom新增vue模板
  4. 教你如何让电脑的ADSL宽带连接开机自动拨号
  5. 在Eclipse RCP中使用Spring AOP/ProxyFactory的问题
  6. python中while语句是_如何在Python中使用while语句[适合初学者]
  7. 关于Linux网卡调优之:RPS (Receive Packet Steering)
  8. 开机启动inittab详解
  9. linux mysql自动备份 和 数据恢复
  10. 怀旧服最新开的服务器是哪个,魔兽世界怀旧服什么时候开服 魔兽世界怀旧服开服时间介绍...
  11. c#明华rf读卡器_深圳明华URF-R330读卡器 M1卡读写程序(C#版)
  12. matlab如何将二进制文件写入txt文档中
  13. 企业微信API之通讯录同步
  14. redis配置文件参数说明及命令操作
  15. js控制页面只刷新一次
  16. java 文件zip打包下载 多个文件夹分类
  17. UV、PV、IP意思及区别解释
  18. SpringSecurity自定义认证成功处理器
  19. ajax xmlhttp下open方法POST、GET参数的区别
  20. Label 标签使用

热门文章

  1. python3识别图中的文字_Python3调用百度AI识别图片中的文字功能示例【测试可用】...
  2. 从写作到演讲,虾米君不断尝试的 2021|年终回顾
  3. 人行261号文关于电子账户的解读
  4. java 设置纸张大小设置_Java读取打印机自定义纸张.
  5. 传感器技术-光电式传感器(学习笔记十)
  6. 我来教你如何将自己的网站上传至服务器并通过域名进行访问
  7. java跳转到ie_ie跳转chrome(ie浏览器点击链接跳转谷歌浏览器)
  8. 联想ghost重装系统_联想笔记本系统重装图文教程
  9. u盾如何在计算机上使用方法,u盾在电脑中具体使用操作过程
  10. 微信开发工具-命令行的使用