问题描述

有n个作业(编号为1~n)要在由两台机器M1和M2组成的流水线上完成加工。每个作业加工的顺序都是先在M1上加工,然后在M2上加工。M1和M2加工作业i所需的时间分别为ai和bi(1≤i≤n)。
流水作业调度问题要求确定这n个作业的最优加工顺序,使得从第一个作业在机器M1上开始加工,到最后一个作业在机器M2上加工完成所需的时间最少。可以假定任何作业一旦开始加工,就不允许被中断,直到该作业被完成,即非优先调度。

问题求解

作业编号为1到n,调度方案的执行步骤为1到n,解空间每一层对应一个步骤的作业分配。
根结点对应步骤0(虚),依次为步骤1、2、…、n分配任务,叶子结点对应步骤n。
叶子节点为一个可行解,比较求最优解
对于按1~n顺序执行的某种调度方案,f1表示在M1上执行完当前第i步的作业对应的总时间,f2数组表示在M2上执行完当前第i步的作业的总时间。
若第i步执行作业j,计算公式如下:
f1=f1+a[j];
f2[i]=max(f1,f2[i-1])+b[j]
这里由于每个结点中都保存了f1和f2,因此可以将f2数组改为单个变量。将每个队列结点的类型声明如下:

struct NodeType      //队列结点类型
{  int no;          //结点编号int x[MAX];           //x[i]表示第i步分配作业编号int y[MAX];            //y[i]=1表示编号为i的作业已经分配int i;            //步骤编号int f1;           //已经分配作业M1的执行时间int f2;          //已经分配作业M2的执行时间int lb;          //下界bool operator<(const NodeType &s) const  //重载<关系函数{return lb>s.lb; //lb越小越优先出队}
};

对应的求结点e的lb的算法如下:

void bound(NodeType &e)  //求结点e的限界值
{  int sum=0;for (int i=1;i<=n;i++) //扫描所有作业if (e.y[i]==0) sum+=b[i];//仅累计e.x中还没有分配的作业的b时间e.lb=e.f2+sum;
}

用bestf(初始值为∞)存放最优调度时间。
bestx数组存放当前作业最优调度。
采用的剪枝原则是,仅仅扩展 e.lb<bestf 的结点。

代码

//问题表示
int n=4;           //作业数
int a[MAX]={0,5,12,4,8};   //M1上的执行时间,不用下标0的元素
int b[MAX]={0,6,2,14,7};   //M2上的执行时间,不用下标0的元素
//求解结果表示
int bestf=INF;         //存放最优调度时间
int bestx[MAX];     //存放当前作业最佳调度
int total=1;           //结点个数累计struct NodeType     //队列结点类型
{  int no;          //结点编号int x[MAX];           //x[i]表示第i步分配作业编号int y[MAX];            //y[i]=1表示编号为i的作业已经分配int i;            //步骤编号int f1;           //已经分配作业M1的执行时间int f2;          //已经分配作业M2的执行时间int lb;          //下界bool operator<(const NodeType &s) const  //重载<关系函数{return lb>s.lb; //lb越小越优先出队}
};void bound(NodeType &e)
{int sum=0;for(int i=1;i<=n;i++)if(e.y[i]==0)//当前作业未被分配sum+=b[i];e.lb=e.f2+sum;
}void bfs()
{NodeType e,e1;priority_queue<NodeType> qu;memset(e.x,0,sizeof(e.x));messet(e.y,0,sizeof(e.y));e.i=0;e.f1=0;e.f2=0;bound(e);e.no=total++;qu.push(e);while(!qu.empty()){e=qu.top();qu.pop();if(e.i==n){if(e.f2<bestf){bestf=e.f2;for(int j=1;j<=n;j++)bestx[j]=e.x[j];}}e1.i=e.i+1;for(int j=1;j<=n;j++){if(e.y[j]==1)continue;for(int i=1;i<=n;i++)e1.x[i]=e.x[i];e1.x[e1.i]=j;for(int i=1;i<=n;i++)e1.y[i]=e.y[i];e1.y[j]=1;e1.f1=e.f1+a[j];e1.f2=max(e1.f1,e.f2)+b[j];bound(e1);if(e1.lb<bestf){e1.no=total++;qu.push(e1);}}}
}

改进

在扩展每个子结点时判断是否为叶子结点,若是则产生一个可行解,比较产生最优解,该叶子结点不进队;若不是叶子结点则将其进队。

//问题表示
int n=4;           //作业数
int a[MAX]={0,5,12,4,8};   //M1上的执行时间,不用下标0的元素
int b[MAX]={0,6,2,14,7};   //M2上的执行时间,不用下标0的元素
//求解结果表示
int bestf=INF;         //存放最优调度时间
int bestx[MAX];     //存放当前作业最佳调度
int total=1;           //结点个数累计struct NodeType     //队列结点类型
{  int no;          //结点编号int x[MAX];           //x[i]表示第i步分配作业编号int y[MAX];            //y[i]=1表示编号为i的作业已经分配int i;            //步骤编号int f1;           //已经分配作业M1的执行时间int f2;          //已经分配作业M2的执行时间int lb;          //下界bool operator<(const NodeType &s) const  //重载<关系函数{return lb>s.lb; //lb越小越优先出队}
};void bound(NodeType &e)
{int sum=0;for(int i=1;i<=n;i++)if(e.y[i]==0)//当前作业未被分配sum+=b[i];e.lb=e.f2+sum;
}void bfs()
{NodeType e,e1;priority_queue<NodeType> qu;memset(e.x,0,sizeof(e.x));messet(e.y,0,sizeof(e.y));e.i=0;e.f1=0;e.f2=0;bound(e);e.no=total++;qu.push(e);while(!qu.empty()){e=qu.top();qu.pop();e1.i=e.i+1;for(int j=1;j<=n;j++){if(e.y[j]==1)continue;for(int i=1;i<=n;i++)e1.x[i]=e.x[i];e1.x[e1.i]=j;for(int i=1;i<=n;i++)e1.y[i]=e.y[i];e1.y[j]=1;e1.f1=e.f1+a[j];e1.f2=max(e1.f1,e.f2)+b[j];bound(e1);if(e1.i==n)//到达叶子节点{if(e1.f2<bestf){bestf=e1.f2;for(int j=1;j<=n;j++)bestx[j]=e1.x[j];}}else if(e1.lb<bestf){e1.no=total++;qu.push(e1);}}}
}

分枝限界法求解流水线作业调度问题相关推荐

  1. 分枝限界法求解0/1背包问题

    问题描述 有n个重量分别为{w1,w2,-,wn}的物品,它们的价值分别为{v1,v2,-,vn},给定一个容量为W的背包. 设计从这些物品中选取一部分物品放入该背包的方案,每个物品要么选中要么不选中 ...

  2. 分枝限界法求解任务分配问题

    问题描述 有n(n≥1)个任务需要分配给n个人执行,每个任务只能分配给一个人,每个人只能执行一个任务. 第i个人执行第j个任务的成本是c[i][j](1≤i,j≤n).求出总成本最小的分配方案. 问题 ...

  3. 第六章——分枝限界法

    分枝限界法概述 分枝限界法和回溯法一样,也是一种在问题的解空间树上搜可行解的穷举算法. 其中"分枝"指的是"分枝限界法"搜索可行解采用的策略为广度优先搜索或实现 ...

  4. 趣学算法之分枝限界法

    14天阅读挑战赛 算法知识点 采用广度优先产生状态空间树的结点,并使用剪枝函数的方法称为--分枝限界法. 分枝限界法的基本做法是: 以广度优先的方式搜索问题的状态空间树.每一个活结点只有一次机会成为扩 ...

  5. 通过例子讲解回溯法、分枝限界法

    1.写在前面 这学期上算法课,对分枝限界法这一章听的似懂非懂.后来复习备考时,参考了王晓东老师的<计算机算法设计与分析>,把这部分的原理彻底整明白了,在此与大家分析心得.我将结合自己的理解 ...

  6. 南邮《算法分析与设计》期末复习 CH9:分枝限界法

    一.分枝限界法 分枝限界法广度优先搜索问题的状态空间树,用剪枝函数(往往是限界函数)进行剪枝,通常求问题的最优解. 二.分枝限界法与回溯法的共同点 都是在问题的状态空间树上搜索问题解的算法,都通过活结 ...

  7. fifo算法_【算法学习】分枝限界法

    分枝限界 关注那些不断已被他人成功应用的新思路.你的原创思想只应该应用在那些你正在研究的问题上. --托马斯·爱迪生(1847-1931) 这周到来的太快, 没想到这么快就迎来了考试. 干了这碗烤柿粥 ...

  8. 分枝限界法/普通队列 01背包问题

    问题 三个物品他们的编号,重量和价值如下.1个背包能够称重30公斤,求装入的物品的最大价值 编号 重量 价值 1 16 45 2 15 25 3 15 25 总结 广度优先搜索解空间树:结点是状态,分 ...

  9. 回溯法解决批处理作业调度问题

    唉,这是作为一个失败的开端.但是,我不害怕失败的!今天稍微晚点睡觉,因为中午多睡啦~最近被王晓东老师的<计算机算法设计与分析>(第4版)折磨得够呛.不会说些文雅的话,这的确是事实.基础差, ...

最新文章

  1. angularjs-ngModel 控制页面的宽度
  2. 人群密度估计--Learning to Count with CNN Boosting
  3. 有限域f9的特征是多少_宽频域谐波的潜在威胁欠缺全面考虑,现有标准需进一步优化...
  4. 记录使用Spartan-6 FPGA进行一次3-8译码器实验
  5. 步骤4 - 微服务提供者接收请求,提供服务并传回给Orchestra
  6. angular面试题及答案_关于最流行的Angular问题的StackOverflow上的48个答案
  7. Java JDBC篇4——数据库连接池
  8. C++ 将数据转为字符串的几种方法
  9. 关于水晶报表打包的一些注意的地方!
  10. [转载]taking photos with live image preview
  11. 计算机桌面小工具软件,win10桌面小工具(Desktop Gadgets Installer)
  12. 《计算机组成与设计(硬件/软件接口)》读书笔记
  13. NLP之人机对话系统
  14. vscode中vue代码格式化的相关配置
  15. ElementUI折叠组件bug问题及解决
  16. 试试kaggle竞赛:辨别猫狗
  17. 中大计算机专业在上升中,考研趣事:中科大软件学院400分以上300+,中大计算机321分排第三...
  18. 魔兽显血改建工具的制作及源码
  19. 更新内核,显卡驱动崩掉解决办法
  20. Unity3D 大型游戏 最后一站 源码 部分重点匹配战斗(四)(13)

热门文章

  1. 北邮邮箱与Win10自带邮箱相连接
  2. 优雅地在markdown插入图片
  3. 利用Matlab判断某些点是否在多边形区域内
  4. android studio按钮点击事件,如何在Android Studio中添加按钮单击事件
  5. 黄金再次失守千八关口 对冲基金空头寸增加
  6. 使用计算机报点系统时填记,铁路 车务 运转系统 自动闭塞《接发列车作业标准》...
  7. 你真的了解DISA STIG吗?
  8. Unity C# 游戏客户端面试复习
  9. STM32驱动74HC165原理图加程序
  10. 破解TCP为Windows7下的迅雷提速(驱动方式修改)