遗传算法解决作业调用问题(classic job shop scheduling problem,JSSP)

车间作业调度问题描述

JSP问题是一个包含n个工件和m台机器的调度问题,其常用的数学描述如下:
Cmax ≥ tij + pij for all (i,j) ∈ N
tkj ≥ tij + pij for all (i,j)  (k,j) ∈ A
tij ≥ tik + pik for all (i,j) and (i,k) ∈ N
tik ≥ tij + pij for all (i,j) and (i,k) ∈ N
tij ≥ 0 for all (i,j) ∈ N
其中,Cmax表示完成所有工件加工后的最大完工时间,pij来表示工件j在机器i上的加工时间,tij表示工件j在机器i上的开始加工时间,N表示操作(i,j)的集合,A表示所有所有的工件j在机器k上加工前必须在机器i上加工操作依赖关系对(i,j)→(k,j)的集合。

遗传算法简介

遗传算法是模拟、解决或优化问题的计算方法,它是受自然界中通过选择、交叉和变异来实现生物进化的启发而提出的。当遗传算法被应用到调度问题中,一个有效的调度序列被称作染色体或个体,每个个体都有自己的适应度值。遗传算法以迭代的方式运行,每次迭代代表了种群的一代。每一代种群个体包括上一代的幸存者和新的经过交叉、变异和选择后而新产生的比较优秀的个体。不同的染色体是否被选择是由它们的适应度值来决定的,适应度越值大,被选中的概率越大。在实验中这种选择机制一直被重复,直至满足给定的条件为止。

遗传算法解决车间调度问题

本文中将分以下几个步骤来介绍遗传算法。

问题建模

本文将用两个二维数组machineNoMatrix[][]和timeMatrix[][]来分别表示第i个工件的第j道工序所使用机器的机器号和所耗费的时间,数组的行号和列号分别代表了工件的工件号和工序号,当第i个工件的第j道工序不存在的话,令mach-ineNoMatrix[i-1][j-1]=-1,timeMatrix[i-1][j-1]=0。

编码

染色体序列的长度为n*m ,n表示工件的数量,m表示机器的数量,染色体序列的每一个元素是[1,n]之间的一个随机数,该数字在序列中第几次出现表示它所代表工件的第几道工序,本文采用的是基于间接工序的编码方法。例如,对于一个3个工件×4台机器的作业调度问题,其染色体的大小为12(3*4)。工件1可以用数字1来表示,它重复出现3次表示工件1有3道加工工序。

解码

我们从左到右解码一个染色体序列,下面以一个3个工件×4台机器的车间调度问题为例来说明解码规则:
编码规则
图1 一个3×4车间调度问题的染色体实例
如图1所示,染色体序列的第一个元素为1,表示工件1,而工件1第一次出现表示是工件1的第一道工序。然后再以第六个元素1例,它表示工件1的第三道工序。我们可以从如图1所示的染色体编码序列中获得当前执行到哪个工件的哪一道工序。

初始化种群

首先随机产生一个300条染色体大小的种群,每条染色体代表一个个体,即一个可行的作业调度序列。

适应度值计算

本文的适应度值的取值为各个工件完成所有加工操作的最大完工时间(Cmax)。根据帕累托最优原则,每个染色体的适应度值代表该染色体的优势排名。
求解车间调度的最短的总调度时间的难点在于:一方面,各个工件不同的工序之间有严格的先后顺序;另一方面,同一台机器在某个时刻只可以加工一种工件。各个工件不同的工序之间有严格的先后顺序这个问题已经在染色体编码序列中已经被解决,因为染色体序列中各个工件出现的顺序就代表着各个工件的工序序列。而同一台机器某个时刻只可以加工一种工件这个问题可以通过维护一个机器数目大小的一维数组来实现,数组存储的值是该机器处理完当前工件后的空闲时间点。
车间调度执行的顺序是按染色体编码序列的顺序从左向右执行,由调度问题的执行位置和染色体编码序列可知要加工工件的工件号i,然后通过工件号在染色体序列的当前位置获得该工件所在的工序号j,由工件号和工序号从二维数组machineNoMatrix[][]和timeMatrix[][]获得第i个工件的第j道工序所使用的机器号和所耗费的时间,然后更新第i个工件第j道工序的开始时间为第i个工件第(j-1)道工序的结束时间或该工序将要使用机器的最近空闲时间点的之中的较大者,更新第i个工件第j道工序的结束时间为该工序的开始时间与加工时间之和,更新该工序所使用机器的最近空闲时间点为第i个工件第j道工序的加工完成时间。如果该工序的完工时间大于当前的最大完工时间,更新最大完工时间的值,直至染色体序列中的所有工序至所有工序被加工完毕,最终可以获得完成车间调度所需的最大完工时间,即适应度的值。

选择

在每一个连续的父代子代中,父代的一部分被选择来产生新的一代,然后基于适应度值来选择新产生的个体,适应度越大的个体越有可能被选中,本文将轮盘赌策略和精英策略相结合的方式来选择交叉和变异步骤所需的候选染色体。

交叉和变异

本文测试了三种交叉算子(顺序交叉:OX,循环顺序交叉:COX,混合顺序交叉:MOX)和两种变异算子(逆转变异:OBM和互换的基因突变:SBM),在完成这六种可能的交叉、变异对的测试后,本文保留了顺序交叉(概率P=0.95)和逆转变异(P=0.02)操作符。下面就分别简要介绍下本文所用到的交叉和变异算子:

逆转变异算子

染色体中的两个值交换它们的位置,如图2所示。
逆转变异算子
图2 逆转变异算子示例

顺序交叉算子

对于一个n个工件×m台机器的车间调度问题,首先产生范围在[1,n*m]的两个随机数且第一个随机数小于第二个随机数,n*m是染色体编码序列的长度,产生的两个随机树代表父代染色体的要遗传给子代染色体的染色体序列的起始和结束位置,在本例中的两个随机数分别为3和5。父代染色体的部分编码序列被子代继承:Father 1的编码序列(3 1 1)被Child 1继承,Father 2的编码序列(3 2 1)被Child 2继承。
Child 1:[,,,3,1,1,,,],即:继承的工序分别为工件3的第二个工序和工件1的第一个和第二个工序。
Child 2:[,,,3,1,1,,,],即:即:继承的工序分别为工件3第一个工序,工件2第二个工序和工件1第三个工序。
为了获得Child 1染色体的其它工序项:
a) 首先我们以Father 2为模板从第二个随机数5所在的位置后面开始循环构造一个新的染色体序列:(2 3 3///2 1 1 3 2 1)。
b) 我们将已经从Father 1中继承的工件序列从新产生的染色体序列中移除(即:工件3的第二个工序和工件1的第一个和第二个工序):由(2 3 X 2 X X 3 2 1)获得(2 3 2 3 2 1)。
c) 填充Child 1剩余部分 :首先从第二个随机数所代表的位置后面开始填充得到[, , _ , 3, 1, 1, 2, 3 , 2],然后循环填充得到最终序列[3, 2, 1, 3, 1, 1, 2, 3, 2]。
同理可求得Child 2的其它工序项。顺序交叉算子的具体用法如图3所示。
顺序交叉算子

图3 顺序交叉算子示例

停止条件

遗传算法运行到最短的总调度时间达到给定下限或者迭代次数达到1000次。
考虑到图片中文字的可读性,本文以小规模的作业调度问题mt06为例将一个最佳调度以甘特图的形式展示出来。mt06的具体调度信息如图4所示,本文的甘特图是用Matlab 2010b绘制的。
调度结果

图4 mt06的一个最佳调度(最短的总调度时间为55)
注:图中p(i,j)表示工件j在机器i上的加工时间,i表示机器i,j表示工件j

甘特图画法: 如何使用matlab制作作业调度结果对应的甘特图

参考文献

https://www.eii.uva.es/elena/JSSP.htm

阅读更多

扫码向博主提问

很臭很臭

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • Java
  • 爬虫
  • 遗传算法
  • 作业调度
去开通我的Chat快问
个人分类: project
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭