目 录
4.7.4 TLBO类中从顺序数中随机找出两个不同数值的方法
第七章 easyopt.shopSch.pms包中类和方法的使用
第八章 easyopt. shopSch.fsp包中类和方法的使用
第九章 easyopt. shopSch.jsp包中类和方法的使用
《Handbook of Optimizing Package: easyopt.jar》
AEOM
December, 2021
4.7.4 TLBO类中从顺序数中随机找出两个不同数值的方法
第七章 easyopt.shopSch.pms包中类和方法的使用
第八章 easyopt. shopSch.fsp包中类和方法的使用
第九章 easyopt. shopSch.jsp包中类和方法的使用
优化计算工具包easyopt.jar是在jdk1.8平台上开发的,可用于jdk1.8及其之后版本的环境。
本说明书是基于easyopt.jar V20220331版本编写的,用于帮助用户理解easyopt.jar车间调度计算和优化包中的类和方法的作用和使用方法。
本说明书结合easyopt.jar的API文档学习和使用更易于理解和掌握。
easyopt.jar包主要包含了进行车间调度计算或智能优化过程中所使用的类和方法集合,当前主要包括如下的子包:
表1.1 easyopt.jar功能简介
包名称 |
包 功 能 |
easyopt.chart |
可进行调度优化计算结果图形展示的类 |
easyopt.common |
车间智能调度优化计算中所涉及的通用类和方法包,主要有各类算法类、数组转换、查找、排序类等 |
easyopt.model |
车间智能调度优化计算中所涉及的通用对象模型,主要有订单对象、过程对象和操作【任务】对象 |
easyopt.shopSch |
各类车间调度优化计算过程中所使用的包和方法 |
easyopt.shopSch.fsp |
各类流水车间进行调度优化计算所使用的方法集合 |
easyopt.shopSch.jsp |
作业车间调度计算实验和智能优化中涉及的类和方法 |
easyopt.shopSch.pms |
各类单阶段并行机进行调度优化计算所使用的方法集合 |
easyopt.jar包导入相关开发环境同其他jar包的导入步骤相同,这里以将easyopt.jar导入eclipse为例进行说明。
Step1: 在eclipse中新建项目;
Step2: 在项目中新建一个文件夹lib;
Step3: 将easyopt.jar粘贴到lib文件夹中,参看图1.1;
图1.1 easyopt.jar包添加进项目lib文件夹
Step4:在项目上点右键,选择Build Path,再选择Configure Build Path,然后在弹出界面中单击“Add JARs”按钮,将本项目中前面粘贴的easyopt.jar加入项目,如图1.2所示。
图1.2 easyopt.jar导入项目
后续即可直接调用该包中的类和方法,具体参看第三章及其后的说明。
车间调度所研究的问题是将稀缺资源分配给在一定时间内的不同任务。它是一个决策过程,在大多数制造和生产系统及信息处理环境中扮演着重要的角色。随着生产规模的不断扩大,调度和决策对企业的管理和生产的重要性日渐凸显。好的调度方案可以提高企业的生产水平,使资源利用更合理,并提高市场竞争力。
车间调度问题一般是指在一定时间内,通过可用共享资源的分配和生产任务的排序,来满足指定的性能指标。车间调度问题一般可以描述为:针对某项可以分解的工作(如钢铁加工等),在一定的约束条件下(如工艺次序约束、资源约束、交货期约束等),如何安排其组成部分(工序)所占用的资源(如加工机床、缓冲区等)、加工时间及先后次序,以便使得某项或多项目标(如最大完成时间、总流经时间、等待时间等)最优化。
车间调度问题受多种因素影响,包括:产品的加工次序、车间生产能力、加工设备性能、原料可用性、批量大小、加工成本、产品的投产期和交货期、零等待约束、零空闲约束、设备维修时间约束、模糊时间约束等。上述约束条件中,有些是生产过程中必须满足的,如交货期、生产能力、原材料供应、设备维修、产品加工次序等;有些约束条件则需要达到一定的满意度,如生产成本、批量大小等;另外,还有些约束条件是动态变化的,具有一定的不确定性,如设备故障维修、原材料供应的变化、模糊加工时间等。
车间调度问题的性能指标是评价调度方案优劣的依据,实际车间调度问题涉及的主要性能指标包括生产周期最短、客户满意度最高、设备利用率最高、约束惩罚最小、利润最大化、成本最低等。
在调度问题中,一般存在m台机器(machine) {M1
,…,Mm} ,n个工件(Job) {J1,…,
Jn},每个工件有多道工序。一个调度问题通常用三元组α\β\γ来描述,其中:
α描述机器环境;
β提供加工特征和约束的细节,可能包含任何一项,也可能包含多个选项;
γ描述最小化的目标,可以包含一个目标,也可以包含多个目标。
调度问题分类及其标识如表2.1所示。
表2.1调度问题分类及其标识
域 |
标识 |
含义 |
|
α |
1 |
单一机床,加工所有工件 |
|
Pm |
并行的m台性能相同的机床,每个工件在指定的机床集合中选择一个进行加工 |
||
Qm |
并行的m台性能不同的机床,每个工件在指定的机床集合中选择一个进行加工 |
||
Fm |
流水车间调度,m台机床串行,每个工件按照相同加工路径经过每台机床 |
||
FFC |
柔性流水车间调度,是流水车间调度Fm和并行机Pm的一般化。有c个串 行的工位,每个工位有多台并行同速机,每个工件可以在多台性能相同的机床 (同一个工位)中选择一台进行加工,所有工件加工路径相同 |
||
Jm |
作业车间调度,m台机床,每个工件有自己的加工路径 |
||
FJc |
柔性作业车间调度,是作业车间调度和并行机Bn的一般化。有。个串 行的工位,每个工位有多台并行同速机,每个工件可以在多台性能相同的机床 (同一个工位)中选择一台进行加工,工件有自己独立的加工路径 |
||
Om |
开放车间调度,m台机床,每个工件在每台机床上都进行多次加工,但有些加工时间可以是零,每个工件的加工路径没有限制 |
||
β |
rj |
工件释放时间,工件j不可能在它的释放时间弓前开始加工。若约束中没 有弓,则工件顶在0时刻即可以加工 |
|
sij |
工件切换时间,代表在同一机床上,工件,加工完毕,加工工件,需要的准备 时间。若工件顶是第一个工件,则S0j表示工件,的准备时间;若工件j是最后 一个工件,则Sj0表示工件j之后的清理时间;若立是依赖于每台机床的,则用Sijk表示在机床k上工件i和工件j的加工切换时间 |
||
prmp |
中断,允许中断一项正在加工的工件,然后把另一个工件放在该机床上加 工。当中断的工件重新回到原来的机床上加工时,其之前的工作可以继续 |
||
prec |
优先(偏序)约束,当一个工件开始加工前,另一个或多个工件必须已经完 成。如果每个工件最多有一个前驱,最多有一个后继,则称为链式优先约束; 若每个工件最多有一个后继,则称为入树;若每个工件最多有一个前驱,则称 为出树 |
||
Brkdzvn |
机床故障,该约束分为固定时间段机床故障和可变时间段机床故障,在机床 故障需要维修的时间段,工件不能在此机床上加工 |
||
Mj |
机床约束,该约束适用于并行机和柔性调度的环境中。集合Mj表示工件j的可选加工机床集合。集合Mj不出现,表示工件j可以在任意机床上加工 |
||
block |
阻塞约束,在一个流水车间中,若两台连续的机床之间有无限容量的缓冲 区,则不会出现工件加工完毕阻塞在原机床的现象;若机床之间没有足够的缓 冲区,则加工完毕的工件会阻塞在上游机床,从而不能进入下一道工序 |
||
nwt |
无等待约束,在流水车间中,工件加工不允许在两台连续的机床间等待。为 保证该约束,工件第一道工序的加工时间必须推迟。该约束一般用于对温度 或特定环境要求严格的情况,如钢材加工等 |
|
|
recrc |
若工件允许再次访问同一台机床,则称为再循环约束 |
|
|
γ |
Cmax |
生产周期,Cmax = max{C1,•••,Cn}其中,Ci(i= 1,…,n)表示工件i的最后一道工序的完工时间。生产周期最小化意味着机器的高利用率 |
|
Fmax |
最大流经时间,Fmax = max{Fi} = max(Ci —ri,},其中,Ci (i= 1, ••• ,n)表示工 件i的最后一道工序的完工时间,ri,表示工件i的释放时间,Fi;表示工件i从开始释放到加工完毕离开系统所经历的时间,即工件i的流经时间 |
|
|
Wmax |
机床最大负载,,其中pi,j,k表示工件i的第j道工序在机床k上的加工时间,ni表示工件i的工序数目 道工序在机床*上加工的加工时间,",表示工件/的工序数目 |
|
|
Wtotal |
机床总负载,minWtotal =,其中, |
|
|
Ctotal |
总生产周期, |
|
|
Ftotal |
总流经时间, |
|
|
|
平均机床负载, |
|
|
|
平均完工时间, |
|
|
Lmax |
最大延迟,Lmax
=max{L1,…,Ln},其中,Li(i=1, ・・・,n)表示工件i违反工期 的惩罚 |
|
|
Ltotal |
总延迟时间, |
|
|
|
平均完工时间, |
|
|
|
平均已完成工件数 |
|
|
|
平均未完成工件数 |
|
|
|
平均机器空闲时间 |
|
|
Imax |
最大机器空闲时间 |
|
某车间需要完成n个作业的生产加工,这些作业只需要经过1次操作即可完工,车间配置了m台设备用于进行这些作业的生产加工, 这m台设备的功能基本相同,均可以进行这些作业的生产加工,即这些设备为并行可替换设备,生产管理人员需要确定这n个作业中在m台并行机上的分配, 以及每台设备上所分配作业的加工先后关系,以达成某些运作目标的优化,这个决策问题称之为单阶段并行机调度(Single Stage Parallel Machine Scheduling,SSPMS或PMS)。
现实生产运作系统中,作业可能需要通过多道工序方能完成生产加工,而在作业的某一道或某几道工序中可能存在着
多台可选机器设备,构成了多阶段的、具有并行机的车间调度问题,这一类问题一般归纳到柔性流水车间或柔性作业车间调度问题中,因此,一般并行机研究主要指单阶段并行机。
虽然单阶段并行机看起来作业流程只有一道,好像比较容易进行生产组织, 但是根据现实生产过程中涉及问题的特征和优化目标,该类问题任然具有很强的优化需求。PMS优化过程中可能需要考虑的因素有:作业交货时间due time、作业释放时间release time、作业拆分约束job splitting、加工过程设备是否具有独占性preemptive vs. nonpreemptive、设备是否存在故障、设备前后加工不同类型作业是否存在调整时间setup time、调整时间是否同作业顺序或机器相关sequence-dependent
or sequence-independent、作业在不同机器上加工时间是否存在不同heterogeneous、优化目标是完工时间最小makespan还是总拖期最小tardiness等。
流水车间调度问题(Flow Shop Scheduling Problem, FSP)是研究最广泛的生产调度问题之一,具有很强的工程应用背景。研究表明:约有25%的生产制造系统、组装线和服务设施可简化为FSP模型。FSP研究n个工件在m台机器上的流水加工过程。以金属导线生产线为例进行说明:待生产的n个客户订单为生产不同规格的导线,生产过程为铜丝依次经过圆线拉丝、扁线辊压、漆包、换位成型四道工序,客户订单可以看作n个独立的作业,各项作业的加工顺序必须按照严格的先后顺序执行,这就是一个流水车间调度问题。调度优化的目标就是确定这n项订单的先后加工顺序,以达到特定生产绩效指标最优。
一般地,FSP描述为:有n个独立的工件按照相同的工艺路线在m台机器上加工,即每个工件需要经过m道工序,这些工序分别要求不同的机器,并且各工序的加工过程不能中断。
同时假设:(1)所有工件在零时刻都可以加工;(2)机器可以连续工作并且机器之间存在无限大的缓冲区;(3)一个工件不能同时由多台机器加工,一台机器也不能同时加工多个工件;(4)已知各工序的加工时间,工件的准备时间包含在加工时间内或者可以忽略不计。
优化目标是:确定各工件的生产次序,即一个加工序列,使得某项生产指标最优,其中常见的生产指标有最大完成时间、总流经时间和机器闲置时间等。优化最大完成时间有利于提高生产率,优化总流经时间可以均衡地利用生产资源和减小在线库存,而优化机器闲置时间则可提高机器利用率。
图2.1为三个工件、四台机器的流水车间调度甘特图,从图中可以看出,工件 1、2、3的加工顺序都是从机器1到机器4,而且同一工件后道工序的开工时间不能早于其前道工序的完工时间。
图2.1
三工件四机器的流水车间调度甘特图
根据相关文献,以最大完成时间、总流经时间和机器闲置时间为优化目标的FSP分别记为、和。显然,上述问题的解空间规模均为。
通常假设流水车间中所有机器上各个工件的加工次序相同,即只需要考虑n个工件在第一道工序上的排序即可,这些工件在后面的机器上的排序同第一道序的排序完全相同,这类问题称为置换流水车间调度问题(Permutation FSP,PFSP),总的排序选择为个不同的排列。
类似地,可将以最大完成时间、总流经时间和机器闲置时间为优化目标的PFSP分别记为、和。尽管PFSP的解空间远远小于FSP,但已证明和为NP-hard问题。至今没有一个具有多项式计算复杂度的全局优化算法。
在炼钢、食品加工、化工和制药等生产制造过程中,加工对象一旦开始加工就不能中断,直到完成其全部工序的操作。例如,在钢铁生产企业的炼钢-连铸生产过程中,为实现热送热装的生产方式,减少钢液在空气中的温降,希望钢液在前后工序间的加工过程零等待。这类作业一旦在第一道工序开工后,后续工序之间不能出现等待的流水车间问题称之为零等待流水车间调度问题(No-Wait Flowshop Scheduling Problem,NWFSP)。
以最大完成时间和总流经时间为优化目标的零等待流水车间调度问题分别记为和。研究表明,当机器数量时,这类调度问题即为NP-hard问题。目前,NWFSP问题及求解算法已成为学术界和工业界共同关注的热点课题。
图2.2 三工件四机器的零等待流水车间调度甘特图
以置换流水车间的三工件、四工序问题为例,如果为零等待调度问题,则其甘特图如图3.2所示,可以看出工件2和工件3为了不在后续的工序出现等待机器空闲情况,在第一道序都推迟了开工时间。
在集成电路、纺织和陶器等许多产品的生产制造过程中,不允许机器停止运转, 这就是所谓的零空闲调度问题。譬如,在采用照相平板印刷法生产集成电路的过程中,所使用的分挡器是一种昂贵的设备,一旦运行是不希望其停止的;陶器滚筒干燥炉的使用过程中要耗费大量的天然气,由于炉中的热惯性较大,其停止和开启都需要几天的时间,因此,在设备运行时,也希望是连续工作的。这类考虑某台设备一旦开工在将全部任务完成之前不能空闲的流水车间调度问题称之为零空闲流水车间调度问题(No-Idle Flowshop Scheduling Problem,NIFSP)。
一般地,NIFSP描述为:有n个独立的工件按照相同的工艺路线在m台机器上加工,即每个工件需要经过m道工序,这些工序分别要求不同的机器,而这些机器一旦开工在将全部作业完成之前不允许空闲,记为:Fm∣perm
,no-idle∣Cmax。
以置换流水车间的三工件、四工序问题为例,如果为零空闲调度问题,则其甘特图如图2.3,可以看出为了实现机器一旦开工则不能空闲的要求,工件1在机器3和机器4上均推迟了开工时间。
图2.3 三工件四机器的零空闲流水车间调度甘特图
在化工、钢铁制造和食品加工等许多生产过程中,由于机器中间缓冲区或生产温度的限制,使得工件加工完成后被阻塞在当前机器上,这就是所谓的阻塞流水车间调度问题(Blocking Flowshop Scheduling Problem,BFSP) o譬如,在化学制造过程中,由于温度的要求,当药品在上游机器上完成后,为了保持此时的高温,应立即离开当前的机器并转向下游机器。但是如果下游机器处于忙的状态,此时药品只能被阻塞在上游机器上。又如,在钢铁制造中,有两个关键的阶段:加热和轧制钢板。铸块在煤坑中加热到很高的温度,被送到轧制钢板磨坊轧制。因为加热设备的停止和开启需要很长时间,为了提高效率和节省成本,所以在设备运行时,希望加工过程是连续的。
一般地,BFSP描述为:有n个独立的工件按照相同的工艺路线在m台机器上加工,工序间不存在存放区,即一个工件在前道设备加工完毕后只有等到后道工序设备空闲方能从前道设备被释放到后道设备,这个等待后道工序空闲的时段前道设备无法从事其他工件的加工。最大完工时间最小化的阻塞流水车间调度问题记为:Fm∣blocking∣Cmax
以置换流水车间的三工件,四工序问题为例,如果为阻塞流水车间调度问题,则其甘特图如下,可以看出由于工序间不存在缓存区,工件2在第一台设备加工结束,工件3在第一台设备、第二台设备和第三台设备上加工结束后都会被阻塞在原有设备上一段时间,以等待后道工序设备空闲,甘特图中由斜线填充的区域。可以看出其生产状态同置换流水车间调度问题的状态存在区别。
图2.4 三工件四机器的阻塞流水车间调度甘特图
混合流水车间调度问题(Hybrid Flow Shop Scheduling Problem,HFSP)也称为柔性流水车间调度问题(Flexible Flow Shop Scheduling
Problem,FFSP),因为该问题是在FSP基础上增加了柔性,即在m道工序中至少有一道工序的机器数量为两台或多台。HFSP的其他特征如下:
(1)
车间要进行n个批次或n个种类产品的生产;
(2)
这些批次或种类的产品的工艺路径都是相同的,都需要经过m道工序,不同的是不同产品在同一道工序上的加工时间可能不同;
(3)
在m到工序中存在至少一道工序的机器数量为两台或多台,且这些机器性能相同。
优化目标设定为:最大完工时间最小。
按照车间调度问题的三元组表示法,HFSP规范标识为: 。
以最快完工时间的四工件四工序,其中工序2和4分别有两台机器的混合流水车间调度问题为例,绘制甘特图如下,各个工件在工序2和工序4将会选择可以最早开工的机器进行生产,从而缩短总的完工时间。
图2.5 四工件四机器的混合流水车间调度甘特图
作业车间调度(Job Shop Scheduling Problem,JSP)是典型的组合优化问题,其目的是实现资源的合理分配,具体来说,为实现规定的生产目标,依据实际需求,将生产资源实现准确地分配和高效地利用,最终可以提高企业的生产效益,缩短供货周期等。
一般而言,JSP 问题的定义可以通过两个集合来表解释,一个可利用机器集合和一个待加工工件集合,其中每个工件集合又是由若干工序构成的集合,JSP 问题的标准的数学描述为:n个工件J
= {1,...,n}在m台机器M= {1,...,m}上完成加工,每个工件需要完成具有前后工序关系的m项操作,每项操作所用的机器事先确定并耗费一定工时,每个操作有且仅有一台可以用来加工的机器,当一个工件的所有工序都完成加工时,则代表着该工件完成加工。
JSP问题可以使用如下示例表所示的数据进行描述,表中涉及四个作业四台机器,每个作业有四道工序,不同作业同一工序所用的机器不同,调度优化是获取各个作业在每台机器上的生产排序,该排序能够满足作业的工序前后约束,并达成某些运作目标的优化,例如完工时间最短等。
表2.2
4*4作业车间调度数据示例表
作业Id |
工序1 |
工序2 |
工序3 |
工序4 |
||||
MachId |
Ptime |
MachId |
Ptime |
MachId |
Ptime |
MachId |
Ptime |
|
1 |
3 |
54 |
1 |
34 |
4 |
61 |
2 |
2 |
2 |
4 |
9 |
1 |
15 |
2 |
89 |
3 |
70 |
3 |
1 |
38 |
2 |
19 |
3 |
28 |
4 |
87 |
4 |
1 |
95 |
3 |
34 |
2 |
7 |
4 |
29 |
示例数据两种排产方案甘特图分别如下2.6(a)和(b)所示,图中纵轴为机器编号,横轴为时间,带颜色的矩形表示操作的工时安排,相同颜色表示同一个作业,图中数字串中:第一个数字为作业编号,第二个工序编号,方括号中两个数字分别为开工和完工时间。可以看出不同排产方案下最早完工时间是不同的,其中图(a)的完工时间为272,图(b)的完工时间为287。
(a)
(b)
图2.6 作业车间调度甘特图
经验规则算法也称之为启发式调度算法,该类算法利用面向问题的特定知识和经验产生求解方案,能够在较短时间内得到次优解,除非极少数规模特殊问题或规模比较小的问题,一般情况下规则算法获得的解的质量难以保证。车间调度问题中的基本经验规则算法有:
(1) FCFS(First come first served)最早到达的作业最先安排【到达时间优先】
(2) EDD(earliest due date)最早交货期的作业最先安排【交货期早优先】
(3) SPT(shortest processing time):处理时间最短的作业最先安排【工时短优先】
(4) LPT(longest processing time):处理时间最长的作业最先安排【工时长优先】
(5) Slack(slack time):松弛时间最短的作业最先安排,松弛时间=交货期之前剩余时间-剩余加工时间【松弛时间短优先】
(6) FOPR(fewest operation remaining):剩余工序数最少的作业最先安排【工序少优先】
(7) MOPR(most operation remaining):剩余工序数最多的作业最先安排【工序少优先】
(8) LSP(least slack per operation):松弛时间与剩余工序数比值最小的作业最先安排【松弛/工序比小优先】
(9) CR(critical ratio):松弛时间与剩余工作日比值小的作业优先。
除了上述经验规则算法之外,还有一些稍微复杂和效率较高的经验规则算法,主要有Johnson算法、CDS算法、Palmer算法、Gupta算法等。
(1) 算法简介
Johnson算法[9]是一种解决的方法,它可以在O(nlog(n))时间内求得问题的最优解。
(2)算法计算流程
步骤1:分组,将n个工件根据后续条件分为两组P和Q。若,则将工件j放入组P中;否则,将工件j放入组Q中。
步骤2:排序,将组P中的工件按照递增排序得到部分排列S1,将组Q中的工件按照递减排序得到部分排列S2,则S={S1,S2}为最优排列。
(3)算法计算示例
例 考虑一个7工件的调度问题,其工时数据为
JobId j |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
P[j,1] |
8 |
12 |
6 |
11 |
9 |
4 |
5 |
P[j,2] |
6 |
10 |
11 |
5 |
3 |
9 |
6 |
由步骤1可得集合P={3,6,7}
,Q={1,2,4,5}
由步骤2可得集合S1={6,7,3},S2={2,1,4,5},所以S={6,7,3,2,1,4,5}位最优生产排序,其最大完成时间为58,详细排产如下:
工序 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
2 |
2 |
2 |
2 |
2 |
2 |
2 |
作业 |
6 |
7 |
3 |
2 |
1 |
4 |
5 |
6 |
7 |
3 |
2 |
1 |
4 |
5 |
开工时间 |
0 |
4 |
9 |
15 |
27 |
35 |
46 |
4 |
13 |
19 |
30 |
40 |
46 |
55 |
完工时间 |
4 |
9 |
15 |
27 |
35 |
46 |
55 |
13 |
19 |
30 |
40 |
46 |
51 |
58 |
(1)CDS简介
CDS方法是Campbell-Dudek-Smith 对Johnson算法的扩展,它可用于对多于两个工序的置换流水车间调度问题进行求解,可在O(mnlog(n))时间内得到Fm|prmu|Cmax的次优解。该方法首先将m台机器分组,产生m-1组F2|prmu|Cmax,再由Johnson算法分别求得各F2|prmu|Cmax的最优排列,然后选择目标值最好的排列为所求结果。
(2)算法步骤
step1 :将Fm|prmu|Cmax分解为m — 1组F2|prmu|Cmax,各组虚拟机器和加工时间如表2. 5所示。
组别 |
虚拟机器1 |
虚拟机器2 |
虚拟加工时间 |
虚拟加工时间 |
1 |
机器1 |
机器m |
|
|
2 |
机器1和2 |
机器m和m-1 |
+ |
+ |
… |
… |
… |
… |
… |
m— 1 |
机器1,2,・・・,m-1 |
机器m,m-1,…,2 |
++…+ |
++…+ |
例 考虑一个阶的,其加工数据为
Job Id |
J1 |
J2 |
J3 |
J4 |
J5 |
M1 |
11 |
8 |
10 |
5 |
12 |
M2 |
7 |
2 |
9 |
9 |
9 |
M3 |
13 |
8 |
13 |
10 |
13 |
M4 |
12 |
7 |
11 |
10 |
9 |
Job1 |
Job2 |
Job3 |
Job4 |
Job5 |
||
No1 |
虚拟Mach1 |
11 |
8 |
10 |
5 |
12 |
虚拟Mach2 |
12 |
7 |
11 |
10 |
9 |
|
No2 |
虚拟Mach1 |
18 |
10 |
19 |
14 |
21 |
虚拟Mach2 |
25 |
15 |
24 |
20 |
22 |
|
No3 |
虚拟Mach1 |
31 |
18 |
32 |
24 |
34 |
虚拟Mach2 |
32 |
17 |
33 |
29 |
31 |
由CDS算法的步骤2,得到3个排列:{4-3-1-5-2}、{2-4-1-3-5}和 {4-1-3-5-2},其对应的最大完成时间分别为79,80和79。
所以,最终输出排列为= (4-3-1-5-2} ,Cmax为79,具体工序时间如下表。
工序 |
作业 |
开工时间 |
完工时间 |
1 |
4 |
0 |
5 |
1 |
3 |
5 |
15 |
1 |
1 |
15 |
26 |
1 |
5 |
26 |
38 |
1 |
2 |
38 |
46 |
2 |
4 |
5 |
14 |
2 |
3 |
15 |
24 |
2 |
1 |
26 |
33 |
2 |
5 |
38 |
47 |
2 |
2 |
47 |
49 |
3 |
4 |
14 |
24 |
3 |
3 |
24 |
37 |
3 |
1 |
37 |
50 |
3 |
5 |
50 |
63 |
3 |
2 |
63 |
71 |
4 |
4 |
24 |
34 |
4 |
3 |
37 |
48 |
4 |
1 |
50 |
62 |
4 |
5 |
63 |
72 |
4 |
2 |
72 |
79 |
(1)Palmer算法简介
Palmer算法是根据作业加工时间构造一个斜度指标,因此也称为斜度指标法,然后根据各作业斜度指标进行排序获得Fm|prmu|Cmax问题的一种次优排序结果,正常情况下,该算法的调度结果不是太好,不如CDS方法。
(2)算法步骤
Step1:按照下式计算所有工件的斜度顺序指标,
Step2:按照sj非增的顺序排列各工件,所得工件排列即为输出结果。
(3)计算示例
Job Id |
J1 |
J2 |
J3 |
J4 |
J5 |
M1 |
11 |
8 |
10 |
5 |
12 |
M2 |
7 |
2 |
9 |
9 |
9 |
M3 |
13 |
8 |
13 |
10 |
13 |
M4 |
12 |
7 |
11 |
10 |
9 |
(1) 由步骤1得到工件1、2、3、4和5的斜度指标分别为9,3,7,16,-5,斜度指标以作业1为例进行说明:
其中s1=(2*1-4-1)*11+(2*2-4-1)*7+(2*3-4-1)*13+(2*4-4-1)*12
=-3*11-1*7+1*13+3*12
=-33-7+13+36=-40+49=9
(2) 按照斜度指标排序得到排列为=(4,1,3,2,5},其最大完成时间为80,可以看出排产结果比CDS差【CDS最大完工时间为79】,具体排产方案如下表
工序 |
作业 |
开工时间 |
完工时间 |
1 |
4 |
0 |
5 |
1 |
1 |
5 |
16 |
1 |
3 |
16 |
26 |
1 |
2 |
26 |
34 |
1 |
5 |
34 |
46 |
2 |
4 |
5 |
14 |
2 |
1 |
16 |
23 |
2 |
3 |
26 |
35 |
2 |
2 |
35 |
37 |
2 |
5 |
46 |
55 |
3 |
4 |
14 |
24 |
3 |
1 |
24 |
37 |
3 |
3 |
37 |
50 |
3 |
2 |
50 |
58 |
3 |
5 |
58 |
71 |
4 |
4 |
24 |
34 |
4 |
1 |
37 |
49 |
4 |
3 |
50 |
61 |
4 |
2 |
61 |
68 |
4 |
5 |
71 |
80 |
(1)算法简介
Gupta是一种修正 Palmer算法,即对斜度指标计算公式进行调整,然后具体获取调度结果。
(2)算法步骤
Step1:按照下式计算每个工件的斜度指标
式中
步骤2:按照s,非减的顺序排列各工件,所得工件排列即为输出结果。
感觉这个算法没啥道理,也许在原文献中能够看出设计这个公式的起因吧。
(3)算法示例
Job Id |
J1 |
J2 |
J3 |
J4 |
J5 |
M1 |
11 |
8 |
10 |
5 |
12 |
M2 |
7 |
2 |
9 |
9 |
9 |
M3 |
13 |
8 |
13 |
10 |
13 |
M4 |
12 |
7 |
11 |
10 |
9 |
(1)
由步骤1得到工件1、2、3、4和5的斜度指标分别为-0.056,0.1,-0.053,-0.071和0.048。
(2)
按照斜度指标排序得到排列为π={4,1,3,5,2},其最大完成时间为79,具体调度方案如下:
工序 |
作业 |
开工时间 |
完工时间 |
1 |
4 |
0 |
5 |
1 |
1 |
5 |
16 |
1 |
3 |
16 |
26 |
1 |
5 |
26 |
38 |
1 |
2 |
38 |
46 |
2 |
4 |
5 |
14 |
2 |
1 |
16 |
23 |
2 |
3 |
26 |
35 |
2 |
5 |
38 |
47 |
2 |
2 |
47 |
49 |
3 |
4 |
14 |
24 |
3 |
1 |
24 |
37 |
3 |
3 |
37 |
50 |
3 |
5 |
50 |
63 |
3 |
2 |
63 |
71 |
4 |
4 |
24 |
34 |
4 |
1 |
37 |
49 |
4 |
3 |
50 |
61 |
4 |
5 |
63 |
72 |
4 |
2 |
72 |
79 |
优化问题是指在满足一定条件下,在众多方案或参数值中寻找最优方案或参数值,以使得某个或多个功能指标达到最优,
或使系统的某些性能指标达到最大值或最小值。优化问题广泛地存在于信号处理、图像处理、生产调度、任务分配、模式识别、自动控制 和机械设计等众多领域。优化方法是一种以数学为基础,用于求解各种优化问题的应用技术。各种优化方法在上述领域得到了广泛应用,
并且已经产生了巨大的经济效益和社会效益。实践证明,通过优化方法,能够提高系统效率,降低能耗,合理地利用资源,并且随着处理对象规模的增加, 这种效果也会更加明显。
在电子、通信、计算机、自动化、机器人、经济学和管理学等众多学科中,不断地出现了许多复杂的组合优化问题。
面对这些大型的优化问题,传统的优化方法(如牛顿法、单纯形法等)需要遍历整个搜索空间,无法在短时间内完成搜索,且容易产生搜索的“组合爆炸”。 例如,许多工程优化问题,往往需要在复杂而庞大的搜索空间中寻找最优解或者准最优解。鉴于实际工程问题的复杂性、非线性、约束性以及建模困难等
诸多特点,寻求高效的优化算法已成为相关学科的主要研究内容之一。
受到人类智能、生物群体社会性或自然现象规律的启发,人们发明了很多智能优化算法来解决上述复杂优化问题,主要包括:模仿自然界生物进化机制的遗传算法;通过群体内个体间的合作与竞争来优化搜索的差分进化算法;模拟生物免疫系统学习和认知功能的免疫算法;模拟蚂蚁集体寻径行为的蚁群算法;模拟鸟群和鱼群群体行为的粒子群算法;源于固体物质退火过程的模拟退火算法;模拟人类智力记忆过程的禁忌搜索算法;模拟动物神经网络行为特征的神经网络算法;等等。这些算法有个共同点,即都是通过模拟或揭示某些自然界的现象和过程或生物群体的智能行为而得到发展;在优化领域称它们为智能优化算法,它们具有简单、通用、便于并行处理等特点。
(1)算法简介
模拟退火算法(Simulated Annealing,SA)最早的思想是由N. Metropolis等人于1953年提出。1983 年,S. Kirkpatrick 等成功地将退火思想引入到组合优化领域。它是基于Monte-Carlo迭代求解策略的一种随机寻优算法,其出发点是基于物理中固体物质的退火过程 与一般组合优化问题之间的相似性。模拟退火算法从某一较高初温出发,伴随温度参数的不断下降,结合概率突跳特性在解空间中随机寻找目标函数 的全局最优解,即在局部最优解能概率性地跳出并最终趋于全局最优。模拟退火算法是一种通用的优化算法,理论上算法具有概率的全局优化性能, 目前已在工程中得到了广泛应用,诸如VLSI、生产调度、控制工程、机器学习、神经网络、信号处理等领域。
(2)算法基本原理
模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大, 而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。
根据Metropolis准则,粒子在温度T时趋于平衡的概率为e(-ΔE/(kT)),其中E为温度T时的内能,ΔE为其改变量,k为Boltzmann常数。
用固体退火模拟组合优化问题,将内能E模拟为目标函数值f,温度T演化成控制参数t,即得到解组合优化问题的模拟退火算法步骤: 由初始解i和控制参数初值t开始,对当前解重复“产生新解→计算目标函数差→接受或舍弃”的迭代,并逐步衰减t值, 算法终止时的当前解即为所得近似最优解,这是基于蒙特卡罗迭代求解法的一种启发式随机搜索过程。 退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件S。
(3)算法流程
模拟退火算法计算流程如下:
Step1:初始温度Temp(充分大),初始解rt1(是算法迭代的起点),最多迭代外温次数outLoopNum,降温速度a;
Step2:对k=1, …, inLoopNum进行下列运算:
Step2.1:产生新解rt2;
Step2.2:计算增量deltF=F(rt2)-F(rt1),其中F()为评价函数,即优化问题目标函数的值;
Step2.3:若deltDist<0则接受rt2作为新的当前解,否则以概率exp(-deltF/Temp)接受rt2作为新的当前解;
Step3:利用Temp=a*Temp降低温度,其中a取值范围(0,1);
Step4:判断是否满足算法终止条件(连续N个温度计算后没能获得更好的解),满足则输出当前解作为最优解,结束程序;不满足继续Step2。
图 模拟退火算法流程图
(1)算法简介
遗传算法(Genetic
Algorithm,GA)最早是由美国的 John holland于20世纪70年代提出, 该算法是根据大自然中生物体进化规律而设计提出的。是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,
是一种通过模拟自然进化过程搜索最优解的方法。该算法通过数学的方式,利用计算机仿真运算,将问题的求解过程转换成类似生物 进化中的染色体基因的交叉、变异等过程。在求解较为复杂的组合优化问题时,相对一些常规的优化算法,通常能够较快地获得较好 的优化结果。1975年, J. Holland等提出了对遗传算法理论研究极为重要的模式理论,出版了专著《自然系统和人工系统的适配》, 在书中系统阐述了遗传算法的基本理论和方法,推动了遗传算法的发展。20世纪80年代后,遗传算法进入兴盛发展时期, 当前,遗传算法已被人们广泛地应用于组合优化、机器学习、信号处理、自适应控制和人工生命等领域。
(2)算法基本原理
遗传算法是一种基于自然选择和群体遗传机理的搜索算法,它模拟了自然选择和自然遗传过程中的繁殖、杂交和突变现象. 再利用遗传算法求解问题时,问题的每一个可能解都被编码成一个“染色体”,即个体,若干个个体构成了群体(所有可能解). 在遗传算法开始时,总是随机的产生一些个体(即初始解),根据预定的目标函数对每一个个体进行评估,给出一个适应度值, 基于此适应度值,选择一些个体用来产生下一代,选择操作体现了“适者生存”的原理,“好”的个体被用来产生下一代, “坏”的个体则被淘汰,然后选择出来的个体,经过交叉和变异算子进行再组合生成新的一代,这一代的个体由于继承了上一代的一 些优良性状,因而在性能上要优于上一代,这样逐步朝着最优解的方向进化.因此,遗传算法可以看成是一个由可行解组成的群体初步进化的过程。
(3)算法流程
遗传算法计算流程如下:
Step1:初始化:设置进化代数计数器t=0,设置最大进化代数T,随机生成M个个体作为初始群体P(0)。
Step2:个体评价:计算群体P(t)中各个个体的适应度。
Step3:选择运算:将选择算子作用于群体。选择的目的是把优化的个体直接遗传到下一代 或通过配对交叉产生新的个体再遗传到下一代。选择操作是建立在群体中个体的适应度评估基础上的。]
Step4:交叉运算:将交叉算子作用于群体。遗传算法中起核心作用的就是交叉算子。
Step5:变异运算:将变异算子作用于群体。即是对群体中的个体串的某些基因座上的基因值作变动。 群体P(t)经过选择、交叉、变异运算之后得到下一代群体P(t+1)。
Step6:终止条件判断:若t=T,则以进化过程中所得到的具有最大适应度个体作为最优解输出,终止计算。
(4)算法要点
编码:由于遗传算法不能直接处理问题空间的参数,因此必须通过编码将要求解的问题表示成遗传空间的染色体或者个体。
这一转换操作就叫做编码,也可以称作(问题的)表示(representation)。针对不同的问题需要选用合适的编码方式,常见的编码方式
有:二进制编码、整数编码、实数编码等。
终止条件:当最优个体的适应度达到给定的阈值,或者最优个体的适应度和群体适应度不再上升时, 或者迭代次数达到预设的代数时,算法终止。预设的代数一般设置为100-500代。
操作算子:遗传操作包括以下三个基本遗传算子(genetic operator):选择(selection);交叉(crossover);变异(mutation)。
选择算子:从群体中选择优胜的个体,淘汰劣质个体的操作叫选择。选择算子有时又称为再生算子(reproduction operator)。选择的目的是把优化的个体(或解)直接遗传到下一代或通过 配对交叉产生新的个体再遗传到下一代。选择操作是建立在群体中个体的适应度评估基础上的,常用的选择算子有以下几种:
适应度比例方法、随机遍历抽样法、局部选择法。
交叉算子:在自然界生物进化过程中起核心作用的是生物遗传基因的重组(加上变异)。同样,遗传算法中起核心作用的 是遗传操作的交叉算子。所谓交叉是指把两个父代个体的部分结构加以替换重组而生成新个体的操作。通过交叉,遗传算法的搜索能力
得以飞跃提高。
变异算子:变异算子的基本内容是对群体中的个体串的某些基因位上的基因值作变动。 遗传算法引入变异的目的有两个:一是使遗传算法具有局部的随机搜索能力。当遗传算法通过交叉算子已接近最优解邻域时,利用变异算子的这种局部随机搜索能力可以加速向最优解收敛。显然,此种情况下的变异概率应取较小值,否则接近最优解的积木块会因变异而遭到破坏。二是使遗传算法可维持群体多样性,以防止出现未成熟收敛现象。此时收敛概率应取较大值。
(1)算法简介
蚁群系统(Ant
System或Ant Colony System)是由意大利学者Dorigo、Maniezzo等人于20世纪90年代首先提出来的。 他们在研究蚂蚁觅食的过程中,发现单个蚂蚁的行为比较简单,但是蚁群整体却可以体现一些智能的行为。例如蚁群可以在不同的环境下,寻找最短到达食物源的路径。这是因为蚁群内的蚂蚁可以通过某种信息机制实现信息的传递。后又经进一步研究发现,
蚂蚁会在其经过的路径上释放一种可以称之为“信息素”的物质,蚁群内的蚂蚁对“信息素”具有感知能力,它们会沿着“信息素”浓度较高路径行走, 而每只路过的蚂蚁都会在路上留下“信息素”,这就形成一种类似正反馈的机制,这样经过一段时间后,整个蚁群就会沿着最短路径到达食物源了。
蚁群算法(Ant
Clony Optimization, ACO)是一种群智能算法,它是由一群无智能或有轻微智能的个体(Agent)通过 相互协作而表现出智能行为,从而为求解复杂问题提供了一个新的可能性。蚁群算法是一种用来寻找优化路径的概率型算法。它由Marco Dorigo于 1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。蚁群算法是一种模拟进化算法,初步的研究表明该算法
具有许多优良的性质。
(2)算法基本原理
将蚁群算法应用于解决优化问题的基本思路为:用蚂蚁的行走路径表示待优化问题的可行解,整个蚂蚁群体的所有路径构成待优化问题的解空间。 路径较短的蚂蚁释放的信息素量较多,随着时间的推进,较短的路径上累积的信息素浓度逐渐增高,选择该路径的蚂蚁个数也愈来愈多。
最终,整个蚂蚁会在正反馈的作用下集中到最佳的路径上,此时对应的便是待优化问题的最优解。
蚂蚁找到最短路径要归功于信息素和环境,假设有两条路可从蚁窝通向食物,开始时两条路上的蚂蚁数量差不多: 当蚂蚁到达终点之后会立即返回,距离短的路上的蚂蚁往返一次时间短,重复频率快,在单位时间里往返蚂蚁的数目就多,留下的信息素也多,
会吸引更多蚂蚁过来,会留下更多信息素。而距离长的路正相反,因此越来越多的蚂蚁聚集到最短路径上来。
蚂蚁具有的智能行为得益于其简单行为规则,该规则让其具有多样性和正反馈。在觅食时,多样性使蚂蚁不会走进死胡同而无限循环, 是一种创新能力;正反馈使优良信息保存下来,是一种学习强化能力。两者的巧妙结合使智能行为涌现,如果多样性过剩,系统过于活跃,
会导致过多的随机运动,陷入混沌状态;如果多样性不够,正反馈过强,会导致僵化,当环境变化时蚁群不能相应调整。 退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件S。
(3)算法流程
蚁群算法计算流程【以TSP问题为例】如下:
step1:对相关参数进行初始化,包括蚁群规模、信息素因子、启发函数因子、信息素挥发因子、信息素常数、最大迭代次数等, 以及将数据读入程序,并进行预处理:比如将城市的坐标信息转换为城市间的距离矩阵。
step2:随机将蚂蚁放于不同出发点,对每个蚂蚁计算其下个访问城市,直到有蚂蚁访问完所有城市。
step3:计算各蚂蚁经过的路径长度Lk,记录当前迭代次数最优解,同时对路径上的信息素浓度进行更新。
step4:判断是否达到最大迭代次数,若否,返回步骤2;是,结束程序。
step5:输出结果,并根据需要输出寻优过程中的相关指标,如运行时间、收敛迭代次数等。
(4)算法要点
蚂蚁数量:设n表示城市数量,m表示蚂蚁数量。m的数量很重要,因为m过大时,会导致搜索过的路径上信息素变化趋于平均, 这样就不好找出好的路径了;m过小时,易使未被搜索到的路径信息素减小到0,这样可能会出现早熟,没找到全局最优解。一般上,在时间等资源条件紧迫的情况下,蚂蚁数设定为城市数的1.5倍较稳妥。
信息素因子:信息素因子反映了蚂蚁在移动过程中所积累的信息量在指导蚁群搜索中的相对重要程度,其值过大,蚂蚁选择以前走过的路径概率大, 搜索随机性减弱;值过小,等同于贪婪算法,使搜索过早陷入局部最优。实验发现,信息素因子选择[1,4]区间,性能较好。
启发函数因子:启发函数因子反映了启发式信息在指导蚁群搜索过程中的相对重要程度,其大小反映的是蚁群寻优过程中先验性和确定性因素的作用强度。 过大时,虽然收敛速度会加快,但容易陷入局部最优;过小时,容易陷入随机搜索,找不到最优解。实验研究发现,当启发函数因子为[3,4.5]时,综合求解性能较好。
信息素挥发因子:信息素挥发因子表示信息素的消失水平,它的大小直接关系到蚁群算法的全局搜索能力和收敛速度。实验发现,当属于[0.2,0.5]时,综合性能较好。
信息素常数:这个参数为信息素强度,表示蚂蚁循环一周时释放在路径上的信息素总量,其作用是为了充分利用有向图上的全局信息反馈量, 使算法在正反馈机制作用下以合理的演化速度搜索到全局最优解。值越大,蚂蚁在已遍历路径上的信息素积累越快,有助于快速收敛。
实验发现,当值属于[10,1000]时,综合性能较好。
最大迭代次数:最大迭代次数值过小,可能导致算法还没收敛就已结束;过大则会导致资源浪费。一般最大迭代次数可以取100到500次。 一般来讲,建议先取200,然后根据执行程序查看算法收敛的轨迹来修改取值。。
(1)算法简介
粒子群优化(Particle
Swarm Optimization, PSO)算法是Kennedy和Eberhart受人工智能研究结果的启发、 通过模拟鸟群觅食过程中的迁徙和群聚行为而提出的一种基于群体智能的全局随机搜索算法,自然界中各种生物体均具有一定的群体行为,
而人工智能的主要研究领域之一是探索自然界生物的群体行为,从而在计算机上构建其群体模型。自然界中的鸟群和鱼群的群体行为一直是科学家的研究兴趣, 生物学家Craig Reynolds在1987年提出了一个非常有影响的鸟群聚集模型,在他的仿真中,每一个个体遵循:
(i)避免与邻域个体相冲撞; (ii)匹配邻域个体的速度; (iii)飞向鸟群中心,且整个群体飞向目标。 仿真中仅利用上面三条简单的规则,就可以非常接近的模拟出鸟群飞行的现象。1995年,美国社会心理学家James Kennedy和电气工程师Russell Eberhart共同提出了粒子群算法, 其基本思想是受对鸟类群体行为进行建模与仿真的研究结果的启发。他们的模型和仿真算法主要对Frank Heppner的模型进行了修正,以使粒子飞向解空间并在最好解处降落。
(2)算法基本原理
PSO从这种模型中得到启示并用于解决优化问题。PSO
中,每个优化问题的潜在解都是搜索空间中的一只鸟,称之为粒子。 所有的粒子都有一个由被优化的函数决定的适值( fitness
value) ,每个粒子还有一个速度决定它们飞翔的方向和距离。然后粒子们就追随当前的最优粒子在解空间中搜索。 PSO初始化随机初始化一群随机粒子,每个粒子表示问题的一个解,然后通过迭代找到最优解。在每一次迭代中,粒子通过跟踪两个“极值”来更新自己: (1)粒子本身所找到的最好解,即个体极值(pbest) (2)整个粒子群中所有粒子在历代搜索过程中所达到的最优解(gbest)即全局极值。 找到这两个最好解后,接下来是PSO中最重要的“加速”过程,每个粒子不断地改变其在解空间中的速度,以尽可能地朝pbest和gbest所指向的区域“飞”去。
(3)算法流程
粒子群算法的计算流程如下:
Step1:根据变量个数N和粒子数量pop,利用rand函数生成二维数组X[pop, N]和速度数组V[pop, N]
Step2:利用适应度函数求得各个X的解fit[pop],记录每个粒子的最好解particleBest[pop]和群体的最好解groupBest,并记录对应的解集particleBestX[pop,N]
Step3:运用迭代公式更新X和V,再继续Step2,直至结束。
参数有动能惯性系数、个体学习系数、群体学习系数、种群规模、最大迭代代数、无更新终止代数。
(1)算法简介
Rao2016开发了一种使用简单,不需要任何算法参数调试的教学算法Teaching Learning Based Optimization(TLBO)。TLBO算法描述了两种基本的学习模式:(i)通过教师学习,(ii)通过与其他学生交互的学习,这两个模式分别命名为教师阶段和学习者阶段。此算法包含一群学生,并给每个学生安排了不同的课程,这些课程为优化问题的设计变量,学生的成绩类似于优化问题的适应度。学生群体的最好学习结果被视为教师。
设计变量其实是优化问题目标函数中包含的参数,最优结果是目标函数的最优结果。
(2)算法基本原理
基于教学的优化(TLBO)是一种模拟课堂教学过程的基于群体的优化方法。TLBO分为两部分。第一部分是“教师阶段”,即向教师学习;
第二部分是“学习者阶段”,即通过学习者之间的互动进行学习。在TLBO中,种群被视为一类学习者。每个学习者代表优化问题的一个可能的解决方案, 分数代表适应度值。老师被认为是迄今为止得到的最好的解决办法。
(3)算法流程
教学算法的计算流程如下:
Step1:数据初始化
Step2:种群初始化-也就是班级的学生初始化,类似于遗传算法中的染色体种群初始化
这里采用实数编码的形式进行编码,实数数量=sum(作业工序数),有多少作业工序就有多少个实数变量。加入有作业A1、A2、B1、B2、B3, 即有两个作业A和B,分别有2个和三个工序,则编码长度为5,由5个实数组成,实数取值范围限定在[0,b]之间,通常将其限定在[0,1]之间, 当然b也可以设定一个比较大的正整数,例如10,如果形成了一个如下的编码:
8.6434 1.6972 0.8544 2.0878 1.1762
则根据数字的大小进行解码,最小的为A1、次之A2、……、最大的代表B3,则上述实数编码转换为作业编码如下:
B3 B1 A1 B2 A2
Step3:循环运算
Step3.1:识别群体中最好的学生和计算班级各科平均成绩
Step3.2:根据公式(1)、(2)、(3)更新全部学生的全部科目成绩;
Step3.3:随机选择两个学生,然后利用公式(6)和(7)进行一个学生的成绩更新;
Step3.4:算法终止条件成立否,如成立,则执行Step4;否则执行Step3.1,继续循环
Step4:算法结束,进行统计和给出结果。
注:其中的公式请参考Rao2016年出版的书籍《Teaching Learning
Based Optimization Algorithm And Its Engineering Applications》。
easyopt.chart包中主要包含了车间智能调度优化计算中所涉及的图形展示类和方法。easyopt.chart包中的类及其功能如下表。
类名 |
功能说明 |
GantChart |
根据传入的调度数据绘制车间调度方案甘特图 |
OptSeriesChart |
根据传入的多组优化算法进化数据绘制进化曲线 |
GantChart类主要封装了根据调度数据绘制甘特图的方法,其构造函数如下:
public
GantChart(double[][] sch) 构造函数,输入参数为二维调度方案数组,其中第一列为作业编号,第二列机器编号,第三列工序编号,第四列开工时间
第五列完工时间...,其中作业编号和机器编号都从1开始编码 |
例(1):假设车间有调度方案如下表所示,使用GantChart类绘制对应的甘特图。
jobId |
machId |
procId |
startTime |
endTime |
1 |
1 |
1 |
0 |
13 |
2 |
2 |
1 |
0 |
27 |
3 |
3 |
1 |
0 |
16 |
4 |
1 |
1 |
13 |
36 |
1 |
2 |
2 |
27 |
41 |
2 |
3 |
2 |
27 |
46 |
3 |
1 |
2 |
36 |
49 |
4 |
2 |
2 |
41 |
46 |
1 |
3 |
3 |
46 |
58 |
2 |
1 |
3 |
49 |
59 |
1 |
2 |
4 |
58 |
75 |
代码设计如下:
package easyopt.example; import easyopt.chart.GantChart; public class Example_Chart_GantChart { public static void main(String[] args) { double[][] sch =
{{1,1,1,0,13},{2,2,1,0,27},{3,3,1,0,16},{4,1,1,13,36},{1,2,2,27,41},{2,3,2,27,46},{3,1,2,36,49},{4,2,2,41,46},{1,3,3,46,58},{2,1,3,49,59},{1,2,4,58,75}}; GantChart
schGant =new GantChart(sch); schGant.drawGant(); } } |
执行结果如下图所示:
在上述甘特图中,如果鼠标进入对应的色块,将采取比较具体的方式显示该色块详细调度信息,鼠标离开该色块,则使用简要方式显示该色块的详细调度信息。
OptSeriesChart类主要封装了用于绘制优化算法寻优进化曲线的方法,其构造函数如下:
public
OptSeriesChart(double[][] optSeriesArr) 参数: optSeriesArr - row is the quantity of
samples[points], column is the quantity of series |
例(1):假设采用特定优化算法对某个完工时间最小的车间调度问题优化求解,在进化前20代记录的当前代最优解如下表,
generation |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
fitVal |
809 |
760 |
728 |
581 |
669 |
521 |
618 |
586 |
545 |
551 |
generation |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
fitVal |
497 |
493 |
480 |
528 |
450 |
323 |
386 |
396 |
324 |
387 |
程序设计如下:
package
easyopt.example; import
easyopt.chart.OptSeriesChart; public class
Example_Chart_OptSeriesChart { public static void
main(String[] args) { double[][]
optData=
{{809},{660},{728},{581},{669},{521},{618},{586},{545},{551},{497},{493},{480},{528},{450},{323},{386},{396},{324},{387}}; OptSeriesChart
optChart=new OptSeriesChart(optData); optChart.drawLine(); } } |
执行结果如下图所示:
在上述收敛曲线中,绿色线条为截止当前代数的最优解,红色为当前代计算的最优解,如果鼠标进入对应代数的纵轴范围,将显示进化到该代数时对应的当前代数最优解和截止当前代数的全局最优解。
例(2):假设当前有两种优化算法对同一问题进行优化求解,这两种算法前20步算法的最优结果如下表所示,试利用OptSeriesChart绘制进化曲线图。
generation |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
fitVal1 |
852 |
764 |
641 |
674 |
703 |
715 |
674 |
719 |
662 |
683 |
fitVal2 |
925 |
898 |
666 |
639 |
586 |
584 |
538 |
544 |
599 |
577 |
generation |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
fitVal1 |
718 |
659 |
654 |
584 |
559 |
549 |
475 |
486 |
505 |
521 |
fitVal2 |
501 |
533 |
612 |
544 |
591 |
598 |
559 |
505 |
453 |
436 |
程序设计如下:
package
easyopt.example; import
easyopt.chart.OptSeriesChart; public class
Example_Chart_OptSeriesChart { public static void
main(String[] args) { double[][]
optData= {{852,925},{764,898},{641,666},{674,639},{703,586},{715,584},{674,538},{719,544},{662,599},{683,577},{718,501},{659,533},{654,612},{584,544},{559,591},{549,598},{475,559},{486,505},{505,453},{521,436},{503,453}}; OptSeriesChart
optChart=new OptSeriesChart(optData); optChart.drawLine(); } } |
程序执行结果如下:
easyopt.common包中主要包含了车间智能调度优化计算中所涉及的通用类和方法包,主要有各类算法类、数组转换、查找、排序类等,主要是将优化计算过程中涉及的通用方法进行包装。easyopt.common包中的类及其功能如下表。
类名 |
功能说明 |
ACO |
蚁群算法运算过程中涉及的相关方法 |
GA |
遗传算法运算过程中涉及的相关方法 |
EasyArray |
数组计算过程中可能涉及的各类处理方法 |
EasyMath |
运算过程中可能涉及到的数学处理方法 |
PSO |
蚁群算法运算过程中涉及的相关方法 |
Rules |
车间调度过程中一些常见的规则排产运算方法 |
TLBO |
教学算法运算过程中涉及的相关方法 |
EasyMath类主要封装了一些车间调度运算过程中涉及的数学计算方法,这些方法都定义为静态方法,在运算过程中可以直接调用,而不需要定义对象。该类中主要包含运算过程中经常使用的方法是数组排序sortArray和生产随机编码randPerm两类方法。
在EasyMath类中包装了针对整数二维数组和实数二维数组两类数据排序的方法,排序可以指定特定的几列进行升序或降序排列。
例(1)对一个数组arr按照第1列升序排序:
EasyMath.sortArray(arr, new int[]{0});//int[]{0}中大括号中的数字表示排序的列序号
排序前 |
排序后 |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
例(2)对一个数组arr按照第2列降序排序:
EasyMath.sortArray(arr, new int[]{-1});//如果大括号中的数字为负数,则表示对该列进行降序排序
排序前 |
排序后 |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
例(3)对一个数组arr按照第1列升序且第2列降序排序:
EasyMath.sortArray(arr, new int[]{0,,-1});
排序前 |
排序后 |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
优化计算中通常需要产生一个初始编码,以表示一个解。
这个随机编码或者由0-1数字组成的数组,例如[0 1 0 1 0 1 1 1 1 1 1 0 0 0],该数组中每个位置的数字或为0或为1;或者由0到n之间数字的乱序组成的数组,例如对n为6的一种排序[0 1 4 6 5 3
2],该数组中每个位置的数字必然为0-6之间的一个数字,而且不重复,不遗漏;或者由1到n之间数字的乱序组成的数组,例如对n为6的一种排序[1 4 6 5 3 2],该数组中每个位置的数字必然为1-6之间的一个数字,而且不重复,不遗漏。
这三类实现分别由EasyMath类中的三个静态方法rand0_1Perm(int len)、randPerm(int len)和randPermStart1(int len)实现。
例(1)
int[] arr1 = EasyMath.rand0_1Perm(10);
可能产生一个长度为10的随机整数数组arr1={1,0,1,0,0,0,1,1,0,0},因为随机生成,每次获得的结果极有可能不一样,但是数组的特点是确定的。
例(2)
int[] arr2 = EasyMath.randPerm(10);
可能产生一个长度为10的随机整数数组arr2={0,5,4,8,7,9,2,3,6,1}。
例(3)
int[] arr3 = EasyMath.randPermStart1(10);
可能产生一个长度为10的随机整数数组arr3={9,2,3,10,5,4,8,1,7,6}。
EasyArray类主要封装了一些数组转换或输出的方法。
EasyArray类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
arrayAdd 实现将第二个数组接到第一个数组后面形成一个新的数组 |
|
arrayAdd 实现将第二个数组接到第一个数组后面形成一个新的数组 |
|
arrayDelete 根据第二个参数中的值是否为1决定是否保留第一个参数中的行向量 |
|
arrayDelete 根据第二个参数中的值是否为1决定是否保留第一个参数中的行向量 |
|
changeStr2Double2 将字符串转变为二维实数数组,数值之间由分号和空格分割开 |
|
changeStr2Double1 将字符串转变为二维实数数组,数值之间由分号和空格分割开 |
|
changeStr2Int1 将字符串转变为一维整数数组,数值之间由空格分割开 |
|
changeStr2Int2 将字符串转变为二维整数数组,数值之间由分号和空格分割开 |
|
getJobQty 根据cycleTimeStr中的数据获取作业的数量,数值之间由分号和/或空格分割开。对于并行机问题来说,全部的作业时间为一行字符串,数字之间用空格分隔开;
对于流水车间或作业车间调度问题来说,不同作业的工序加工时间之间用分号;隔开;根据cycleTimeStr这个字符串来获得作业的数量 |
|
printArray 将一维数组打印出来 |
|
printArray 将二维数组打印出来 |
|
printArray 将一维数组打印出来 |
|
printArray 将二维数组打印出来,符合制作甘特图的形式 |
|
printSchedule 将二维数组打印出来,符合制作甘特图的形式 |
车间调度优化问题通常需要输入各项作业的工艺工时数据,例如4个作业5道工序的置换流水车间调度问题,要进行排产优化,至少需要录入如下表所示各项作业在每道工序的作业时间。
JobId |
Process1 |
Process2 |
Process3 |
Process4 |
Process5 |
J1 |
22 |
15 |
23 |
23 |
22 |
J2 |
14 |
22 |
24 |
15 |
12 |
J3 |
15 |
11 |
13 |
20 |
15 |
J4 |
24 |
19 |
14 |
24 |
15 |
使用者输入这个四行五列数据时可以采取一种比较简单转换方式将其转换为下列的字符串:
22 15 23 23 22;14 22 24 15 12;15 11 13 20 15;24 19 14 24 15
不同作业工时数据采用分号分割开,同一作业不同工序之间的作业工时使用空格分隔开。调度计算程序在接收到这个字符串之后,需要将字符串转换成二维数组,以便于后续调度计算。为了方便进行这种从字符串工艺工时数据转换为二维数组或一维数组的工艺工时数据,EasyArray类中设计了changeStr2Double1、changeStr2Double2、changeStr2Int1、changeStr2Int2。
在进行多目标优化计算过程中,需要从原始解集中保留非支配解,或者需要将两个解集合并起来以便检索新解集中的非支配解,这就需要程序能够进行数组的合并和删除。EasyArray类中设计针对二维实数和整数数组处理的数组合并和删除方法:arrayAdd和arrayDelete。
为了将二维数组按照分行的方式显示出来,一维数组在单行显示出来,设计了针对一维/二维的整数和实数数组内容输出的方法printArray。
以二维实数数组为例,演示字符串转换为二维数组、二维数组合并和删除以及二维数组分行打印方法的使用。
String str1 ="22 15 23 23 22;14 22 24 15 12;15 11 13 20 15;24 19
14 24 15"; double[][] data1 = EasyArray.changeStr2Double2(str1); System.out.println("-----------data1's content----------"); EasyArray.printArray(data1); String str2 ="20 18 17 23 5;20 5 8 5 15"; double[][] data2 = EasyArray.changeStr2Double2(str2); System.out.println("-----------data2's content----------"); EasyArray.printArray(data2); double[][] data3 = EasyArray.arrayAdd(data1, data2); System.out.println("-----------data3's content----------"); EasyArray.printArray(data3); int[] isRetain = {1,1,1,0,0,1}; double[][] data4 =EasyArray.arrayDelete(data3, isRetain); System.out.println("-----------data4's content----------"); EasyArray.printArray(data4); |
运行结果如下:
-----------data1's content---------- 22.0 15.0 23.0 23.0 22.0
; 14.0 22.0 24.0 15.0 12.0
; 15.0 11.0 13.0 20.0 15.0
; 24.0 19.0 14.0 24.0 15.0
; -----------data2's content---------- 20.0 18.0 17.0 23.0 5.0
; 20.0 5.0 8.0 5.0 15.0 ; -----------data3's content---------- 22.0 15.0 23.0 23.0 22.0
; 14.0 22.0 24.0 15.0 12.0
; 15.0 11.0 13.0 20.0 15.0
; 24.0 19.0 14.0 24.0 15.0
; 20.0 18.0 17.0 23.0 5.0
; 20.0 5.0 8.0 5.0 15.0 ; -----------data4's content---------- 22.0 15.0 23.0 23.0 22.0
; 14.0 22.0 24.0 15.0 12.0
; 15.0 11.0 13.0 20.0 15.0
; 20.0 5.0 8.0 5.0 15.0 ; |
其中data4是将data3的数据根据isRetain中值为0的行数据删除后的结果。
GA类主要封装了一些遗传算法运算中涉及的方法,主要包括遗传算法中的初始化种群和运算算子。
GA类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
crossOX 遗传算法交叉操作:按照一定概率进行种群交叉操作操作,两点间基因片段【次序交叉】,具体规则参考
“次序交叉”或“Order
Crossover”相关资料 |
|
crossPBX 遗传算法交叉操作:按照一定概率进行种群交叉操作操作,两点间基因片段【基于位置的交叉】,具体规则参考
“基于位置交叉”或“Position-based
Crossover”相关资料 |
|
initBitChrome 根据种群规模和基因长度初始化二进制染色体种群 |
|
initJSP1Chrome 根据种群规模、作业数量、机器数量初始化machQty个[1-jobQty]之间整数乱序的染色体种群,主要用于解决
作业车间调度问题 |
|
initSequence1Chrome 根据种群规模和基因长度初始化1-geneLength之间整数乱序的染色体种群,主要用于解决 车间调度、TSP问题和VRP问题方面 |
|
initSequenceChrome 根据种群规模和基因长度初始化0-[geneLength-1]之间整数乱序的染色体种群,主要用于解决 车间调度、TSP问题和VRP问题方面 |
|
muteBit 按照一定概率进行种群变异操作,【0-1变异】 |
|
muteTwoPointReverse 按照一定概率进行种群变异操作,两点间基因片段【逆序变异】 |
|
muteTwoPointSwap 按照一定概率进行种群变异操作,【两点互换变异】 |
|
selectionElistMin 针对最小化目标函数优化问题,基于精英保留策略进行染色体选择,从而形成下代种群 |
|
selectionRoulletMax 针对最大化目标函数,基于轮盘赌策略进行染色体选择,从而形成下代种群 |
|
selectionRoulletMin 针对最小化目标函数,基于轮盘赌策略进行染色体选择,从而形成下代种群 |
GA类封装的初始化种群方法主要有:initBitChrome、initJSP1Chrome、initSequence1Chrome和initSequenceChrome四个方法。
例:
int[][] chrome1 = GA.initBitChrome(5,
20); System.out.println("----------chrome1's content-----------"); EasyArray.printArray(chrome1); int[][] chromeSeq0 =GA.initSequenceChrome(5,
20); System.out.println("----------chromeSeq0's content-----------"); EasyArray.printArray(chromeSeq0); int[][] chromeSeq1 =GA.initSequence1Chrome(5,
20); System.out.println("----------chromeSeq1's content-----------"); EasyArray.printArray(chromeSeq1); int[][] chromeSeqJSP = GA.initJSP1Chrome(5,
6, 4); System.out.println("----------chromeSeqJSP's content-----------"); EasyArray.printArray(chromeSeqJSP); |
执行结果:
----------chrome1's content----------- 0 1 1 1 0 0 0 0 1 0 0 0
0 0 1 1 0 1 0 1 ; 1 1 1 1 0 1 1 0 0 0 1 0
0 1 1 1 1 0 0 0 ; 0 1 0 1 1 1 1 0 0 1 1 1
1 1 1 0 0 0 0 1 ; 1 0 0 1 0 1 0 0 1 0 1 0
1 1 0 1 1 1 0 0 ; 1 1 1 0 1 1 0 0 1 0 0 1
1 1 0 1 1 1 0 0 ; ----------chromeSeq0's
content----------- 10 17 19 9 12 11 15 8 1
4 3 16 5 2 13 6 14 7 18 0 ; 7 5 1 13 11 0 19 4 16 14
2 18 10 8 12 9 6 15 17 3 ; 4 9 14 17 12 1 15 6 3 11
13 7 10 19 18 2 8 0 5 16 ; 0 11 1 2 16 4 5 18 8 10
6 19 7 9 17 13 15 14 3 12 ; 2 0 14 7 15 5 1 4 11 10
19 6 18 8 13 3 16 9 17 12 ; ----------chromeSeq1's
content----------- 20 15 18 7 12 8 17 5 2
1 10 4 3 13 6 16 19 9 14 11 ; 3 10 9 13 14 18 15 19 7
5 1 11 2 6 20 8 12 16 4 17 ; 11 7 14 18 16 20 17 15
1 9 19 10 8 5 2 6 4 3 12 13 ; 11 5 6 3 8 20 9 19 15 16
13 7 1 12 4 2 17 10 18 14 ; 20 6 11 12 7 19 15 8 16
13 3 2 5 9 10 4 1 18 17 14 ; ----------chromeSeqJSP's
content----------- 2 2 3 5 2 5 4 6 4 4 6 3
4 6 1 6 1 3 5 5 1 3 2 1 ; 6 3 2 3 2 1 4 6 5 1 3 5
1 4 4 1 2 5 2 3 4 5 6 6 ; 6 5 3 3 1 3 4 2 2 1 1 6
4 6 5 6 1 5 4 3 4 5 2 2 ; 2 5 2 3 6 1 6 5 3 4 3 1
6 4 5 4 3 2 4 1 2 1 5 6 ; 5 4 2 4 1 2 6 1 5 6 2 6 3 3 5 3 4 4 2 3 1 5
1 6 ; |
由于各个方法是根据输入参数随机产生种群,所以每次执行的结果可能不同,但是结果数据的特征是固定的。
其中:
chrome1中每个位置上的数值或者为0,或者为1;
chrome2中每行数据必然是0到19【方法第二个参数减一】这二十个整数的随机乱序;
chrome3中每行数据必然是1到20【方法第二个参数】这二十个整数的随机乱序;
chrome4中每行必然出现的1、2、…、5、6【方法的第二个参数确定】这六个数字必然都出现4【方法的第三个参数确定】次。
GA类封装的选择算子方法主要有针对最小化问题的精英保留算子和轮盘赌算子以及最大化问题的轮盘赌算子,分别命名为:selectionElistMin、selectionRoulletMin和selectionRoulletMax。由于选择算子同各条染色体对应的目标函数值相关,相同染色体对不同问题的目标函数结果也不相同,所以这里不进行示例描述,具体可以参看后续不同车间调度问题优化中GA算法应用部分。
GA类封装的交叉算子方法有次序交叉和基于位置的交叉,分别命名为:crossOX、crossPBX。
int[][] chromeSeqJSP = GA.initJSP1Chrome(5,
6, 4); System.out.println("-------chromeSeqJSP's content------"); EasyArray.printArray(chromeSeqJSP); int[][] chromeSeqJSPOX = GA.crossOX(chromeSeqJSP, 0.7); System.out.println("-------chromeSeqJSPOX's content------"); EasyArray.printArray(chromeSeqJSPOX); int[][] chromeSeqJSPPBX = GA.crossPBX(chromeSeqJSPOX, 0.7); System.out.println("-------chromeSeqJSPPBX's content------"); EasyArray.printArray(chromeSeqJSPPBX); |
结果如下:
-------chromeSeqJSP's content------ 6 4 5 5 2 1 2 5 3 4 3 4
6 4 1 5 1 1 6 6 2 2 3 3
; 5 2 2 4 2 6 1 1 3 1 6 2
4 4 5 6 5 6 1 4 3 5
3 3 ; 5 4 3 6 2 2 3 2 5 1 1 3
6 5 1 1 2 6 4 4 4 5 3 6 ; 6 4 1 2 4 6 3 2 1 5 1 4
1 3 6 2 5 3 5 5 2 4 3 6 ; 6 5 2 1 1 3 1 6 3 4 6 2
4 2 3 5 6 5 3 1 5 4 2 4 ; -------chromeSeqJSPOX's
content------ 5 2 2 5 4 3 4 6 4 1 5 1
1 6 6 2 2 6 1 4 3 5 3
3 ; 5 2 4 2 1 1 6 2 4 4 5 6
5 6 1 4 3 1 6 6 2 2 3 5
; 4 6 2 3 2 5 3 2 1 5 1 3 6 5 1 1 2
6 4 4 4 5 3 6 ; 6 4 4 6 2 1 3 2 5 1 1 4
1 3 6 2 5 3 5 5 2 4 3 6 ; 6 5 2 1 1 3 1 6 3 4 6 2
4 2 3 5 6 5 3 1 5 4 2 4 ; -------chromeSeqJSPPBX's
content------ 5 2 5 2 4 1 6 4 4 5 1 6
5 6 1 1 6 1 6 6 2 2 3 5 ; 5 2 2 5 1 3 4 2 4 4 5 1
1 6 6 6 5 6 1 6 3 5 3 3 ; 6 4 4 2 3 1 3 2 2 1 1 4
5 1 6 3 6 5 1 5 2 4 3 6 ; 4 6 2 4 6 5 3 2 2 5 1 3
1 1 1 4 1 3 6 4 4 5 3 6 ; 6 5 2 1 1 3 1 6 3 4 6 2 4 2 3 5 6 5 3 1 5 4
2 4 ; |
在chromeSeqJSP按照次序交叉方式crossOX获得的新染色体chromeSeqJSPOX过程中,以前两条染色体交叉为例,crossOX首先随机生产两个位置点13和18,从而从前两个染色体中分别获得交换的字串“1 6 6 2 2 3”和“6 1 4 3 5 3”,分别如上表中的红色和绿色标注,然后将这两个字串在两个染色体中交换,再进行补齐操作,使得两条染色体中各个数字出现的次数均为4次。
在chromeSeqJSP按照基于位置的交叉方式crossPBX获得的新染色体chromeSeqJSPPBX过程中,以第3和第4两条染色体交叉为例,crossPBX首先随机生产一些交换位置,示例中为:2, 14, 23, 1, 9, 0, 11, 5, 7, 6, 20, 19, 10, 21, 22,首先将第3条染色体选中交换位置的编码交换到第4条染色体对应位置,并将第4条染色体中对应位置的编码交换到第3天染色体对应位置,然后调整使得每条染色体中1到6这些数字都出现4次。
-------chromeSeqJSPOX's content------ 5 2 2 5 4 3 4 6 4 1 5 1 1 6 6 2 2 6 1 4 3 5 3 3 ; 5 2 4 2 1 1 6 2 4 4 5 6 5 6 1 4 3 1 6 6 2 2 3 5 ; 4 6
2 3 2 5 3 2 1 5 1 3 6 5 1 1 2 6 4 4
4 5 3 6 ; 6 4 4 6 2 1 3 2 5 1 1 4 1 3 6 2 5 3 5 5 2 4 3 6 ; 6 5 2 1 1 3 1 6 3 4 6 2 4 2 3 5 6 5 3 1 5 4 2 4 ; -------chromeSeqJSPPBX's content------ 5 2 5 2 4 1 6 4 4 5 1 6 5 6 1 1 6 1 6 6 2 2 3 5 ; 5 2 2 5 1 3 4 2 4 4 5 1 1 6 6 6 5 6 1 6 3 5 3 3 ; 6 4 4 2 3 1 3 2 2 1 1 4 5 1 6 3 6 5 1 5 2 4 3 6 ; 4 6 2 4 6 5 3
2 2 5 1 3 1 1 1 4 1 3 6 4 4 5 3 6 ; 6 5 2 1 1 3 1 6 3 4 6 2 4 2 3 5 6 5 3 1 5 4
2 4 ; |
GA类封装的变异算子方法有0-1变异、逆序变异和两点互换变异,分别命名为:muteBit、muteTwoPointReverse、muteTwoPointSwap。
例:
int[][] chrome01 = GA.initBitChrome(5, 20); System.out.println("-------chrome01's content-------"); EasyArray.printArray(chrome01); int[][] chrome01mute = GA.muteBit(chrome01, 0.8); System.out.println("-------chrome01mute's content-------"); EasyArray.printArray(chrome01mute); |
执行结果:
-------chrome01's content------- 1 1 0 0 0 1 1 0 0 0 1 1 1 0 1 0
0 1 1 1 ; 0 0 1 1 1 0 0 0 1 1 1 0 1 0 0 0 0
0 0 1 ; 1 0 1 1 1 0 1 1 0 1 1 0 0 0 1 0 0 1 1 1 ; 1 1 0 0 0 0 0 1 0 1 0 0
0 1 1 0 0 1 0 1 ; 0 1 1 0 1 0 0 1 1 0 0 0
1 0 1 1 0 0 0 0 ; -------chrome01mute's content------- 1 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0
0 1 1 1 ; 0 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 0
0 0 1 ; 1 0 1 1 1 0 1 1 1 1 1 0 0 0 1 0 0 1 1 1 ; 1 1 0 0 0 0 0 1 0 1 0 0
0 1 1 0 0 1 0 1 ; 0 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 0 0 0 0 ; |
对每一条染色体,按照80%的概率修改其一个位置的数值,例如第一行第二个数字由1变成0,第三行第九个数字由0变成1。
逆序变异和两点交换变异示例如下:
int[][] chromeSeqA =GA.initSequenceChrome(5,
20); System.out.println("-------chromeSeqA's content-------"); EasyArray.printArray(chromeSeqA); int[][] chromeSeqAmute =GA.muteTwoPointReverse(chromeSeqA, 0.6); System.out.println("-------chromeSeqAmute's content-------"); EasyArray.printArray(chromeSeqAmute); int[][] chromeSeqAmute2 =GA.muteTwoPointReverse(chromeSeqAmute, 0.6); System.out.println("-------chromeSeqAmute2's content-------"); EasyArray.printArray(chromeSeqAmute2); |
执行结果如下:
-------chromeSeqA's content------- 0 10 7 13 11 9 6 5 2 12 8 17 19
3 18 1 4 16 14 15 ; 5 11 6 17 13 3 16 15 8
14 10 12 1 19 4 2 7 18 0 9 ; 14 12 2 7 8 18 17 10 6
0 15 3 1 9 11 19 16 5 4 13 ; 9 18 3 16 6 1 5 12 7 11
17 15 19 13 14 4 2 10 0 8 ; 15 11 8 1 0 2 19 18 10
16 7 14 9 5 6 12 13 17 3 4 ; -------chromeSeqAmute's
content------- 0 10 7 18 3 19 17 8 12 2 5 6 9 11
13 1 4 16 14 15 ; 5 11 6 17 13 3 16 15 8
14 10 12 1 19 4 2 7 18 0 9 ; 14 12 2 7 8 18 17 10 6
0 15 3 1 9 11 19 16 5 4 13 ; 9 18 3 16 6 1 5 12 7 11
17 15 19 13 14 4 2 10 0 8 ; 15 11 8 1 0 2 19 18 10
16 7 14 9 5 6 12 13 17 3 4 ; -------chromeSeqAmute2's
content------- 0 10 7 18 3 19 17 8 12
2 16 4 1 13 11 9 6 5 14 15 ; 5 11 6 17 13 3 16 15 8
14 10 12 1 19 4 2 7 18 0 9 ; 14 12 2 7 8 18 17 10 6
11 9 1 3 15 0 19 16 5 4 13 ; 9 18 3 16 6 1 5 15 17 11
7 12 19 13 14 4 2 10 0 8 ; 15 11 8 1 0 5 9 14 7 16 10 18 19 2 6 12 13 17
3 4 ; |
点间逆序变异参看chromeSeqA中第一行数据变化为chromeSeqAmute的第一行数据,其将13 11 9 6 5 2 12 8 17 19 3 18编码逆序排程18 3 19 17 8 12
2 5 6 9 11 13形成新的染色体。
两点交换变异参看chromeSeqAmute第三行数据变化为chromeSeqAmute2的第三行数据,红色表示的两个位置数据11和0交换从而形成新的解。
ACO类主要封装了一些蚁群算法运算中涉及的方法,主要包括蚁群算法中信息素生成、根据信息素生成蚂蚁路径以及信息素的更新。
ACO类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
createRoute 根据信息素生成路径【1-jobQty】 |
|
createRoutes 根据信息素和蚂蚁数量生成路径【1-jobQty】 |
|
initPheromone 初始化信息素 |
|
initPheromone 初始化信息素 |
|
initPheromone2 初始化信息素,针对jsp问题 |
|
updatePheromone 更新信息素 |
蚁群算法搜索过程是对信息素的更新和评价,ACO类中设计了分别针对并行机、流水车间和作业车间三类问题的信息素初始化方法,依次命名为:initPheromone、initPheromone和initPheromone2。第一个初始化方法输入参数为各个作业加工时间的一维数组、第二个初始化方法输入的参数为各个作业在各道工序上的加工时间的二维数组、第三个初始化方法输入的参数为各个作业在各道工序上加工时间和加工设备的二维数组。
例(1):
车间现有10项作业需要进行同一项操作,车间能执行该操作的设备是3台同质并行机,10项作业该项操作的加工时间如下表:
作业Id |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
工时 |
21.2 |
5.4 |
7 |
7 |
15 |
20.9 |
18.1 |
19.6 |
9.6 |
4.7 |
利用ACO对这10项作业同质并行机问题进行调度优化时,需要根据各作业的加工时间生成初始信息素,实现方法如下:
double[] cycleTimes = {21.2,5.4,7,7,15,20.9,18.1,19.6,9.6,4.7}; double[][] pheromone = ACO.initPheromone(cycleTimes); |
输出结果将是12行12列的二维实数数组,每个元素的初始值为1/10【作业数量的倒数】。
例(2):
流水车间中有3项作业,每项作业依次要经过机器1、机器2、机器3和机器4进行加工,作业在各台机器上的加工时间如下表:
作业\工序 |
工序1 |
工序2 |
工序3 |
工序4 |
作业1 |
13.4 |
8.7 |
11.6 |
14.3 |
作业2 |
5.7 |
21.7 |
4.8 |
4.8 |
作业3 |
4.1 |
12.6 |
21.1 |
23.2 |
利用ACO对其进行调度优化时,需要根据各作业的加工时间生成初始信息素,实现方法如下:
double[][] ctimes2 = {{13.4, 8.7,
11.6, 14.3},{5.7, 21.7, 4.8, 4.8}, {4.1,
12.6, 21.1, 23.2}}; double[][] pheromone2 = ACO.initPheromone(ctimes2); |
输出结果将是5行5列的二维实数数组,每个元素的初始值为1/3【作业数量的倒数】。
例(3):
现有3项作业4道工序的作业车间进行调度问题,工艺工时数据如下表所示:
作业Id |
工序1 |
工序2 |
工序3 |
工序4 |
||||
设备Id |
工时 |
设备Id |
工时 |
设备Id |
工时 |
设备Id |
工时 |
|
1 |
3 |
54 |
1 |
34 |
4 |
61 |
2 |
2 |
2 |
4 |
9 |
1 |
15 |
2 |
89 |
3 |
70 |
3 |
1 |
38 |
2 |
19 |
3 |
28 |
4 |
87 |
4 |
1 |
95 |
3 |
34 |
2 |
7 |
4 |
29 |
利用ACO进行排产优化时,可按照如下方式进行信息素初始化:
double[][] ctimes2 = {{13.4, 8.7,
11.6, 14.3},{5.7, 21.7, 4.8, 4.8}, {4.1,
12.6, 21.1, 23.2}}; double[][] pheromone2 = ACO.initPheromone(ctimes2); |
输出结果将是5行5列的二维实数数组,每个元素的初始值为1/3【作业数量的倒数】。
蚁群算法寻优过程中需要根据信息素转变为能够表示实际问题解的结果,在车间调度优化中,问题解是各个作业的排序,例如并行机调度中的作业数量为N,则问题的可行解必然是1到N之间这N个自然数的一种随机排序。蚁群算法搜索过程不直接对这N个自然数的排序进行操作,而是对N+2行和N+2列的实数二维数组进行操作,每一行的数据表示一个解,所以需要能够将实数行向量转变为1到N之间自然数排序的方法。ACO类中有两个生成路径的方法,根据信息素形成一只蚂蚁行走路径的方法createRoute和根据信息素新成全部蚂蚁行走路径的方法createRoutes。
例(1):
假设在算法运算过程中获得了信息素数组变量pheromone的值如下:
0.87 |
0.60 |
0.54 |
0.30 |
0.95 |
0.15 |
0.23 |
0.57 |
0.70 |
0.88 |
0.82 |
0.79 |
0.51 |
0.38 |
0.69 |
0.58 |
0.28 |
0.98 |
0.63 |
0.94 |
0.25 |
0.35 |
1.03 |
0.11 |
0.71 |
0.11 |
0.10 |
1.03 |
0.34 |
0.76 |
0.81 |
0.21 |
0.42 |
0.20 |
0.98 |
0.96 |
0.38 |
0.66 |
0.23 |
0.66 |
0.74 |
0.15 |
0.21 |
0.42 |
0.71 |
0.54 |
1.02 |
0.82 |
0.57 |
0.58 |
0.45 |
0.57 |
0.96 |
0.46 |
0.23 |
0.88 |
0.18 |
0.27 |
0.21 |
1.10 |
1.02 |
0.76 |
1.06 |
0.49 |
1.08 |
0.96 |
0.94 |
0.70 |
0.51 |
0.87 |
1.10 |
0.95 |
0.47 |
0.19 |
0.55 |
0.45 |
0.37 |
0.18 |
0.44 |
0.60 |
0.91 |
0.25 |
0.88 |
0.50 |
0.24 |
0.20 |
0.62 |
0.87 |
0.94 |
0.59 |
0.27 |
0.10 |
0.71 |
0.24 |
0.27 |
0.25 |
1.02 |
1.05 |
0.24 |
0.96 |
0.65 |
0.50 |
0.98 |
1.10 |
0.86 |
0.92 |
0.85 |
0.26 |
0.13 |
0.30 |
0.84 |
1.09 |
0.11 |
0.71 |
0.39 |
1.07 |
0.70 |
0.70 |
0.46 |
0.75 |
1.00 |
0.92 |
0.26 |
0.81 |
1.00 |
0.88 |
0.57 |
0.14 |
0.20 |
0.47 |
0.40 |
1.04 |
0.98 |
0.96 |
0.60 |
1.07 |
0.33 |
0.39 |
0.58 |
0.77 |
0.24 |
0.16 |
0.59 |
0.98 |
则利用下列代码可以分别生成一只蚂蚁和十只蚂蚁的路径:
int[] route =ACO.createRoute(pheromone); System.out.println("-----one ant's route created by pheromone-----"); EasyArray.printArray(route); int[][] routes =ACO.createRoutes(pheromone,10); System.out.println("-----ten ants' routes created by pheromone-----"); EasyArray.printArray(routes); |
由于蚂蚁根据信息素形成路径具有随机性,一种可能结果如下:
------one
ant's route created by pheromone------ 6 10 1 9 2 4 5 7 3 8 ------ten
ants' routes created by pheromone------ 9 5 2 4
7 8 3 1 6 10 ; 10 6 7 3
4 8 9 2 5 1 ; 4 7 3
10 1 9 5 2 6 8 ; 9 5 10 4
7 3 2 8 6 1 ; 2 5 10
1 6 8 7 3 9 4 ; 8 9 7
2 10 5 4 3 6 1 ; 1 2 3
10 9 7 5 8 4 6 ; 4 9 5 10 1 7 6 3 2 8 ; 1 6 8
3 7 4 9 2 10 5 ; 1 5 9 7 2 4 8 3 10 6 ; |
从十只蚂蚁的路径看,当前这些蚂蚁还处于随机探索阶段,也就是各个节点之间信息素的强度差别不是太大,节点之间没有形成较强的吸引力,所以蚂蚁们的行走路径没有多少规律。相对来说节点9和节点5之间的信息素强度可能稍高,因为9-5链接出现在10只蚂蚁路径中5个路径之中。10-6两点直接连通出现了3次。
蚁群算法寻优过程中根据当前点间信息素强度、截止目前最好解对应的路径、截止当前最好解的值和信息素挥发系数更新点间的信息素,以便蚂蚁在后续步骤中积聚到同一条路径中来,进而获得问题的最优解。ACO类中完成该功能的方法为updatePheromone。由于涉及具体问题的目标函数方能更新信息素,这里仅列出方法的参数。
public double[][]
updatePheromone(double[][] pherom,
int[] bestRoute,
double bestFit,
double rho) 参数: pherom - 作业之间链接弧的信息素,行列相等,均为节点数量+2 bestRoute - 迭代过程中获得的最优解,一维数组,数组个数为为节点数量,【注意】编号从1开始 bestFit - 最优解的值 rho - 信息素挥发系数 返回: 信息素二维数组,行列均为作业数量+2 |
PSO类主要封装了一些粒子群算法运算中涉及的方法,主要包括粒子群算法中位置向量和速度向量初始化、根据位置向量转变为车间调度问题解的排序整数向量、位置向量和速度向量的更新等。
PSO类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
getMinFitIdx 将根据一维向量数组获得最小解对应的数组下标 |
|
initV 根据粒子数量、变量数量初始化[0,1]区间的二维初始速度V |
|
initX 根据粒子数量、变量数量初始化[0,1]区间的二维初始粒子群X |
|
parseInt 将实数的二维粒子群X转变为整数的二维粒子群intX |
|
parseInt 将实数的二维粒子群X转变为整数的二维粒子群intX |
|
updateV 根据当前解、速度、个体最优解、群体最优解、算法参数更新解集各粒子的速度向量V |
|
updateX 根据当前解、速度、个体最优解、群体最优解、算法参数更新解集的值X |
粒子群算法寻优过程主要依靠位置向量和速度向量的更新,PSO类中设计了位置向量初始化和速度向量初始化的方法,分别命名为:initX和initV。
例(1)
车间现有10项作业需要进行同一项操作,车间能执行该操作的设备是3台同质并行机,10项作业该项操作的加工时间如下表:
作业Id |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
工时 |
21.2 |
5.4 |
7 |
7 |
15 |
20.9 |
18.1 |
19.6 |
9.6 |
4.7 |
利用PSO对其进行优化求解时,首先需要随机生成一定粒子数量的初始化位置向量和速度向量,实现如下:
int variableQty = 10 ; int pop =5; double[][] X = PSO.initX(pop, variableQty); double[][] V =PSO.initV(pop, variableQty); System.out.println("--- init the Xs ------"); EasyArray.printArray(X); System.out.println("--- init the Vs ------"); EasyArray.printArray(V); |
因为是随机生成初始化解,执行之后的结果可能如下所示:
--- init the Xs ------ 0.248 0.071 0.006 0.137
0.059 0.053 0.751 0.451 0.736 0.445 ; 0.281 0.850 0.023 0.546
0.719 0.745 0.937 0.445 0.810 0.378 ; 0.079 0.262 0.380 0.394
0.014 0.470 0.218 0.815 0.978 0.901 ; 0.892 0.447 0.034 0.501
0.685 0.606 0.481 0.427 0.753 0.440 ; 0.730 0.601 0.791 0.078
0.110 0.428 0.022 0.281 0.028 0.955 ; --- init the Vs ------ 0.029 0.262 0.749 0.432
0.070 0.881 0.551 0.833 0.770 0.464 ; 0.429 0.671 0.768 0.083
0.585 0.094 0.718 0.265 0.897 0.055 ; 0.278 0.719 0.217 0.128
0.134 0.895 0.825 0.352 0.852 0.849 ; 0.635 0.347 0.380 0.172
0.747 0.837 0.301 0.505 0.790 0.610 ; 0.539 0.445 0.071 0.907 0.045 0.517 0.915 0.216 0.183 0.240 ; |
注:实数值小数位数进行了处理,只保留3位小数。
PSO算法中直接操作的对象是实数型的位置向量,而这些实数向量需要转换为整数向量以表示各个作业加工的先后顺序。PSO算法中设计了单个粒子位置向量转换为整数向量的方法和一群粒子位置向量转换为整数向量的方法parseInt。
例(1):
有一个包含5个粒子每个粒子具有10维位置的粒子群位置向量,将其第一个粒子转换为作业排序的整数向量,和将全部粒子转换为可以表示作业排序的整数向量,代码如下:
double[][] X = PSO.initX(5, 10); System.out.println("--- init the Xs ------"); EasyArray.printArray(X); int[] intSeq = PSO.parseInt(X[0]); System.out.println("--- 一维实数向量转换为一维整数向量------"); EasyArray.printArray(intSeq); int[][] intSeqs = PSO.parseInt(X); System.out.println("--- 二维实数向量转换为二维整数向量 ------"); EasyArray.printArray(intSeqs); |
执行结果如下:
--- init the Xs
------ 0.642 0.807 0.710
0.107 0.563 0.743 0.161 0.692 0.763 0.501 ; 0.459 0.820 0.031
0.181 0.260 0.094 0.068 0.390 0.495 0.438 ; 0.729 0.313 0.369
0.529 0.374 0.920 0.426 0.824 0.468 0.717 ; 0.332 0.902 0.524
0.024 0.454 0.955 0.627 0.719 0.432 0.312 ; 0.083 0.727 0.668
0.805 0.175 0.340 0.050 0.650 0.610 0.596 ; --- 一维实数向量转换为一维整数向量------ 4 7 10 5 1 8 3 6 9 2 --- 二维实数向量转换为二维整数向量
------ 4 7 10 5 1 8 3 6
9 2 ; 3 7 6 4 5 8 10 1
9 2 ; 2 3 5 7 9 4 10 1
8 6 ; 4 10 1 9 5 3 7 8
2 6 ; 7 1 5 6 10 9 8 3
2 4 ; |
整数向量每一行表示中各个数字表示对应作业的加工顺序。
PSO算法中每次迭代时需要获取最优解的位置和速度信息,所以需要获取最优解所对应的粒子序号。PSO算法设计了从一维数组中找出最小值序号的方法getMinFitIdx。
例(1):
有一个一维数组[0.642 0.807 0.710 0.107
0.563 0.743
0.161 0.692
0.763 0.501],请找出最小值所在的位置下标。
double[] fits = {0.642,0.807,0.710,0.107,0.563,0.743,0.161,0.692,0.763,0.501}; System.out.println(PSO.getMinFitIdx(fits)); |
输出结果为3,即第四个数字0.107最小。
PSO算法中每次迭代需要进行各个粒子的位置信息和速度信息更新,以实现粒子向最优解逼近。PSO算法分别设计了updateX和updateV,根据当前解、速度、个体最优解、群体最优解、算法参数更新粒子的位置向量X和速度向量V。由于这两个方法使用了较多的参数,这里仅列出这两个方法的参数,具体使用参看后续内容。
public double[][]
updateX(double[][] X,
double[][] V,
double[][] singleBest,
double[] groupBest,
double[] params) 根据当前解、速度、个体最优解、群体最优解、算法参数更新解集的值X 参数: X - 当前粒子群的解集,行为粒子个数,列为变量个数 V - 当前粒子群对应的速度,行为粒子个数,列为变量个数 singleBest
- 当前粒子群各个粒子的最好解,行为粒子个数,列为变量个数 groupBest
- 当前种群最好解,一维数组,长度为变量个数 params
- 算法参数,0-惯性系数w,1-个体学习因子c1,2-社会学习因子c2 返回: 返回新的粒子群X,二维数组,行为粒子个数,列为变量个数 |
public double[][]
updateV(double[][] X,
double[][] V,
double[][] singleBest,
double[] groupBest,
double[] params) 根据当前解、速度、个体最优解、群体最优解、算法参数更新解集各粒子的速度向量V 参数: X - 当前粒子群的解集,行为粒子个数,列为变量个数 V - 当前粒子群对应的速度,行为粒子个数,列为变量个数 singleBest
- 当前粒子群各个粒子的最好解,行为粒子个数,列为变量个数 groupBest
- 当前种群最好解,一维数组,长度为变量个数 params
- 算法参数,0-惯性系数w,1-个体学习因子c1,2-社会学习因子c2 返回: 返回新的速度V,二维数组,行为粒子个数,列为变量个数 |
TLBO类主要封装了一些教学算法运算中涉及的方法,包括班级学生成绩初始化、从成绩向量转换为作业排序解向量、基于教师教学和同学相互学习过程的成绩更新等。
TLBO类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
getMeanScores 对全部学生各个科目成绩计算出平均成绩 |
|
getSequenceFromOneScore 对单个学生各个科目成绩进行排序,然后生成该学生成绩对应的排序顺序序号数组,即车间调度的作业排序【作业编号从1开始】 |
|
getSequenceFromScores 对每个学生各个科目成绩进行排序,然后生成排序顺序序号数组,即车间调度的作业排序【作业编号从1开始】 |
|
getTwoDiffNum 获取区间[0,num-1]这num个数字中的两个不同数字 |
|
initClass 根据班级学生数量,科目数量初始化成绩集合 |
|
updateOneScore 根据两个学生各个科目的成绩,更新第一个学生的成绩 |
|
updateScores 根据当前班级同学成绩、最好同学成绩和班级平均成绩更新班级同学的成绩 |
教学算法寻优过程主要依靠班级每位同学各个科目成绩的更新来进行最优解的搜索,TLBO类中设计的初始化班级方法为initClass。
例(1)
车间现有10项作业需要进行同一项操作,车间能执行该操作的设备是3台同质并行机,10项作业该项操作的加工时间如下表:
作业Id |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
工时 |
21.2 |
5.4 |
7 |
7 |
15 |
20.9 |
18.1 |
19.6 |
9.6 |
4.7 |
利用TLBO对其进行优化求解时,首先需要随机生成包含一定数量这10门功课的成绩,实现如下:
double[][] scores = TLBO.initClass(5,
10); EasyArray.printArray(scores); |
随机生成的结果如下,由于初始化为随机赋值,每次生成的结果可能不同,但是每个数字均是落在[0,100]之间。
86.0 32.0 89.0 52.0 73.0 87.0 87.0 63.0 46.0 95.0 ; 13.0 27.0 41.0 1.0 77.0 8.0 92.0 38.0 49.0 91.0 ; 48.0 56.0 62.0 22.0 9.0 91.0 71.0 70.0 14.0 81.0 ; 25.0 18.0 76.0 16.0 25.0 11.0 57.0 20.0 17.0 89.0 ; 83.0 90.0 65.0 2.0 48.0 1.0 75.0 99.0 38.0 96.0 ; |
TLBO算法中直接操作的对象是实数型的成绩向量,而这些实数向量需要转换为整数向量以表示各个作业加工的先后顺序。TLBO算法中设计了单个同学成绩向量转换为整数向量的方法和全部同学成绩向量转换为整数向量的方法getSequenceFromOneScore和getSequenceFromScores。
例(1):
当前班级由5名学生的10门课程成绩组成,需要将第一个同学成绩以及全部5名同学成绩转换为作业排序,实现如下:
double[][] scores = TLBO.initClass(5, 10); System.out.println("---initialize the class's scores---"); EasyArray.printArray(scores); int[] oneSeq =TLBO.getSequenceFromOneScore(scores[0]); int[][] manySeqs =TLBO.getSequenceFromScores(scores); System.out.println("---create a sequence from one student's
scores---"); EasyArray.printArray(oneSeq); System.out.println("---create sequences from many students'
scores---"); EasyArray.printArray(manySeqs); |
执行结果如下:
---initialize the class's scores--- 51.0 1.0 29.0 32.0 50.0 57.0 83.0 16.0 63.0 10.0 ; 67.0 41.0 18.0 59.0 66.0 93.0 100.0 2.0 70.0 92.0 ; 61.0 51.0 74.0 87.0 93.0 26.0 2.0 69.0 45.0 63.0 ; 76.0 8.0 48.0 62.0 96.0 37.0 28.0 37.0 17.0 21.0 ; 73.0 79.0 78.0 16.0 42.0 30.0 46.0 15.0 89.0 89.0 ; ---create a sequence from one student's scores--- 2 10 8 3 4 5 1 6 9 7 ---create sequences from many students' scores--- 2 10 8 3 4 5 1 6 9 7 ; 8 3 2 4 5 1 9 10 6 7 ; 7 6 9 2 1 10 8 3 4 5 ; 2 9 10 7 6 8 3 4 1 5 ; 8 4 6 5 7 1 3 2 9 10 ; |
注:因为初始化具有随机性,所以班级初始化成绩可能不一样,只要班级初始化成绩确定,则根据每位同学成绩生成的排序结果将是确定的。
TLBO算法寻优过程中需要随机从班级中选择不同的学生进行成绩更新,所以设计了给定参数n后,返回[0,n-1]之间的两个不同数字的方法getTwoDiffNum。
例:
当前算法中学生数为10,从中选择两个用于成绩更新的学生下标,实现如下:
int[] twoIdx = TLBO.getTwoDiffNum(10); |
随机选择后twoIdx的值为[0,9]之间的两个不同数字。
TLBO算法选优过程中有两个成绩更新过程,一为根据当前班级同学成绩、最好同学成绩和班级平均成绩更新班级同学的成绩,另一个为随机选择两个不同学生并更新第一个同学成绩,对应的两个方法分别为:updateScores和updateOneScore。由于两个方法需要相关同学对应的目标函数,这里仅列出这两个方法的参数,具体使用参看后续内容。
public double[][]
updateOneScore(double[][] scores,
boolean isFirstGood) 根据两个学生各个科目的成绩,更新第一个学生的成绩 参数: scores - 当前班级各个同学的成绩 isFirstGood - 第一个学生综合评价是否优于第二个学生 返回: 二维数组,其中行为2,列为科目数量,即返回两个学生的各科目成绩 |
public double[][]
updateScores(double[][] scores,
double[] bestScores,
double[] meanScores) 根据当前班级同学成绩、最好同学成绩和班级平均成绩更新班级同学的成绩 参数: scores - 当前班级各个同学的成绩 bestScores - 班级最好同学各科成绩 meanScores - 班级各个科目的平均成绩 返回: 二维数组,一行代表一个学生各个科目的成绩,一列代表某个科目全部学生的成绩 |
Rules类主要封装了一些车间调度的经验规则算法,主要包括交付时间优先EDD、先到先服务FCFS、综合考虑FCFS和EDD的算法FEDD、从何考虑FCFS和最长加工时间优先LPT的算法FLPT等。
Rules类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
seqEDD 利用交付时间优先规则进行作业排序 |
|
seqFCFS 利用先来先服务FCFS规则进行作业排序 |
|
seqFEDD 利用先来先服务FCFS和最早交付时间优先EDD规则进行作业排序 |
|
seqFLPT 利用先来先服务FCFS和最长加工时间优先LPT规则进行作业排序 |
|
seqFSPT 利用先来先服务FCFS和最短加工时间优先规则进行作业排序 |
EDD方法为生产排序中的交付时间优先排序规则,根据各项作业的交付时间对作业加工顺序进行排序,交付时间越早排序越靠前。
例:
有10项作业需要进行排序,这些作业的交付时间如下表
JobId |
J1 |
J2 |
J3 |
J4 |
J5 |
J6 |
J7 |
J8 |
J9 |
J10 |
DueTime |
20 |
21 |
7 |
10 |
22 |
10 |
20 |
21 |
17 |
5 |
使用EDD方法获得全部作业排序的先后关系,实现如下:
double[] dtimes = {20,21,7,10,22,10,20,21,17,5}; int[] seq = Rules.seqEDD(dtimes); EasyArray.printArray(seq); |
执行结果输出如下:
10 3 4 6 9 1 7 2 8 5 |
EDD方法为生产排序中的先到先服务排序规则,根据各项作业的释放时间对作业加工顺序进行排序,释放时间越早排序越靠前。
例:
有10项作业需要进行排序,这些作业的释放时间如下表
JobId |
J1 |
J2 |
J3 |
J4 |
J5 |
J6 |
J7 |
J8 |
J9 |
J10 |
ReleaseTime |
12 |
5 |
14 |
6 |
23 |
10 |
22 |
17 |
12 |
22 |
使用FCFS方法获得全部作业排序的先后关系,实现如下:
double[] rtimes = {12,5,14,6,23,10,22,17,12,22}; int[] seq2 =Rules.seqFCFS(rtimes); EasyArray.printArray(seq2); |
执行结果输出如下:
2 4 6 1 9 3 8 7 10 5 |
FEDD方法首先采取先到先服务规则进行排序,如果遇到两个作业释放时间相同,则按照先到先服务规则排序。
例:
有十项作业的交付时间和释放时间如下表所示:
JobId |
J1 |
J2 |
J3 |
J4 |
J5 |
J6 |
J7 |
J8 |
J9 |
J10 |
DueTime |
20 |
21 |
7 |
10 |
22 |
10 |
20 |
21 |
17 |
5 |
ReleaseTime |
12 |
5 |
14 |
6 |
23 |
10 |
22 |
17 |
12 |
22 |
按照FEDD排序实现如下:
double[] dtimes = {20,21,7,10,22,10,20,21,17,5}; double[] rtimes = {12,5,14,6,23,10,22,17,12,22}; int[] seq3 =Rules.seqFEDD(dtimes, rtimes); EasyArray.printArray(seq3); |
执行结果如下:
2 4 6 9 1 3 8 10 7 5 |
FLPT方法是先采用先到先服务规则进行排序,如果遇到两个作业释放时间相同,则按照加工时间总时长最长优先的规则进行排序。
例:
有十项作业的加工时间和交付时间如下表所示:
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
Proc6 |
ReleaseTime |
J1 |
17.9 |
12.2 |
8.9 |
22.5 |
17.8 |
7.6 |
12 |
J2 |
22.1 |
6.1 |
4.2 |
22.4 |
14.5 |
6.4 |
5 |
J3 |
17.5 |
21.7 |
9.6 |
20.4 |
10.1 |
22.5 |
14 |
J4 |
13.8 |
21.8 |
20.2 |
21.5 |
7.7 |
5.5 |
6 |
J5 |
10.3 |
14.3 |
19.8 |
18.9 |
13.3 |
7.3 |
23 |
J6 |
12 |
12.3 |
23.8 |
7.9 |
14.5 |
18.2 |
10 |
J7 |
9 |
5.7 |
22.6 |
10.9 |
20.7 |
21.8 |
22 |
J8 |
9.7 |
18.8 |
10.9 |
20.8 |
11 |
9.2 |
17 |
J9 |
14 |
23.8 |
8.1 |
8.7 |
4.7 |
8 |
12 |
J10 |
17.8 |
17.2 |
16.5 |
4.8 |
5.3 |
10.4 |
22 |
按照FLPT排序实现如下:
double[] rtimes = {12,5,14,6,23,10,22,17,12,22}; double[][] ptimes = {{17.9,12.2,8.9,22.5,17.8,7.6},{22.1,6.1,4.2,22.4,14.5,6.4}, {17.5,21.7,9.6,20.4,10.1,22.5},{13.8,21.8,20.2,21.5,7.7,5.5}, {10.3,14.3,19.8,18.9,13.3,7.3},{12,12.3,23.8,7.9,14.5,18.2}, {9,5.7,22.6,10.9,20.7,21.8},{9.7,18.8,10.9,20.8,11,9.2}, {14,23.8,8.1,8.7,4.7,8},{17.8,17.2,16.5,4.8,5.3,10.4}}; double[] jobSumPtimes = new double[ptimes.length]; for(int i=0;i<ptimes.length;i++) { jobSumPtimes[i] = EasyMath.sum(ptimes[i]); } int[] seq4 = Rules.seqFLPT(jobSumPtimes, rtimes); EasyArray.printArray(seq4); |
执行结果如下:
2 4 6 1 9 3 8 7 10 5 |
FSPT方法是先采用先到先服务规则进行排序,如果遇到两个作业释放时间相同,则按照加工时间总时长最短优先的规则进行排序。
例:
有十项作业的加工时间和交付时间如下表所示:
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
Proc6 |
ReleaseTime |
J1 |
17.9 |
12.2 |
8.9 |
22.5 |
17.8 |
7.6 |
12 |
J2 |
22.1 |
6.1 |
4.2 |
22.4 |
14.5 |
6.4 |
5 |
J3 |
17.5 |
21.7 |
9.6 |
20.4 |
10.1 |
22.5 |
14 |
J4 |
13.8 |
21.8 |
20.2 |
21.5 |
7.7 |
5.5 |
6 |
J5 |
10.3 |
14.3 |
19.8 |
18.9 |
13.3 |
7.3 |
23 |
J6 |
12 |
12.3 |
23.8 |
7.9 |
14.5 |
18.2 |
10 |
J7 |
9 |
5.7 |
22.6 |
10.9 |
20.7 |
21.8 |
22 |
J8 |
9.7 |
18.8 |
10.9 |
20.8 |
11 |
9.2 |
17 |
J9 |
14 |
23.8 |
8.1 |
8.7 |
4.7 |
8 |
12 |
J10 |
17.8 |
17.2 |
16.5 |
4.8 |
5.3 |
10.4 |
22 |
按照FSPT排序实现如下:
double[] rtimes = {12,5,14,6,23,10,22,17,12,22}; double[][] ptimes = {{17.9,12.2,8.9,22.5,17.8,7.6},{22.1,6.1,4.2,22.4,14.5,6.4}, {17.5,21.7,9.6,20.4,10.1,22.5},{13.8,21.8,20.2,21.5,7.7,5.5}, {10.3,14.3,19.8,18.9,13.3,7.3},{12,12.3,23.8,7.9,14.5,18.2}, {9,5.7,22.6,10.9,20.7,21.8},{9.7,18.8,10.9,20.8,11,9.2}, {14,23.8,8.1,8.7,4.7,8},{17.8,17.2,16.5,4.8,5.3,10.4}}; double[] jobSumPtimes = new double[ptimes.length]; for(int i=0;i<ptimes.length;i++) { jobSumPtimes[i] = EasyMath.sum(ptimes[i]); } int[] seq5 = Rules.seqFSPT(jobSumPtimes, rtimes); EasyArray.printArray(seq5); |
执行结果如下:
2 4 6 9 1 3 8 10 7 5 |
easyopt.model包中主要包含了车间智能调度优化计算中所涉及的通用对象模型,主要有订单对象、过程对象和操作【任务】对象。easyopt.model包中的类及其功能如下表。
类 |
说明 |
Order |
车间调度中的订单类,包含了订单的全部信息 |
Process |
订单的加工工序类,一般会关联到特定订单 |
Task |
该类对象将表示一项具体的操作:在哪台机器上加工哪种订单,在什么时候开始,又在什么时候结束, 该操作之前机器设备的空闲时段的时长,开始时间和结束时间 |
Order类为较复杂车间调度问题中的订单类,即作业,该类主要包含作业的基本信息,例如工序、工时、释放时间或交付时间等属性,还包括对这些属性进行读和写操作的方法。
限定符和类型 |
方法和说明 |
|
getDueTime 获取该订单的交付时间 |
|
getNextProcId 获取该订单下一排产工序编号,从0开始编号 |
|
getOrderId 获取该订单在全部订单中的编号,从0开始编号 |
|
getPreEndTime 获取该订单前一工序排产结束的时间,也即后一工序最早可开工时间 |
|
getProcessList 获取该订单各道工序的工艺对象列表 |
|
getProcTime 获取单一工序订单的作业工时:主要用于并行机调度 |
|
getReleaseTime 获取该订单的释放时间 |
|
setDueTime 设置该订单的交付时间 |
|
setNextProcId 设置该订单下一排产工序编号,从0开始编号 |
|
setOrderId 设置该订单在全部订单中的编号,从0开始编号 |
|
setPreEndTime 设置该订单前一工序排产结束的时间,也即后一工序最早可开工时间 |
|
setProcessList 设置该订单的工艺对象列表 |
|
setProcTime 设置单一工序订单的作业工时:主要用于并行机调度 |
|
setReleaseTime 设置该订单的释放时间 |
该类的方法含义非常明显,使用也很简单,对方法的使用不再赘述。
Process类为较复杂车间调度问题中订单类的子对象类,即订单的单个工序详情类,该类主要包含某个作业特定工序的信息,例如工序编码、工序工时、可使用机器编号列表等属性,还包括对这些属性进行读和写操作的方法。
限定符和类型 |
字段和说明 |
|
cycleTime 该订单在本道工序的加工总时间 |
|
machIndex 本道工序可用设备编码,是设备在全部设备中的顺序号,从0开始编码 |
|
machQty 本道工序可用设备数量 |
|
processId 该工序的编码,从0开始编码 |
|
splitQty 本订单该工序可拆分子订单数量,即可以分为几个子订单 |
该类的方法含义非常明显,使用也很简单,对方法的使用不再赘述。
Task类为较复杂车间调度问题中最后的排产结果类。全部订单排产结束后,将形成一个一个的任务,这些任务满足订单工艺工时约束,是实际可执行的排产方案。该类主要包含作业编号、所用设备编号、作业开工时间、完工时间等属性,还包括对这些属性进行读和写操作的方法。
限定符和类型 |
方法和说明 |
|
getEndTime 获得该任务对应的完工时间 |
|
getGap 获得该任务所用机器在此任务之前紧前空闲时段的长度 |
|
getGapEndTime 同一台机器上前后任务时间可能存在空闲时间,该函数获得当前任务紧前空闲时间的结束时间,等于该任务的开工时间 |
|
getGapStartTime 获得该任务所用机器在此任务之前空闲时段的开始时间, 除非是该机器上的第一个任务,要不然该数组等于该任务之前的任务的完工时间 |
|
getIsSynStart 获取该任务是否为同步启停 |
|
getMachId 获得该任务对应所使用的机器在全部机器中的编码,从0开始编码 |
|
getOrderId 获得该任务对应的订单的编码,从0开始编码 |
|
getPeriodNum 获得同步启停并行机调度中该任务所处的工作时段,组号为1以上的整数表示可以同步开工,为0表示不可同步开工 |
|
getProcessId 获得该任务对应的作业工序的编码,从0开始编码 |
|
getReleaseTime 获得该任务对应作业的释放时间 |
|
getStartTime 获得该任务的开工时间 |
|
getTaskId 获得该任务在全部任务列表中的编码,从0开始编码 |
|
setEndTime 设置该任务的完工时间 |
|
setGap 设置该任务所用机器在此任务之前紧前空闲时段的长度 |
|
setGapEndTime 设置该任务所用机器在此任务之前紧前空闲时段的结束时间 |
|
setGapEtime 同一台机器上前后任务时间可能存在空闲时间,该函数是设置当前任务紧前空闲时间的结束时间 |
|
setGapStartTime 设置该任务所用机器在此任务之前紧前空闲时段的开始时间 |
|
setGapStime 同一台机器上前后任务时间可能存在空闲时间,该函数是设置当前任务紧前空闲时间的开始时间 |
|
setIsSynStart 若是同步启停作业调度,设置该任务是否可以开工,0不可开工,1可开工 |
|
setMachId 设置该任务所用机器编码,全部机器编码从0开始 |
|
setOrderId 设置该任务的作业编码,为对应作业在全部作业中的编码,从0开始 |
|
setPeriodNum 设置同步启停并行机调度中该任务所处的工作时段,组号为1以上的整数表示可以同步开工,为0表示不可同步开工 |
|
setProcessId 设置该任务的工序编码,为对应作业的工序编码,从0开始 |
|
setReleaseTime 设置该任务对应订单的释放时间 |
|
setStartTime 设置该任务的开工时间 |
|
setTaskId 设置该任务在全部任务列表中的编码,从0开始编码 |
|
setZeros 同一台机器上前后任务时间可能存在空闲时间,该函数是将当前任务紧前空闲时间的开始时间和结束时间置0 |
该类的方法含义非常明显,使用也很简单,对方法的使用不再赘述。
easyopt.shopSch包中主要包含了车间智能调度优化计算中所涉及同调度问题直接相关的通用类和方法,主要有各类算法类、数组转换、查找、排序类等,主要是将优化计算过程中涉及的通用方法进行包装。easyopt.shopSch包中的类及其功能如下表。
类 |
说明 |
Schedule |
对调度结果schedule数据相关处理方法的类,
例如求调度结果的最大完工时间、完工时间之和、最大延误时间 |
Scheduling |
调度运算过程中所使用的方法集合类,例如初始化订单列表和任务列表,或在运算中进行订单或任务特定信息处理的方法 |
SchOptResult |
使用迭代优化算法进行车间调度问题优化计算后的结果对象类,主要存储两类结果: (1) schedule[][]:具体的调度方案数组,该数组列数随着问题的变化而变化, 其中,第一列:作业编号,第二类:机器编号,第三列:工序编号
第四列:开工时间,第五列:完工时间,第六列:交付时间,第七列:释放时间, 第八列:调整开始时间,第九列:调整结束时间,第十列:调整时长,第十一列:同步开工的组号【同步启停并行机中,有组号为同步开工,0为不能同步开工】; (2) optSeries[][]:算法迭代过程每一代进化的目标函数值,一般为三列, 第一列-迭代代数,第二列-迄今为止最优目标函数值,第三列-当代最优解 |
其中SchOptResult类仅设定了两个数组属性变量,主要用于优化计算过程,所以下面仅对Schedule和Scheduling两个类及其使用进行说明。
Schedule类为调度计算中对调度结果的数组schedule进行处理的类,主要封装了从schedule数组中获得当前调度方案的一些绩效指标,例如最大完工时间、最大延误时间等。
Schedule类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
getCmaxIsumTime 获得特定调度方案的最大完工时间和设备空闲时间之和 |
|
getMaxFinishTime 获得特定调度方案的最大完工时间 |
|
getMaxLateTime 获得特定调度方案的最大延误时间长度 |
|
getSumLateTime 获得特定调度方案的延误时间之和 |
|
getTotalFinishTime 获得特定调度方案的各个作业完工时间之和 |
以如下的流水作业车间调度结果测试Schedule类中的方法
作业Id |
机器Id |
工序Id |
开工时间 |
完工时间 |
交付时间 |
1 |
1 |
1 |
0 |
375 |
510 |
1 |
2 |
2 |
375 |
387 |
510 |
1 |
3 |
3 |
387 |
529 |
510 |
1 |
4 |
4 |
529 |
774 |
510 |
1 |
5 |
5 |
774 |
1186 |
510 |
10 |
1 |
1 |
375 |
1271 |
6199 |
10 |
2 |
2 |
1271 |
2167 |
6199 |
10 |
3 |
3 |
2167 |
2381 |
6199 |
10 |
4 |
4 |
2381 |
2639 |
6199 |
10 |
5 |
5 |
2639 |
2898 |
6199 |
4 |
1 |
1 |
1271 |
1731 |
1790 |
4 |
2 |
2 |
2167 |
2709 |
1790 |
4 |
3 |
3 |
2709 |
3232 |
1790 |
4 |
4 |
4 |
3232 |
3352 |
1790 |
4 |
5 |
5 |
3352 |
3851 |
1790 |
3 |
1 |
1 |
2167 |
2179 |
1548 |
3 |
2 |
2 |
2709 |
3585 |
1548 |
3 |
3 |
3 |
3585 |
3709 |
1548 |
3 |
4 |
4 |
3709 |
4243 |
1548 |
3 |
5 |
5 |
4243 |
5008 |
1548 |
5 |
1 |
1 |
2709 |
3237 |
2777 |
5 |
2 |
2 |
3585 |
3686 |
2777 |
5 |
3 |
3 |
3709 |
4498 |
2777 |
5 |
4 |
4 |
4498 |
4622 |
2777 |
5 |
5 |
5 |
5008 |
6007 |
2777 |
9 |
1 |
1 |
3585 |
3842 |
6755 |
9 |
2 |
2 |
3842 |
4369 |
6755 |
9 |
3 |
3 |
4498 |
5251 |
6755 |
9 |
4 |
4 |
5251 |
5461 |
6755 |
9 |
5 |
5 |
6007 |
6470 |
6755 |
2 |
1 |
1 |
3842 |
4474 |
1370 |
2 |
2 |
2 |
4498 |
4950 |
1370 |
2 |
3 |
3 |
5251 |
6009 |
1370 |
2 |
4 |
4 |
6009 |
6287 |
1370 |
2 |
5 |
5 |
6470 |
6868 |
1370 |
6 |
1 |
1 |
4498 |
5294 |
3458 |
6 |
2 |
2 |
5294 |
5539 |
3458 |
6 |
3 |
3 |
6009 |
6641 |
3458 |
6 |
4 |
4 |
6641 |
7016 |
3458 |
6 |
5 |
5 |
7016 |
7139 |
3458 |
11 |
1 |
1 |
5294 |
5826 |
4366 |
11 |
2 |
2 |
6009 |
6311 |
4366 |
11 |
3 |
3 |
6641 |
7142 |
4366 |
11 |
4 |
4 |
7142 |
7907 |
4366 |
11 |
5 |
5 |
7907 |
8895 |
4366 |
8 |
1 |
1 |
6009 |
6023 |
6533 |
8 |
2 |
2 |
6641 |
6765 |
6533 |
8 |
3 |
3 |
7142 |
7356 |
6533 |
8 |
4 |
4 |
7907 |
8450 |
6533 |
8 |
5 |
5 |
8895 |
9680 |
6533 |
7 |
1 |
1 |
6641 |
7173 |
4588 |
7 |
2 |
2 |
7173 |
7403 |
4588 |
7 |
3 |
3 |
7907 |
8450 |
4588 |
7 |
4 |
4 |
8895 |
9791 |
4588 |
7 |
5 |
5 |
9791 |
10243 |
4588 |
该调度结果的甘特图如下:
使用Schedule类中封装的这些方法示例如下:
import easyopt.shopSch.Schedule; public class Example_Schedule { public void main(String[] args) { double[][] schedule= {{1,1,1,0,375,510},{1,2,2,375,387,510},{1,3,3,387,529,510},{1,4,4,529,774,510},{1,5,5,774,1186,510},{10,1,1,375,1271,6199},{10,2,2,1271,2167,6199},{10,3,3,2167,2381,6199},{10,4,4,2381,2639,6199},{10,5,5,2639,2898,6199},{4,1,1,1271,1731,1790},{4,2,2,2167,2709,1790},{4,3,3,2709,3232,1790},{4,4,4,3232,3352,1790},{4,5,5,3352,3851,1790},{3,1,1,2167,2179,1548},{3,2,2,2709,3585,1548},{3,3,3,3585,3709,1548},{3,4,4,3709,4243,1548},{3,5,5,4243,5008,1548},{5,1,1,2709,3237,2777},{5,2,2,3585,3686,2777},{5,3,3,3709,4498,2777},{5,4,4,4498,4622,2777},{5,5,5,5008,6007,2777},{9,1,1,3585,3842,6755},{9,2,2,3842,4369,6755},{9,3,3,4498,5251,6755},{9,4,4,5251,5461,6755},{9,5,5,6007,6470,6755},{2,1,1,3842,4474,1370},{2,2,2,4498,4950,1370},{2,3,3,5251,6009,1370},{2,4,4,6009,6287,1370},{2,5,5,6470,6868,1370},{6,1,1,4498,5294,3458},{6,2,2,5294,5539,3458},{6,3,3,6009,6641,3458},{6,4,4,6641,7016,3458},{6,5,5,7016,7139,3458},{11,1,1,5294,5826,4366},{11,2,2,6009,6311,4366},{11,3,3,6641,7142,4366},{11,4,4,7142,7907,4366},{11,5,5,7907,8895,4366},{8,1,1,6009,6023,6533},{8,2,2,6641,6765,6533},{8,3,3,7142,7356,6533},{8,4,4,7907,8450,6533},{8,5,5,8895,9680,6533},{7,1,1,6641,7173,4588},{7,2,2,7173,7403,4588},{7,3,3,7907,8450,4588},{7,4,4,8895,9791,4588},{7,5,5,9791,10243,4588}}; double[] cmaxIsumTime =Schedule.getCmaxIsumTime(schedule); double maxFinishTime = Schedule.getMaxFinishTime(schedule); double maxLateTime = Schedule.getMaxLateTime(schedule); double sumLateTime = Schedule.getSumLateTime(schedule); double sumFinishTime = Schedule.getTotalFinishTime(schedule); System.out.println("调度方案的最大完工时间= " + cmaxIsumTime[0] + " 设备空闲时间之和= " + cmaxIsumTime[1] ); System.out.println("调度方案的最大完工时间= " + maxFinishTime + " 最大延误时间= " + maxLateTime ); System.out.println("调度方案的延误时间之和= " + sumLateTime + " 完工时间之和= " + sumFinishTime ); } } |
执行结果如下:
调度方案的最大完工时间= 10243.0 设备空闲时间之和= 24125.0 调度方案的最大完工时间= 10243.0 最大延误时间= 5655.0 调度方案的延误时间之和= 31937.0 完工时间之和= 68245.0 |
其中:
(1)
最大完工时间为调度方案中每个订单完工时间【第五列数据】的最大值;
(2)
最大延误时间为每个订单最后一道工序的完工时间【第五列数据】与其交付时间【第六列数据】差值【必须大于0,即有延误】之中的最大值;
(3)
延误时间之和为每个订单最后一道工序的完工时间【第五列数据】与其交付时间【第六列数据】之差大于0的数值之和。
(4)
完工时间之和为每个订单最后一道工序的完工时间【第五列数据】之和。
(5)
设备空闲时间之和为每台设备开工和完工时间跨度减去在这个事件跨度内该设备的工作时长。
Scheduling类主要封装了复杂车间调度【混合流水车间、作业车间】运算过程中所使用的方法集合类,例如初始化订单列表和任务列表,或在运算中进行订单或任务列表处理的方法等。
Scheduling类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
getJobSchedule 按工序进行任务列表的更新:根据订单的排序【seq】和已经排定的任务列表【inTaskList】,将全部订单当前工序【procNo】的作业任务排定到任务列表中,从而形成新的任务列表。具体来说,在多工序排产运算中,需要根据工序依次对全部订单进行排定,即每个订单每个工序的任务排定在某台机器的特定时段:指定开工时间和完工时间。 |
|
getJobSchedule 按订单进行任务列表的更新:将订单列表【inOrderList】中的指定订单【orderId】排入到既有任务列表【inTaskList】以形成新的任务列表。 |
|
getProcMachIds 根据作业车间调度的工艺参数获取每个作业各道工序所用设备编码,设备编码从0开始 |
|
getProcTimes 根据作业车间调度的工艺参数获取每个作业各道工序所用作业时间 |
|
getSeqJobProcIds 根据作业车间调度的工艺参数和排序获得排序中每个位置作业的工序号,工序编号从0开始编码 |
|
initOrderListHFSP 根据作业工时和每道工序机器数量初始化混合流水车间的订单对象列表 |
|
initOrderListHFSP 根据作业工时、每道工序机器数量和作业释放时间初始化混合流水车间的订单对象列表 |
|
initOrderListJSP 根据作业工时初始化作业车间调度问题中的订单对象列表 |
|
initOrderListPMS 根据作业工时、作业释放时间初始化并行机调度问题中的订单对象列表 |
|
initOrderListPMS 根据作业工时、作业释放时间、交付时间初始化并行机调度问题中的订单对象列表 |
|
initTaskList 根据maxTime对全部machQty安排一个gap从0开始到maxTime结束,作业从maxTime到maxTime+1结束的任务, 形成调度问题的初始任务列表 |
Scheduling类中的方法主要是用于比较复杂的车间调度问题运算,例如复杂并行机、混合流水车间和作业车间调度问题。复杂并行机、混合流水车间和作业车间调度问题中,不同作业相同工序的任务可能会安排在不同的机器设备上,需要从可安排设备中寻找可以最早插入该任务的空闲时段,所以使用对象列表的方式表示已有调度任务要比使用数组的方式表示已有调度任务在程序运算方面要方便。有鉴于此,Scheduling类中设定了一些可以通过已知参数的数组转换为对象列表的方法。
例1: 根据如下并行机工时数据和释放时间数据,构建订单对象列表
orderId |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
procTime |
6.1 |
20.4 |
15.1 |
18.6 |
20.4 |
5.7 |
8.3 |
19.2 |
20.9 |
9.2 |
releaseTime |
6.7 |
9.7 |
4.1 |
5.7 |
7.7 |
1.3 |
5.8 |
1.2 |
1.4 |
4.6 |
实现代码如下;
import java.util.ArrayList; import easyopt.model.Order; import easyopt.shopSch.Scheduling; public class Example_Scheduling { public void main(String[] args) { // TODO Auto-generated method stub double[] procTimes = {6.1,20.4,15.1,18.6,20.4,5.7,8.3,19.2,20.9,9.2}; double[] releaseTimes = {6.7,9.7,4.1,5.7,7.7,1.3,5.8,1.2,1.4,4.6}; ArrayList<Order>
orderList = (ArrayList<Order>) Scheduling.initOrderListPMS(procTimes, releaseTimes); for(Order o : orderList) { System.out.println(o.toString()); } } } |
执行结果如下:
Order{orderId=0,
dueTime=0.0, releaseTime=6.7, procTime=6.1, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=1,
dueTime=0.0, releaseTime=9.7, procTime=20.4, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=2,
dueTime=0.0, releaseTime=4.1, procTime=15.1, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=3,
dueTime=0.0, releaseTime=5.7, procTime=18.6, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=4,
dueTime=0.0, releaseTime=7.7, procTime=20.4, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=5,
dueTime=0.0, releaseTime=1.3, procTime=5.7, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=6,
dueTime=0.0, releaseTime=5.8, procTime=8.3, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=7,
dueTime=0.0, releaseTime=1.2, procTime=19.2, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=8,
dueTime=0.0, releaseTime=1.4, procTime=20.9, nextProcId=0, preEndTime=0.0, processList=[]} Order{orderId=9, dueTime=0.0, releaseTime=4.6,
procTime=9.2, nextProcId=0, preEndTime=0.0, processList=[]} |
Order对象每个属性变量的含义请参看第四章。
例2:一个混合流水车间调度问题参数如下:
作业工序工时表
作业\工序 |
proc1 |
proc2 |
proc3 |
proc4 |
proc5 |
job1 |
375 |
12 |
142 |
245 |
412 |
job2 |
632 |
452 |
758 |
278 |
398 |
job3 |
12 |
876 |
124 |
534 |
765 |
job4 |
460 |
542 |
523 |
120 |
499 |
五道工序可用机器数量依次为1、2、1、2、2台,以最大完工时间最小化为目标进行作业排序,当作业排序为2、4、1、3时,其详细排产方案如何,最大完工时间为多少。
示例程序如下:
import java.util.ArrayList; import easyopt.common.EasyMath; import easyopt.model.Order; import easyopt.model.Task; import easyopt.shopSch.Scheduling; public class Example_Scheduling { public void main(String[] args) { double[][] ptimes = {{375,12,142,245,412},{632,452,758,278,398},{12,876,124,534,765},{460,542,523,120,499}}; int[] machQtys = {1,2,1,2,2}; int[] seq = {1,3,0,2}; //step1: 根据工时数据和每道工序机器数量生成订单任务列表 System.out.println(" ------------生成初始任务列表------------------- "); ArrayList<Order>
hfspOrderList = (ArrayList<Order>) Scheduling.initOrderListHFSP(ptimes, machQtys); for(Order o : hfspOrderList) { System.out.println(o.toString()); } //step2: 根据机器数量生成各个机器的初始任务列表,以方便后续任务的安排 System.out.println(" --------给每台机器生成一个具有充分大空闲时段的任务---- "); int machQty = EasyMath.sum(machQtys); double maxTime = EasyMath.sum(ptimes)*10;//充分大即可,以全部作业时间之和的10倍完全可以满足要求 ArrayList<Task>
tasks =(ArrayList<Task>) Scheduling.initTaskList(machQty, maxTime); for(Task t : tasks) { System.out.println(t.toString()); } //step3: 先将全部作业的第一道工序安排到任务列表 System.out.println(" ------------将第一道工序安排后的任务列表--------- "); tasks = (ArrayList<Task>)
Scheduling.getJobSchedule(seq, 0, hfspOrderList, tasks); for(Task t : tasks) { System.out.println(t.toString()); } //step4: 将全部作业的第二道工序安排到任务列表 System.out.println(" ------------将第二道工序安排后的任务列表--------"); tasks = (ArrayList<Task>)
Scheduling.getJobSchedule(seq, 1, hfspOrderList, tasks); for(Task t : tasks) { System.out.println(t.toString()); } //step5: 先将全部作业的第三道工序安排到任务列表 System.out.println(" ------------将第三道工序安排后的任务列表------- "); tasks = (ArrayList<Task>)
Scheduling.getJobSchedule(seq, 2, hfspOrderList, tasks); for(Task t : tasks) { System.out.println(t.toString()); } //step6: 将全部作业的第四道工序安排到任务列表 System.out.println(" ------------将第四道工序安排后的任务列表-------- "); tasks = (ArrayList<Task>)
Scheduling.getJobSchedule(seq, 3, hfspOrderList, tasks); for(Task t : tasks) { System.out.println(t.toString()); } //step7: 将全部作业的第五道工序安排到任务列表 System.out.println(" ------------将第五道工序安排后的任务列表-------- "); tasks = (ArrayList<Task>)
Scheduling.getJobSchedule(seq, 4, hfspOrderList, tasks); for(Task t : tasks) { System.out.println(t.toString()); } } } |
执行结果如下:
------------生成初始任务列表------------------- Order{orderId=0, dueTime=0.0, releaseTime=0.0, procTime=0.0, nextProcId=0,
preEndTime=0.0, processList=[Process{processId=0, machQty=1, machIndex=[0], splitQty=0,
cycleTime=375.0}, Process{processId=1, machQty=2, machIndex=[1, 2], splitQty=0,
cycleTime=12.0}, Process{processId=2, machQty=1, machIndex=[3], splitQty=0, cycleTime=142.0},
Process{processId=3, machQty=2, machIndex=[4, 5], splitQty=0, cycleTime=245.0},
Process{processId=4, machQty=2, machIndex=[6, 7], splitQty=0, cycleTime=412.0}]} Order{orderId=1, dueTime=0.0, releaseTime=0.0, procTime=0.0, nextProcId=0,
preEndTime=0.0, processList=[Process{processId=0, machQty=1, machIndex=[0], splitQty=0,
cycleTime=632.0}, Process{processId=1, machQty=2, machIndex=[1, 2], splitQty=0,
cycleTime=452.0}, Process{processId=2, machQty=1, machIndex=[3], splitQty=0, cycleTime=758.0},
Process{processId=3, machQty=2, machIndex=[4, 5], splitQty=0, cycleTime=278.0},
Process{processId=4, machQty=2, machIndex=[6, 7], splitQty=0, cycleTime=398.0}]} Order{orderId=2, dueTime=0.0, releaseTime=0.0, procTime=0.0, nextProcId=0,
preEndTime=0.0, processList=[Process{processId=0, machQty=1, machIndex=[0], splitQty=0,
cycleTime=12.0}, Process{processId=1, machQty=2, machIndex=[1, 2], splitQty=0,
cycleTime=876.0}, Process{processId=2, machQty=1, machIndex=[3], splitQty=0, cycleTime=124.0},
Process{processId=3, machQty=2, machIndex=[4, 5], splitQty=0, cycleTime=534.0},
Process{processId=4, machQty=2, machIndex=[6, 7], splitQty=0, cycleTime=765.0}]} Order{orderId=3, dueTime=0.0, releaseTime=0.0, procTime=0.0, nextProcId=0,
preEndTime=0.0, processList=[Process{processId=0, machQty=1, machIndex=[0], splitQty=0,
cycleTime=460.0}, Process{processId=1, machQty=2, machIndex=[1, 2], splitQty=0,
cycleTime=542.0}, Process{processId=2, machQty=1, machIndex=[3], splitQty=0, cycleTime=523.0},
Process{processId=3, machQty=2, machIndex=[4, 5], splitQty=0, cycleTime=120.0},
Process{processId=4, machQty=2, machIndex=[6, 7], splitQty=0, cycleTime=499.0}]} -------给每台机器生成一个具有充分大空闲时段的任务---- Task{machId=0, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=1, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=2, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=3, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=4, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=5, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=6, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=7, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} ------------将第一道工序安排后的任务列表--------- Task{machId=1, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=2, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=3, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=4, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=5, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=6, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=7, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=0, startTime=0.0, endTime=632.0, orderId=1, processId=0, gapEndTime=0.0,
gapStartTime=0.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=632.0, endTime=1092.0, orderId=3, processId=0, gapEndTime=632.0,
gapStartTime=632.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=1092.0, endTime=1467.0, orderId=0, processId=0,
gapEndTime=1092.0, gapStartTime=1092.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1479.0, gap=80111.0, releaseTime=0.0} Task{machId=0, startTime=1467.0, endTime=1479.0, orderId=2, processId=0,
gapEndTime=1467.0, gapStartTime=1467.0, gap=0.0, releaseTime=0.0} ------------将第二道工序安排后的任务列表-------- Task{machId=3, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=4, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=5, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=6, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=7, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=0, startTime=0.0, endTime=632.0, orderId=1, processId=0, gapEndTime=0.0,
gapStartTime=0.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=632.0, endTime=1092.0, orderId=3, processId=0, gapEndTime=632.0,
gapStartTime=632.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=1092.0, endTime=1467.0, orderId=0, processId=0,
gapEndTime=1092.0, gapStartTime=1092.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1479.0, gap=80111.0, releaseTime=0.0} Task{machId=0, startTime=1467.0, endTime=1479.0, orderId=2, processId=0,
gapEndTime=1467.0, gapStartTime=1467.0, gap=0.0, releaseTime=0.0} Task{machId=1, startTime=632.0, endTime=1084.0, orderId=1, processId=1, gapEndTime=632.0,
gapStartTime=0.0, gap=632.0, releaseTime=0.0} Task{machId=2, startTime=1092.0, endTime=1634.0, orderId=3, processId=1,
gapEndTime=1092.0, gapStartTime=0.0, gap=1092.0, releaseTime=0.0} Task{machId=1, startTime=1467.0, endTime=1479.0, orderId=0, processId=1,
gapEndTime=1467.0, gapStartTime=1084.0, gap=383.0, releaseTime=0.0} Task{machId=1, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2355.0, gap=79235.0, releaseTime=0.0} Task{machId=2, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1634.0, gap=79956.0, releaseTime=0.0} Task{machId=1, startTime=1479.0, endTime=2355.0, orderId=2, processId=1,
gapEndTime=1479.0, gapStartTime=1479.0, gap=0.0, releaseTime=0.0} ------------将第三道工序安排后的任务列表------- Task{machId=4, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=5, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=6, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=7, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=0, startTime=0.0, endTime=632.0, orderId=1, processId=0, gapEndTime=0.0,
gapStartTime=0.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=632.0, endTime=1092.0, orderId=3, processId=0, gapEndTime=632.0,
gapStartTime=632.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=1092.0, endTime=1467.0, orderId=0, processId=0,
gapEndTime=1092.0, gapStartTime=1092.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1479.0, gap=80111.0, releaseTime=0.0} Task{machId=0, startTime=1467.0, endTime=1479.0, orderId=2, processId=0,
gapEndTime=1467.0, gapStartTime=1467.0, gap=0.0, releaseTime=0.0} Task{machId=1, startTime=632.0, endTime=1084.0, orderId=1, processId=1, gapEndTime=632.0,
gapStartTime=0.0, gap=632.0, releaseTime=0.0} Task{machId=2, startTime=1092.0, endTime=1634.0, orderId=3, processId=1,
gapEndTime=1092.0, gapStartTime=0.0, gap=1092.0, releaseTime=0.0} Task{machId=1, startTime=1467.0, endTime=1479.0, orderId=0, processId=1,
gapEndTime=1467.0, gapStartTime=1084.0, gap=383.0, releaseTime=0.0} Task{machId=1, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2355.0, gap=79235.0, releaseTime=0.0} Task{machId=2, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1634.0, gap=79956.0, releaseTime=0.0} Task{machId=1, startTime=1479.0, endTime=2355.0, orderId=2, processId=1,
gapEndTime=1479.0, gapStartTime=1479.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=1084.0, endTime=1842.0, orderId=1, processId=2,
gapEndTime=1084.0, gapStartTime=0.0, gap=1084.0, releaseTime=0.0} Task{machId=3, startTime=1842.0, endTime=2365.0, orderId=3, processId=2,
gapEndTime=1842.0, gapStartTime=1842.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=2365.0, endTime=2507.0, orderId=0, processId=2,
gapEndTime=2365.0, gapStartTime=2365.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2631.0, gap=78959.0, releaseTime=0.0} Task{machId=3, startTime=2507.0, endTime=2631.0, orderId=2, processId=2,
gapEndTime=2507.0, gapStartTime=2507.0, gap=0.0, releaseTime=0.0} ------------将第四道工序安排后的任务列表-------- Task{machId=6, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=7, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=0.0, gap=81590.0, releaseTime=0.0} Task{machId=0, startTime=0.0, endTime=632.0, orderId=1, processId=0, gapEndTime=0.0,
gapStartTime=0.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=632.0, endTime=1092.0, orderId=3, processId=0, gapEndTime=632.0,
gapStartTime=632.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=1092.0, endTime=1467.0, orderId=0, processId=0,
gapEndTime=1092.0, gapStartTime=1092.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1479.0, gap=80111.0, releaseTime=0.0} Task{machId=0, startTime=1467.0, endTime=1479.0, orderId=2, processId=0,
gapEndTime=1467.0, gapStartTime=1467.0, gap=0.0, releaseTime=0.0} Task{machId=1, startTime=632.0, endTime=1084.0, orderId=1, processId=1, gapEndTime=632.0,
gapStartTime=0.0, gap=632.0, releaseTime=0.0} Task{machId=2, startTime=1092.0, endTime=1634.0, orderId=3, processId=1,
gapEndTime=1092.0, gapStartTime=0.0, gap=1092.0, releaseTime=0.0} Task{machId=1, startTime=1467.0, endTime=1479.0, orderId=0, processId=1,
gapEndTime=1467.0, gapStartTime=1084.0, gap=383.0, releaseTime=0.0} Task{machId=1, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2355.0, gap=79235.0, releaseTime=0.0} Task{machId=2, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1634.0, gap=79956.0, releaseTime=0.0} Task{machId=1, startTime=1479.0, endTime=2355.0, orderId=2, processId=1,
gapEndTime=1479.0, gapStartTime=1479.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=1084.0, endTime=1842.0, orderId=1, processId=2,
gapEndTime=1084.0, gapStartTime=0.0, gap=1084.0, releaseTime=0.0} Task{machId=3, startTime=1842.0, endTime=2365.0, orderId=3, processId=2,
gapEndTime=1842.0, gapStartTime=1842.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=2365.0, endTime=2507.0, orderId=0, processId=2,
gapEndTime=2365.0, gapStartTime=2365.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2631.0, gap=78959.0, releaseTime=0.0} Task{machId=3, startTime=2507.0, endTime=2631.0, orderId=2, processId=2,
gapEndTime=2507.0, gapStartTime=2507.0, gap=0.0, releaseTime=0.0} Task{machId=4, startTime=1842.0, endTime=2120.0, orderId=1, processId=3,
gapEndTime=1842.0, gapStartTime=0.0, gap=1842.0, releaseTime=0.0} Task{machId=5, startTime=2365.0, endTime=2485.0, orderId=3, processId=3,
gapEndTime=2365.0, gapStartTime=0.0, gap=2365.0, releaseTime=0.0} Task{machId=4, startTime=2507.0, endTime=2752.0, orderId=0, processId=3,
gapEndTime=2507.0, gapStartTime=2120.0, gap=387.0, releaseTime=0.0} Task{machId=5, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=3165.0, gap=78425.0, releaseTime=0.0} Task{machId=4, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2752.0, gap=78838.0, releaseTime=0.0} Task{machId=5, startTime=2631.0, endTime=3165.0, orderId=2, processId=3,
gapEndTime=2631.0, gapStartTime=2485.0, gap=146.0, releaseTime=0.0} ------------将第五道工序安排后的任务列表-------- Task{machId=0, startTime=0.0, endTime=632.0, orderId=1, processId=0, gapEndTime=0.0,
gapStartTime=0.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=632.0, endTime=1092.0, orderId=3, processId=0, gapEndTime=632.0,
gapStartTime=632.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=1092.0, endTime=1467.0, orderId=0, processId=0,
gapEndTime=1092.0, gapStartTime=1092.0, gap=0.0, releaseTime=0.0} Task{machId=0, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1479.0, gap=80111.0, releaseTime=0.0} Task{machId=0, startTime=1467.0, endTime=1479.0, orderId=2, processId=0,
gapEndTime=1467.0, gapStartTime=1467.0, gap=0.0, releaseTime=0.0} Task{machId=1, startTime=632.0, endTime=1084.0, orderId=1, processId=1, gapEndTime=632.0,
gapStartTime=0.0, gap=632.0, releaseTime=0.0} Task{machId=2, startTime=1092.0, endTime=1634.0, orderId=3, processId=1,
gapEndTime=1092.0, gapStartTime=0.0, gap=1092.0, releaseTime=0.0} Task{machId=1, startTime=1467.0, endTime=1479.0, orderId=0, processId=1,
gapEndTime=1467.0, gapStartTime=1084.0, gap=383.0, releaseTime=0.0} Task{machId=1, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2355.0, gap=79235.0, releaseTime=0.0} Task{machId=2, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=1634.0, gap=79956.0, releaseTime=0.0} Task{machId=1, startTime=1479.0, endTime=2355.0, orderId=2, processId=1,
gapEndTime=1479.0, gapStartTime=1479.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=1084.0, endTime=1842.0, orderId=1, processId=2,
gapEndTime=1084.0, gapStartTime=0.0, gap=1084.0, releaseTime=0.0} Task{machId=3, startTime=1842.0, endTime=2365.0, orderId=3, processId=2,
gapEndTime=1842.0, gapStartTime=1842.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=2365.0, endTime=2507.0, orderId=0, processId=2,
gapEndTime=2365.0, gapStartTime=2365.0, gap=0.0, releaseTime=0.0} Task{machId=3, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2631.0, gap=78959.0, releaseTime=0.0} Task{machId=3, startTime=2507.0, endTime=2631.0, orderId=2, processId=2,
gapEndTime=2507.0, gapStartTime=2507.0, gap=0.0, releaseTime=0.0} Task{machId=4, startTime=1842.0, endTime=2120.0, orderId=1, processId=3,
gapEndTime=1842.0, gapStartTime=0.0, gap=1842.0, releaseTime=0.0} Task{machId=5, startTime=2365.0, endTime=2485.0, orderId=3, processId=3,
gapEndTime=2365.0, gapStartTime=0.0, gap=2365.0, releaseTime=0.0} Task{machId=4, startTime=2507.0, endTime=2752.0, orderId=0, processId=3,
gapEndTime=2507.0, gapStartTime=2120.0, gap=387.0, releaseTime=0.0} Task{machId=5, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=3165.0, gap=78425.0, releaseTime=0.0} Task{machId=4, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=2752.0, gap=78838.0, releaseTime=0.0} Task{machId=5, startTime=2631.0, endTime=3165.0, orderId=2, processId=3,
gapEndTime=2631.0, gapStartTime=2485.0, gap=146.0, releaseTime=0.0} Task{machId=6, startTime=2120.0, endTime=2518.0, orderId=1, processId=4,
gapEndTime=2120.0, gapStartTime=0.0, gap=2120.0, releaseTime=0.0} Task{machId=7, startTime=2485.0, endTime=2984.0, orderId=3, processId=4,
gapEndTime=2485.0, gapStartTime=0.0, gap=2485.0, releaseTime=0.0} Task{machId=6, startTime=2752.0, endTime=3164.0, orderId=0, processId=4,
gapEndTime=2752.0, gapStartTime=2518.0, gap=234.0, releaseTime=0.0} Task{machId=7, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=3930.0, gap=77660.0, releaseTime=0.0} Task{machId=6, startTime=81590.0, endTime=81591.0, orderId=-1, processId=0,
gapEndTime=81590.0, gapStartTime=3164.0, gap=78426.0, releaseTime=0.0} Task{machId=7, startTime=3165.0, endTime=3930.0, orderId=2, processId=4,
gapEndTime=3165.0, gapStartTime=2984.0, gap=181.0, releaseTime=0.0} |
最后一个tasks列表输出的为最终的详细排产方案,其中排除orderId=-1的任务项【该任务项为各个机器最右侧的任务项,为计算过程初始化形成的虚拟任务】,其他的任务项则为各个作业每道工序的具体排产,其中最大的完工时间为最后一个安排的任务的endTime:3930。最终排产任务的调度方案甘特图如下所示。
Scheduling类中流水车间的相关方法使用过程类似,这里不再赘述。
easyopt.shopSch.pms包中主要包含并行机调度计算和优化过程中涉及的类和方法。easyopt.shopSch.pms包中的类及其功能如下表。
类名 |
功能说明 |
MooPMS |
多目标并行机优化相关计算程序 |
PMS |
普通并行机调度中使用的一些方法和优化算法 |
SynPMS |
同步启停并行机调度计算中使用的一些方法和优化算法 |
QmPMS |
异质并行机并行机调度计算中使用的一些方法和优化算法 |
PMS类主要封装了对并行机调度计算和优化中涉及的方法。
PMS类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
|
getSingleStagePMSch 基于作业时间、作业排序和机器数量获得并行机【单阶段同质并行机,具有交付时间的】详细调度方案 |
|
getSingleStagePMSch 基于作业时间、作业排序和机器数量获得并行机【单阶段同质并行机,具有交付时间的】详细调度方案 |
|
getSingleStagePMSch 基于作业时间、作业排序和机器数量获得并行机【单阶段同质并行机】详细调度方案 |
|
getSingleStagePMSch 基于作业时间、作业排序、调整时间和机器数量获得并行机【单阶段同质并行机】详细调度方案 |
|
optPMSCmaxByACO 利用蚁群算法进行单阶段并行机Pm||Cmax问题的优化求解 |
|
optPMSCmaxByGA 利用遗传算法进行单阶段并行机Pm||Cmax问题的优化求解 |
|
optPMSCmaxByPSO 利用粒子群算法进行单阶段并行机Pm||Cmax问题的优化求解 |
|
optPMSCmaxBySA 利用模拟退火算法进行单阶段并行机Pm||Cmax问题的优化求解 |
|
optPMSCmaxByTLBO 利用教学算法进行单阶段并行机Pm||Cmax问题的优化求解 |
|
optPMSLmaxByACO 利用蚁群算法进行单阶段并行机Pm||Lmax问题的优化求解 |
|
optPMSLmaxByGA 利用遗传算法进行单阶段并行机Pm||Lmax问题的优化求解 |
|
optPMSLmaxByPSO 利用粒子群算法进行单阶段并行机Pm||Lmax问题的优化求解 |
|
optPMSLmaxBySA 利用模拟退火算法进行单阶段并行机Pm||Lmax问题的优化求解 |
|
optPMSLmaxByTLBO 利用教学算法进行置单阶段并行机Pm||Lmax问题的优化求解 |
|
optPMSLtotalByACO 利用蚁群算法进行单阶段并行机Pm||Ltotal问题的优化求解 |
|
optPMSLtotalByGA 利用遗传算法进行单阶段并行机Pm||Ltotal问题的优化求解 |
|
optPMSLtotalByPSO 利用粒子群算法进行单阶段并行机Pm||Ltotal问题的优化求解 |
|
optPMSLtotalBySA 利用模拟退火算法进行单阶段并行机Pm||Ltotal问题的优化求解 |
|
optPMSLtotalByTLBO 利用教学算法进行单阶段并行机Pm||Ltotal问题的优化求解 |
|
optPMSRjLmaxByACO 利用蚁群算法进行单阶段并行机Pm|rj|Lmax问题的优化求解 |
|
optPMSRjLmaxByGA 利用遗传算法进行单阶段并行机Pm|rj|Lmax问题的优化求解 |
|
optPMSRjLmaxByPSO 利用粒子群算法进行单阶段并行机Pm|rj|Lmax问题的优化求解 |
|
optPMSRjLmaxBySA 利用模拟退火算法进行单阶段并行机Pm|rj|Lmax问题的优化求解 |
|
optPMSRjLmaxByTLBO 利用教学算法进行单阶段并行机Pm|rj|Lmax问题的优化求解 |
|
optPMSSjCmaxByACO 利用蚁群算法进行单阶段并行机Pm|sij|Cmax问题的优化求解 |
|
optPMSSjCmaxByGA 利用遗传算法进行单阶段并行机Pm|sij|Cmax问题的优化求解 |
|
optPMSSjCmaxByPSO 利用粒子群算法进行单阶段并行机Pm|sij|Cmax问题的优化求解 |
|
optPMSSjCmaxBySA 利用模拟退火算法进行单阶段并行机Pm|sij|Cmax问题的优化求解 |
|
optPMSSjCmaxByTLBO 利用教学算法进行单阶段并行机Pm|sij|Cmax问题的优化求解 |
|
optPMSSynByEDD 利用交付时间优先进行单阶段同步启停并行机Pm|rj,syn|#问题的求解 |
|
optPMSSynByFCFS 利用先来先服务规则进行单阶段同步启停并行机Pm|rj,syn|#问题的求解 |
|
optPMSSynCmaxByFCFS 利用先来先服务规则进行单阶段同步启停并行机Pm|rj,syn|#问题的求解 |
|
optPMSSynRjCmaxByACO 利用蚁群算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
|
optPMSSynRjCmaxByGA 利用遗传算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
|
optPMSSynRjCmaxByPSO 利用粒子群算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
|
optPMSSynRjCmaxBySA 利用模拟退火算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
|
optPMSSynRjCmaxByTLBO 利用教学算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
|
optPMSSynRjLmaxByACO 利用蚁群算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
|
optPMSSynRjLmaxByGA 利用遗传算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
|
optPMSSynRjLmaxByPSO 利用粒子群算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
|
optPMSSynRjLmaxBySA 利用模拟退火算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
|
optPMSSynRjLmaxByTLBO 利用教学算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
普通并行机一般指同质并行机,而且作业排序没有特殊的约束。下面分别以示例的方式说明进行普通并行机排序计算和优化求解的实现过程,据此演示PMS类中相关方法的使用。
例1:假设有一批作业任务需要在3台同质并行机上排产,每项作业的加工工时如下表所示,若按顺序排产则最早完工时间为多少?若按倒序排产则最早完工时间又为多少?
JobId |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
ProcTime |
6 |
5 |
10 |
13 |
9 |
23 |
22 |
10 |
19 |
5 |
9 |
11 |
10 |
17 |
该问题需要先通过当前参数生成详细的排产方案,然后对排产方案计算最大完工时间。该问题需要使用如下的getSingleStagePMSch方法
public double[][]
getSingleStagePMSch(double[] ptimes,
int[] seq,
int machQty) 基于作业时间、作业排序和机器数量获得并行机【单阶段同质并行机】详细调度方案 参数: ptimes - 作业时间 seq - 作业排序数组,从1开始编号 machQty - 并行机数量 返回: 返回调度排序的二维数组,共五列,第一列:作业编号,第二类:机器编号,第三列:工序编号
第四列:开工时间,第五列:完工时间,第三列是为了同多阶段车间调度统一化预留的一列,在单阶段调度中无用 |
根据该方法的介绍,程序实现如下:
import easyopt.common.EasyArray; import easyopt.shopSch.Schedule; import easyopt.shopSch.pms.PMS; public class Example_PMS { public static void main(String[] args) { double[] ptimes = {6,5,10,13,9,23,22,10,19,5,9,11,10,17}; int[] seq = {1,2,3,4,5,6,7,8,9,10,11,12,13,14}; int[] seq2 = {14,13,12,11,10,9,8,7,6,5,4,3,2,1}; int machQty =3 ; PMS
pms =new PMS(); double[][] schedule = pms.getSingleStagePMSch(ptimes, seq, machQty); System.out.println("----具体调度方案如下-----"); EasyArray.printArray(schedule); System.out.println("----最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(schedule)); double[][] schedule2 = pms.getSingleStagePMSch(ptimes, seq2, machQty); System.out.println("----倒序排序的具体调度方案如下-----"); EasyArray.printArray(schedule2); System.out.println("----倒序排序的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(schedule2)); } } |
执行结果如下:
----具体调度方案如下----- 1.0 1.0 0.0 0.0 6.0 ; 2.0 2.0 0.0 0.0 5.0 ; 3.0 3.0 0.0 0.0 10.0 ; 4.0 2.0 0.0 5.0 18.0 ; 5.0 1.0 0.0 6.0 15.0 ; 6.0 3.0 0.0 10.0 33.0 ; 7.0 1.0 0.0 15.0 37.0 ; 8.0 2.0 0.0 18.0 28.0 ; 9.0 2.0 0.0 28.0 47.0 ; 10.0 3.0 0.0 33.0 38.0 ; 11.0 1.0 0.0 37.0 46.0 ; 12.0 3.0 0.0 38.0 49.0 ; 13.0 1.0 0.0 46.0 56.0 ; 14.0 2.0 0.0 47.0 64.0 ; ----最大完工时间为----- 64.0 ----倒序排序的具体调度方案如下----- 14.0 1.0 0.0 0.0 17.0 ; 13.0 2.0 0.0 0.0 10.0 ; 12.0 3.0 0.0 0.0 11.0 ; 11.0 2.0 0.0 10.0 19.0 ; 10.0 3.0 0.0 11.0 16.0 ; 9.0 3.0 0.0 16.0 35.0 ; 8.0 1.0 0.0 17.0 27.0 ; 7.0 2.0 0.0 19.0 41.0 ; 6.0 1.0 0.0 27.0 50.0 ; 5.0 3.0 0.0 35.0 44.0 ; 4.0 2.0 0.0 41.0 54.0 ; 3.0 3.0 0.0 44.0 54.0 ; 2.0 1.0 0.0 50.0 55.0 ; 1.0 3.0 0.0 54.0 60.0 ; ----倒序排序的最大完工时间为----- 60.0 |
从结果可以看出,顺序排序的最大完工时间【64】要比逆序排序的最大完工时间【60】大。
例2:还是以例1的并行机工时数据和机器数量为例,分别使用模拟退火算法、遗传算法、粒子群算法、蚁群算法和教学算法进行该问题的优化求解,获取最大完工时间最小的排序。
其中:
该问题的模拟退火算法优化方法具体参数和设定要求为:
public SchOptResult optPMSCmaxBySA(double[] ptimes, int machQty, double[] params)
利用模拟退火算法进行单阶段并行机Pm||Cmax问题的优化求解 参数:
返回: 返回优化计算的调度结果对象SchOptResult,其变量schedule为具体调度方案的二维数组,
共五列,第一列:作业编号,第二类:机器编号,第三列:工序编号, 第四列:开工时间,第五列:完工时间; 其变量optSeries为迭代收敛曲线,第一列为进化代数,第二列为迄今为止最优目标函数值,第三列为当前代的最优解 |
该问题的遗传算法优化方法具体参数和设定要求为:
public SchOptResult optPMSCmaxByGA(double[] ptimes, int machQty, double[] params)
利用遗传算法进行单阶段并行机Pm||Cmax问题的优化求解
参数: ptimes - 作业时间 machQty - 并行机数量 params - 遗传算法的相关参数,0-迭代代数,1-种群规模,2-交叉概率,3-变异概率,4-无更新终止代数 返回:
返回优化计算的调度结果对象SchOptResult,其变量schedule为具体调度方案的二维数组,
共五列,第一列:作业编号,第二类:机器编号,第三列:工序编号, 第四列:开工时间,第五列:完工时间; 其变量optSeries为迭代收敛曲线,第一列为进化代数,第二列为迄今为止最优目标函数值,第三列为当前代的最优解 |
该问题的粒子群算法优化方法具体参数和设定要求为:
public SchOptResult optPMSCmaxByPSO(double[] ptimes, int machQty, double[] params)
利用粒子群算法进行单阶段并行机Pm||Cmax问题的优化求解 参数:
返回: 返回优化计算的调度结果对象SchOptResult,其变量schedule为具体调度方案的二维数组,
共五列,第一列:作业编号,第二类:机器编号,第三列:工序编号, 第四列:开工时间,第五列:完工时间; 其变量optSeries为迭代收敛曲线,第一列为进化代数,第二列为迄今为止最优目标函数值,第三列为当前代的最优解 |
该问题的蚁群算法优化方法具体参数和设定要求为:
public SchOptResult optPMSCmaxByACO(double[] ptimes, int machQty, double[] params)
利用蚁群算法进行单阶段并行机Pm||Cmax问题的优化求解 参数:
返回: 返回优化计算的调度结果对象SchOptResult,其变量schedule为具体调度方案的二维数组,
共五列,第一列:作业编号,第二类:机器编号,第三列:工序编号, 第四列:开工时间,第五列:完工时间; 其变量optSeries为迭代收敛曲线,第一列为进化代数,第二列为迄今为止最优目标函数值,第三列为当前代的最优解 |
该问题的教学算法优化方法具体参数和设定要求为:
public SchOptResult optPMSCmaxByTLBO(double[] ptimes, int machQty, double[] params)
利用教学算法进行单阶段并行机Pm||Cmax问题的优化求解 参数:
返回: 返回优化计算的调度结果对象SchOptResult,其变量schedule为具体调度方案的二维数组,
共五列,第一列:作业编号,第二类:机器编号,第三列:工序编号, 第四列:开工时间,第五列:完工时间; 其变量optSeries为迭代收敛曲线,第一列为进化代数,第二列为迄今为止最优目标函数值,第三列为当前代的最优解 |
根据上述各个方法的参数及其说明,设计示例问题的优化程序如下:
import easyopt.common.EasyArray; import easyopt.shopSch.SchOptResult; import easyopt.shopSch.Schedule; import easyopt.shopSch.pms.PMS; public class Example_PMSopt { public static void main(String[] args) { double[] ptimes =
{6,5,10,13,9,23,22,10,19,5,9,11,10,17}; int machQty =3 ; double[] saParas = {0.992,40,400,70}; double[] gaParas =
{400,40,0.7,0.6,70}; double[] acoParas = {0.2,40,400,70}; double[] psoParas =
{0.9,2,2,40,400,70}; double[] tlboParas = {40,400,70}; PMS
pms =new PMS(); SchOptResult
saResult = pms.optPMSCmaxBySA(ptimes, machQty, saParas); SchOptResult
gaResult = pms.optPMSCmaxByGA(ptimes, machQty, gaParas); SchOptResult
acoResult = pms.optPMSCmaxByACO(ptimes, machQty, acoParas); SchOptResult
psoResult = pms.optPMSCmaxByPSO(ptimes, machQty, psoParas) ; SchOptResult
tlboResult = pms.optPMSCmaxByTLBO(ptimes, machQty, tlboParas) ; System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
优化输出结果如下:
----模拟退火算法获得的最优排序调度方案如下----- 11.0 1.0 0.0 0.0 9.0 ; 4.0 2.0 0.0 0.0 13.0 ; 5.0 3.0 0.0 0.0 9.0 ; 2.0 3.0 0.0 9.0 14.0 ; 9.0 1.0 0.0 9.0 28.0 ; 13.0 2.0 0.0 13.0 23.0 ; 7.0 3.0 0.0 14.0 36.0 ; 6.0 2.0 0.0 23.0 46.0 ; 14.0 1.0 0.0 28.0 45.0 ; 8.0 3.0 0.0 36.0 46.0 ; 12.0 1.0 0.0 45.0 56.0 ; 3.0 3.0 0.0 46.0 56.0 ; 1.0 2.0 0.0 46.0 52.0 ; 10.0 2.0 0.0 52.0 57.0 ; ----模拟退火算法获得的最大完工时间为----- 57.0 ----遗传算法获得的最优排序调度方案如下----- 5.0 1.0 0.0 0.0 9.0 ; 4.0 2.0 0.0 0.0 13.0 ; 9.0 3.0 0.0 0.0 19.0 ; 7.0 1.0 0.0 9.0 31.0 ; 11.0 2.0 0.0 13.0 22.0 ; 14.0 3.0 0.0 19.0 36.0 ; 6.0 2.0 0.0 22.0 45.0 ; 12.0 1.0 0.0 31.0 42.0 ; 3.0 3.0 0.0 36.0 46.0 ; 13.0 1.0 0.0 42.0 52.0 ; 1.0 2.0 0.0 45.0 51.0 ; 8.0 3.0 0.0 46.0 56.0 ; 2.0 2.0 0.0 51.0 56.0 ; 10.0 1.0 0.0 52.0 57.0 ; ----遗传算法获得的最大完工时间为----- 57.0 ----粒子群算法获得的最优排序调度方案如下----- 4.0 1.0 0.0 0.0 13.0 ; 14.0 2.0 0.0 0.0 17.0 ; 7.0 3.0 0.0 0.0 22.0 ; 13.0 1.0 0.0 13.0 23.0 ; 9.0 2.0 0.0 17.0 36.0 ; 8.0 3.0 0.0 22.0 32.0 ; 2.0 1.0 0.0 23.0 28.0 ; 1.0 1.0 0.0 28.0 34.0 ; 12.0 3.0 0.0 32.0 43.0 ; 6.0 1.0 0.0 34.0 57.0 ; 3.0 2.0 0.0 36.0 46.0 ; 11.0 3.0 0.0 43.0 52.0 ; 5.0 2.0 0.0 46.0 55.0 ; 10.0 3.0 0.0 52.0 57.0 ; ----粒子群算法获得的最大完工时间为----- 57.0 ----蚁群算法获得的最优排序调度方案如下----- 4.0 1.0 0.0 0.0 13.0 ; 10.0 2.0 0.0 0.0 5.0 ; 12.0 3.0 0.0 0.0 11.0 ; 3.0 2.0 0.0 5.0 15.0 ; 6.0 3.0 0.0 11.0 34.0 ; 1.0 1.0 0.0 13.0 19.0 ; 11.0 2.0 0.0 15.0 24.0 ; 5.0 1.0 0.0 19.0 28.0 ; 7.0 2.0 0.0 24.0 46.0 ; 9.0 1.0 0.0 28.0 47.0 ; 14.0 3.0 0.0 34.0 51.0 ; 8.0 2.0 0.0 46.0 56.0 ; 13.0 1.0 0.0 47.0 57.0 ; 2.0 3.0 0.0 51.0 56.0 ; ----蚁群算法获得的最大完工时间为----- 57.0 ----教学算法获得的最优排序调度方案如下----- 9.0 1.0 0.0 0.0 19.0 ; 7.0 2.0 0.0 0.0 22.0 ; 14.0 3.0 0.0 0.0 17.0 ; 4.0 3.0 0.0 17.0 30.0 ; 1.0 1.0 0.0 19.0 25.0 ; 8.0 2.0 0.0 22.0 32.0 ; 6.0 1.0 0.0 25.0 48.0 ; 12.0 3.0 0.0 30.0 41.0 ; 3.0 2.0 0.0 32.0 42.0 ; 10.0 3.0 0.0 41.0 46.0 ; 13.0 2.0 0.0 42.0 52.0 ; 11.0 3.0 0.0 46.0 55.0 ; 5.0 1.0 0.0 48.0 57.0 ; 2.0 2.0 0.0 52.0 57.0 ; ----教学算法获得的最大完工时间为----- 57.0 |
从优化结果可以看出,由于该问题规模相对较小,几种算法最后都获得了57这个较小的完工时间。同时,也可以看出,获得57这样小的最大完工时间的作业排序有多种,分别为:
(1)11、4、5、2、9、13、7、6、14、8、12、3、1、10【模拟退火的结果】
(2)5、4、9、7、11、14、6、12、3、13、1、8、2、10【遗传算法的结果】
(3)4、14、7、13、9、8、2、1、12、6、3、11、5、10【粒子群算法的结果】
(4)4、10、12、3、6、1、11、5、7、9、14、8、13、2【蚁群算法的结果】
(5)9、7、14、4、1、8、6、12、3、10、13、11、5、2【教学算法的结果】
前述示例对使用PMS类中的方法进行最简单并行机调度优化求解过程进行描述,其他包含释放时间、交付时间或调整时间的并行机调度问题优化求解过程与之类似,只是使用过程中要选择不同的方法而已。
QmPMS类主要封装了对异质并行机调度计算和优化中涉及的方法。
QmPMS类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getSingleStageQmSch(double[][] ptimes, double[] dueTimes,
int[] seq) 基于作业时间、作业排序获得Qm并行机【单阶段异质并行机】详细调度方案 |
double[][] |
getSingleStageQmSch(double[][] ptimes, int[] seq) 基于作业时间、作业排序获得Qm并行机【单阶段异质并行机】详细调度方案 |
SchOptResult |
optQmCmaxByACO(double[][] ptimes, double[] params) 利用蚁群算法进行单阶段并行机Qm||Cmax问题的优化求解 |
SchOptResult |
optQmCmaxByGA(double[][] ptimes, double[] params) 利用遗传算法进行单阶段并行机Qm||Cmax问题的优化求解 |
SchOptResult |
optQmCmaxByPSO(double[][] ptimes, double[] params) 利用粒子群算法进行单阶段并行机Qm||Cmax问题的优化求解 |
SchOptResult |
optQmCmaxBySA(double[][] ptimes, double[] params) 利用模拟退火算法进行单阶段并行机Qm||Cmax问题的优化求解 |
SchOptResult |
optQmCmaxByTLBO(double[][] ptimes, double[] params) 利用教学算法进行单阶段并行机Qm||Cmax问题的优化求解 |
SchOptResult |
optQmLmaxByACO(double[][] ptimes, double[] dueTimes, double[]
params) 利用蚁群算法进行单阶段并行机Qm||Lmax问题的优化求解 |
SchOptResult |
optQmLmaxByGA(double[][] ptimes, double[] dueTimes, double[]
params) 利用遗传算法进行单阶段并行机Qm||Lmax问题的优化求解 |
SchOptResult |
optQmLmaxByPSO(double[][] ptimes, double[] dueTimes, double[]
params) 利用粒子群算法进行单阶段并行机Qm||Lmax问题的优化求解 |
SchOptResult |
optQmLmaxBySA(double[][] ptimes, double[] dueTimes, double[]
params) 利用模拟退火算法进行单阶段并行机Qm||Lmax问题的优化求解 |
SchOptResult |
optQmLmaxByTLBO(double[][] ptimes, double[] dueTimes, double[]
params) 利用教学算法进行单阶段并行机Qm||Lmax问题的优化求解 |
异质并行机指的是并行机的加工能力存在差异,也即同一项作业在不同机器上的加工时间存在差异。下面分别以示例的方式说明进行异质并行机排序计算和优化求解的实现过程,据此演示PMS类中相关方法的使用。
例1:假设有一批作业任务需要在4台异质并行机上排产,每项作业的加工工时如下表所示,若按顺序排产则最早完工时间为多少?若按倒序排产则最早完工时间又为多少?
JobId |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Mach1 |
20 |
10 |
25 |
36 |
13 |
35 |
33 |
24 |
32 |
20 |
12 |
30 |
28 |
24 |
10 |
28 |
9 |
38 |
37 |
10 |
Mach2 |
25 |
11 |
25 |
41 |
12 |
33 |
35 |
29 |
34 |
17 |
17 |
31 |
31 |
23 |
16 |
29 |
10 |
33 |
43 |
15 |
Mach3 |
25 |
12 |
25 |
41 |
14 |
30 |
32 |
28 |
37 |
19 |
18 |
31 |
36 |
21 |
14 |
28 |
15 |
35 |
39 |
18 |
Mach4 |
24 |
8 |
24 |
41 |
8 |
30 |
26 |
23 |
31 |
17 |
15 |
33 |
34 |
26 |
14 |
25 |
8 |
35 |
40 |
10 |
该问题需要先通过当前参数生成详细的排产方案,然后对排产方案计算最大完工时间。该问题需要使用如下的getSingleStageQmSch方法
public double[][] getSingleStageQmSch(double[][]
ptimes,
int[] seq) 基于作业时间、作业排序获得Qm并行机【单阶段异质并行机】详细调度方案 参数: ptimes - 作业时间,每一行为一项作业在各台机器上的加工时间,列数为异质并行机的数量 seq - 作业排序数组,从1开始编号 返回: 返回调度排序的二维数组,共五列,第一列:作业编号,第二类:机器编号,第三列:工序编号
第四列:开工时间,第五列:完工时间,第三列是为了同多阶段车间调度统一化预留的一列,在单阶段调度中无用 |
根据该方法的介绍,程序实现如下:
import
easyopt.common.EasyArray; import
easyopt.shopSch.Schedule; import
easyopt.shopSch.pms.QmPMS; public class
Example_QmPMS { public static void
main(String[] args) { double[][]
ptimes =
{{20,25,25,24},{10,11,12,8},{25,25,25,24},{36,41,41,41},{13,12,14,8},{35,33,30,30},{33,35,32,26},{24,29,28,23},{32,34,37,31},{20,17,19,17},{12,17,18,15},{30,31,31,33},{28,31,36,34},{24,23,21,26},{10,16,14,14},{28,29,28,25},{9,10,15,8},{38,33,35,35},{37,43,39,40},{10,15,18,10}}; int[] seq =
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; int[] seq2 =
{20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; QmPMS qmpms = new
QmPMS(); double[][]
schedule = qmpms.getSingleStageQmSch(ptimes, seq); System.out.println("----具体调度方案如下-----"); EasyArray.printArray(schedule); System.out.println("----最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(schedule)); double[][]
schedule2 = qmpms.getSingleStageQmSch(ptimes, seq2); System.out.println("----倒序排序的具体调度方案如下-----"); EasyArray.printArray(schedule2); System.out.println("----倒序排序的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(schedule2)); } } |
执行结果如下:
----具体调度方案如下----- 1.0 1.0 0.0 0.0 20.0 ; 2.0 2.0 0.0 0.0 11.0 ; 3.0 3.0 0.0 0.0 25.0 ; 4.0 4.0 0.0 0.0 41.0 ; 5.0 2.0 0.0 11.0 23.0 ; 6.0 1.0 0.0 20.0 55.0 ; 7.0 2.0 0.0 23.0 58.0 ; 8.0 3.0 0.0 25.0 53.0 ; 9.0 4.0 0.0 41.0 72.0 ; 10.0 3.0 0.0 53.0 72.0 ; 11.0 1.0 0.0 55.0 67.0 ; 12.0 2.0 0.0 58.0 89.0 ; 13.0 1.0 0.0 67.0 95.0 ; 14.0 3.0 0.0 72.0 93.0 ; 15.0 4.0 0.0 72.0 86.0 ; 16.0 4.0 0.0 86.0 111.0 ; 17.0 2.0 0.0 89.0 99.0 ; 18.0 3.0 0.0 93.0 128.0 ; 19.0 1.0 0.0 95.0 132.0 ; 20.0 2.0 0.0 99.0 114.0 ; ----最大完工时间为----- 132.0 ----倒序排序的具体调度方案如下----- 20.0 1.0 0.0 0.0 10.0 ; 19.0 2.0 0.0 0.0 43.0 ; 18.0 3.0 0.0 0.0 35.0 ; 17.0 4.0 0.0 0.0 8.0 ; 16.0 4.0 0.0 8.0 33.0 ; 15.0 1.0 0.0 10.0 20.0 ; 14.0 1.0 0.0 20.0 44.0 ; 13.0 4.0 0.0 33.0 67.0 ; 12.0 3.0 0.0 35.0 66.0 ; 11.0 2.0 0.0 43.0 60.0 ; 10.0 1.0 0.0 44.0 64.0 ; 9.0 2.0 0.0 60.0 94.0 ; 8.0 1.0 0.0 64.0 88.0 ; 7.0 3.0 0.0 66.0 98.0 ; 6.0 4.0 0.0 67.0 97.0 ; 5.0 1.0 0.0 88.0 101.0 ; 4.0 2.0 0.0 94.0 135.0 ; 3.0 4.0 0.0 97.0 121.0 ; 2.0 3.0 0.0 98.0 110.0 ; 1.0 1.0 0.0 101.0 121.0 ; ----倒序排序的最大完工时间为----- 135.0 |
从结果可以看出,顺序排序的最大完工时间【132】要比逆序排序的最大完工时间【135】小。
例2:还是以例1的异质并行机工时数据为例,分别使用模拟退火算法、遗传算法、粒子群算法、蚁群算法和教学算法进行该问题的优化求解,获取最大完工时间最小的排序。
求解异质并行机的几种算法参数及其说明请参看API,设计示例问题的优化程序如下:
import
easyopt.common.EasyArray; import
easyopt.shopSch.SchOptResult; import
easyopt.shopSch.Schedule; import
easyopt.shopSch.pms.QmPMS; public class
Example_QmPMSopt { public static void
main(String[] args) { //
TODO Auto-generated method stub double[][]
ptimes =
{{20,25,25,24},{10,11,12,8},{25,25,25,24},{36,41,41,41},{13,12,14,8},{35,33,30,30},{33,35,32,26},{24,29,28,23},{32,34,37,31},{20,17,19,17},{12,17,18,15},{30,31,31,33},{28,31,36,34},{24,23,21,26},{10,16,14,14},{28,29,28,25},{9,10,15,8},{38,33,35,35},{37,43,39,40},{10,15,18,10}}; double[] saParas =
{0.992,40,400,70}; double[] gaParas =
{400,40,0.7,0.6,70}; double[] acoParas =
{0.2,40,400,70}; double[] psoParas =
{0.9,2,2,40,400,70}; double[] tlboParas =
{40,400,70}; QmPMS qmpms = new
QmPMS(); SchOptResult saResult = qmpms.optQmCmaxBySA(ptimes,saParas); SchOptResult
gaResult = qmpms.optQmCmaxByGA(ptimes,gaParas); SchOptResult
acoResult = qmpms.optQmCmaxByACO(ptimes,acoParas); SchOptResult
psoResult = qmpms.optQmCmaxByPSO(ptimes,psoParas) ; SchOptResult
tlboResult = qmpms.optQmCmaxByTLBO(ptimes,tlboParas) ; System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
优化输出结果如下:
----模拟退火算法获得的最优排序调度方案如下----- 10.0 1.0 0.0 0.0 20.0 ; 1.0 2.0 0.0 0.0 25.0 ; 2.0 3.0 0.0 0.0 12.0 ; 9.0 4.0 0.0 0.0 31.0 ; 3.0 3.0 0.0 12.0 37.0 ; 15.0 1.0 0.0 20.0 30.0 ; 12.0 2.0 0.0 25.0 56.0 ; 13.0 1.0 0.0 30.0 58.0 ; 8.0 4.0 0.0 31.0 54.0 ; 6.0 3.0 0.0 37.0 67.0 ; 11.0 4.0 0.0 54.0 69.0 ; 20.0 2.0 0.0 56.0 71.0 ; 4.0 1.0 0.0 58.0 94.0 ; 5.0 3.0 0.0 67.0 81.0 ; 16.0 4.0 0.0 69.0 94.0 ; 18.0 2.0 0.0 71.0 104.0 ; 19.0 3.0 0.0 81.0 120.0 ; 7.0 4.0 0.0 94.0 120.0 ; 14.0 1.0 0.0 94.0 118.0 ; 17.0 2.0 0.0 104.0 114.0 ; ----模拟退火算法获得的最大完工时间为----- 120.0 ----遗传算法获得的最优排序调度方案如下----- 15.0 1.0 0.0 0.0 10.0 ; 12.0 2.0 0.0 0.0 31.0 ; 16.0 3.0 0.0 0.0 28.0 ; 17.0 4.0 0.0 0.0 8.0 ; 20.0 4.0 0.0 8.0 18.0 ; 9.0 1.0 0.0 10.0 42.0 ; 5.0 4.0 0.0 18.0 26.0 ; 13.0 4.0 0.0 26.0 60.0 ; 8.0 3.0 0.0 28.0 56.0 ; 10.0 2.0 0.0 31.0 48.0 ; 11.0 1.0 0.0 42.0 54.0 ; 18.0 2.0 0.0 48.0 81.0 ; 3.0 1.0 0.0 54.0 79.0 ; 19.0 3.0 0.0 56.0 95.0 ; 6.0 4.0 0.0 60.0 90.0 ; 4.0 1.0 0.0 79.0 115.0 ; 1.0 2.0 0.0 81.0 106.0 ; 7.0 4.0 0.0 90.0 116.0 ; 14.0 3.0 0.0 95.0 116.0 ; 2.0 2.0 0.0 106.0 117.0 ; ----遗传算法获得的最大完工时间为----- 117.0 ----粒子群算法获得的最优排序调度方案如下----- 12.0 1.0 0.0 0.0 30.0 ; 6.0 2.0 0.0 0.0 33.0 ; 1.0 3.0 0.0 0.0 25.0 ; 11.0 4.0 0.0 0.0 15.0 ; 5.0 4.0 0.0 15.0 23.0 ; 7.0 4.0 0.0 23.0 49.0 ; 18.0 3.0 0.0 25.0 60.0 ; 15.0 1.0 0.0 30.0 40.0 ; 13.0 2.0 0.0 33.0 64.0 ; 4.0 1.0 0.0 40.0 76.0 ; 19.0 4.0 0.0 49.0 89.0 ; 3.0 3.0 0.0 60.0 85.0 ; 17.0 2.0 0.0 64.0 74.0 ; 16.0 2.0 0.0 74.0 103.0 ; 14.0 1.0 0.0 76.0 100.0 ; 8.0 3.0 0.0 85.0 113.0 ; 9.0 4.0 0.0 89.0 120.0 ; 2.0 1.0 0.0 100.0 110.0 ; 10.0 2.0 0.0 103.0 120.0 ; 20.0 1.0 0.0 110.0 120.0 ; ----粒子群算法获得的最大完工时间为----- 120.0 ----蚁群算法获得的最优排序调度方案如下----- 4.0 1.0 0.0 0.0 36.0 ; 18.0 2.0 0.0 0.0 33.0 ; 9.0 3.0 0.0 0.0 37.0 ; 10.0 4.0 0.0 0.0 17.0 ; 5.0 4.0 0.0 17.0 25.0 ; 20.0 4.0 0.0 25.0 35.0 ; 1.0 2.0 0.0 33.0 58.0 ; 2.0 4.0 0.0 35.0 43.0 ; 15.0 1.0 0.0 36.0 46.0 ; 8.0 3.0 0.0 37.0 65.0 ; 13.0 4.0 0.0 43.0 77.0 ; 3.0 1.0 0.0 46.0 71.0 ; 6.0 2.0 0.0 58.0 91.0 ; 14.0 3.0 0.0 65.0 86.0 ; 17.0 1.0 0.0 71.0 80.0 ; 11.0 4.0 0.0 77.0 92.0 ; 19.0 1.0 0.0 80.0 117.0 ; 12.0 3.0 0.0 86.0 117.0 ; 16.0 2.0 0.0 91.0 120.0 ; 7.0 4.0 0.0 92.0 118.0 ; ----蚁群算法获得的最大完工时间为----- 120.0 ----教学算法获得的最优排序调度方案如下----- 19.0 1.0 0.0 0.0 37.0 ; 12.0 2.0 0.0 0.0 31.0 ; 3.0 3.0 0.0 0.0 25.0 ; 2.0 4.0 0.0 0.0 8.0 ; 1.0 4.0 0.0 8.0 32.0 ; 14.0 3.0 0.0 25.0 46.0 ; 15.0 2.0 0.0 31.0 47.0 ; 7.0 4.0 0.0 32.0 58.0 ; 16.0 1.0 0.0 37.0 65.0 ; 6.0 3.0 0.0 46.0 76.0 ; 9.0 2.0 0.0 47.0 81.0 ; 10.0 4.0 0.0 58.0 75.0 ; 13.0 1.0 0.0 65.0 93.0 ; 8.0 4.0 0.0 75.0 98.0 ; 4.0 3.0 0.0 76.0 117.0 ; 18.0 2.0 0.0 81.0 114.0 ; 17.0 1.0 0.0 93.0 102.0 ; 20.0 4.0 0.0 98.0 108.0 ; 11.0 1.0 0.0 102.0 114.0 ; 5.0 4.0 0.0 108.0 116.0 ; ----教学算法获得的最大完工时间为----- 117.0 |
从优化结果可以看出,遗传算法和教学算法分别获得最小值117,其他三种算法获得的完工时间为120。以教学算法优化计算结果绘制甘特图如下:
前述示例对使用QmPMS类中的方法进行Cmax目标优化求解过程进行描述,该类中进行Lmax目标优化的方法求解过程如此类似,只是使用过程中要选择不同的方法和设置的参数有所不同而已。
SynPMS类主要封装了对同步启停并行机调度计算和优化中涉及的方法。在现实工厂中,有些并行机从事同一工序作业,必须同步开工同步停工,SynPMS类主要进行该种并行机调度的相关计算和优化。
SynPMS类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getSingleStageSynPMSch(double[]
ptimes, double[] dTimes, int[] seq, int machQty, double[] rTimes) 基于作业时间、作业排序和机器数量获得并行机【单阶段同质并行机-同步启停并行机,具有交付时间的】详细调度方案 |
double[][] |
getSingleStageSynPMSch(double[]
ptimes, int[] seq, int machQty, double[] rTimes) 基于作业时间、作业排序和机器数量获得并行机【单阶段同质并行机-同步启停并行机,具有交付时间的】详细调度方案 |
SchOptResult |
optPMSSynByEDD(double[]
ptimes, double[] dTimes, int machQty, double[] rTimes) 利用交付时间优先进行单阶段同步启停并行机Pm|rj,syn|#问题的求解 |
SchOptResult |
optPMSSynByFCFS(double[]
ptimes, double[] dTimes, int machQty, double[] rTimes) 利用先来先服务规则进行单阶段同步启停并行机Pm|rj,syn|#问题的求解 |
SchOptResult |
optPMSSynCmaxByFCFS(double[]
ptimes, int machQty, double[] rTimes) 利用先来先服务规则进行单阶段同步启停并行机Pm|rj,syn|#问题的求解 |
SchOptResult |
optPMSSynRjCmaxByACO(double[]
ptimes, double[] rtimes, int machQty, double[] params) 利用蚁群算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
SchOptResult |
optPMSSynRjCmaxByGA(double[]
ptimes, double[] rtimes, int machQty, double[] params) 利用遗传算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
SchOptResult |
optPMSSynRjCmaxByPSO(double[]
ptimes, double[] rtimes, int machQty, double[] params) 利用粒子群算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
SchOptResult |
optPMSSynRjCmaxBySA(double[]
ptimes, double[] rtimes, int machQty, double[] params) 利用模拟退火算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
SchOptResult |
optPMSSynRjCmaxByTLBO(double[]
ptimes, double[] rtimes, int machQty, double[] params) 利用教学算法进行同步启停单阶段并行机Pm|rj,syn|Cmax问题的优化求解 |
SchOptResult |
optPMSSynRjLmaxByACO(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用蚁群算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
SchOptResult |
optPMSSynRjLmaxByGA(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用遗传算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
SchOptResult |
optPMSSynRjLmaxByPSO(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用粒子群算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
SchOptResult |
optPMSSynRjLmaxBySA(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用模拟退火算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
SchOptResult |
optPMSSynRjLmaxByTLBO(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用教学算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
double[][] |
optSynRjLsumByACO(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用蚁群算法进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解 |
double[][] |
optSynRjLsumByEDD(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty) 利用EDD进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解 |
double[][] |
optSynRjLsumByFCFS(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty) 利用FCFS进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解 |
double[][] |
optSynRjLsumByFEDD(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty) 利用FCFS+EDD(先到先服务的同时最早交付时间优先)进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解 |
double[][] |
optSynRjLsumByFLPT(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty) 利用FCFS+LPT(先到先服务的同时最长加工时间优先)进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解 |
double[][] |
optSynRjLsumByFSPT(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty) 利用FCFS+SPT(先到先服务的同时最短加工时间优先)进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解 |
double[][] |
optSynRjLsumByGA(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用遗传算法进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解 |
double[][] |
optSynRjLsumByIG(double[]
ptimes, double[] rtimes, int machQty, double[] dtimes) 利用改进贪婪算法进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解, 算法参考:D. |
double[][] |
optSynRjLsumByIGonFCFS(double[]
ptimes, double[] rtimes, int machQty, double[] dtimes) 利用改进贪婪算法进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解, 算法参考:D. |
double[][] |
optSynRjLsumByMultiFIG(double[]
ptimes, double[] rtimes, int machQty, double[] dtimes) 利用成对交换多循环的改进【用FCFS产生初始解】贪婪算法进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解,
算法参考:D. |
double[][] |
optSynRjLsumByMultiIG(double[]
ptimes, double[] rtimes, int machQty, double[] dtimes) 利用成对交换多循环的贪婪算法进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解, 算法参考:D. |
double[][] |
optSynRjLsumByPSO(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用粒子群算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
double[][] |
optSynRjLsumBySA(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用模拟退火算法进行同步启停单阶段并行机Pm|rj,syn|Lsum问题的优化求解 |
double[][] |
optSynRjLsumByTLBO(double[]
ptimes, double[] dtimes, double[] rtimes, int machQty, double[] params) 利用教学算法进行同步启停单阶段并行机Pm|rj,syn|Lmax问题的优化求解 |
同步启停并行机调度考虑的问题是在初始时刻订单不是全部可开工,即订单的释放时间各不相同,而一旦某台并行机没有任务可用,则全部并行机都要停止工作,直至有其他订单可以排产为止。下面分别以示例的方式说明进行同步启停并行机排序计算和优化求解的实现过程,据此演示PMS类中相关方法的使用。
例1:假设有一批作业任务需要在3台同步启停并行机上排产,每项作业的加工工时和释放时间如下表所示,若按顺序排产则最早完工时间为多少?若按倒序排产则最早完工时间又为多少?
JobId |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
ProcTimes |
9 |
23 |
11 |
24 |
16 |
9 |
15 |
12 |
17 |
20 |
26 |
13 |
26 |
23 |
37 |
24 |
ReleaseTimes |
10 |
12 |
13 |
31 |
31 |
34 |
46 |
49 |
56 |
60 |
72 |
76 |
83 |
95 |
96 |
104 |
该问题需要先通过当前参数生成详细的排产方案,然后对排产方案计算最大完工时间。该问题需要使用如下的getSingleStageSynPMSch方法
public double[][] getSingleStageSynPMSch(double[]
ptimes,
int[] seq,
int machQty,
double[] rTimes) 基于作业时间、作业排序和机器数量获得并行机【单阶段同质并行机-同步启停并行机,具有交付时间的】详细调度方案 参数: ptimes - 作业时间 rTimes - 释放时间 seq - 作业排序数组,从1开始编号,数据传递过程必须要保证ptimes、dtimes和seq的长度相等 machQty - 并行机数量 返回: 返回调度排序的二维数组,共十一列,第一列:作业编号,第二类:机器编号,第三列:工序编号
第四列:开工时间,第五列:完工时间,第六列:交付时间,第七列:释放时间,第八列:setup开始,第九列:setup结束, 第十列:setup时长,第十一列:同步开工的组号【同步启停并行机中,有组号为同步开工,0为不能同步开工】 |
根据该方法的介绍,程序实现如下:
import
easyopt.common.EasyArray; import
easyopt.shopSch.Schedule; import
easyopt.shopSch.pms.SynPMS; public class
Example_SynPMS { public static void
main(String[] args) { double[] ptimes =
{9,23,11,24,16,9,15,12,17,20,26,13,26,23,37,24}; double[] rtimes =
{10,12,13,31,31,34,46,49,56,60,72,76,83,95,96,104}; int machQty =3
; int[] seq =
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; int[] seq2 =
{16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; SynPMS synpms = new
SynPMS(); double[][]
schedule = synpms.getSingleStageSynPMSch(ptimes, seq, machQty, rtimes); System.out.println("----具体调度方案如下-----"); EasyArray.printArray(schedule); System.out.println("----最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(schedule)); double[][]
schedule2 = synpms.getSingleStageSynPMSch(ptimes, seq2, machQty, rtimes); System.out.println("----倒序排序的具体调度方案如下-----"); EasyArray.printArray(schedule2); System.out.println("----倒序排序的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(schedule2)); } } |
执行结果如下:
----具体调度方案如下----- 1.0 1.0 0.0 13.0 22.0 0.0 10.0 0.0 0.0 0.0 1.0
; 2.0 2.0 0.0 13.0 22.0 0.0 12.0 0.0 0.0 0.0 1.0
; 3.0 3.0 0.0 13.0 22.0 0.0 13.0 0.0 0.0 0.0 1.0
; 2.0 2.0 0.0 31.0 45.0 0.0 12.0 0.0 0.0 0.0 2.0
; 3.0 3.0 0.0 31.0 33.0 0.0 13.0 0.0 0.0 0.0 2.0
; 4.0 1.0 0.0 31.0 55.0 0.0 31.0 0.0 0.0 0.0 2.0
; 5.0 3.0 0.0 33.0 49.0 0.0 31.0 0.0 0.0 0.0 2.0
; 6.0 2.0 0.0 45.0 54.0 0.0 34.0 0.0 0.0 0.0 2.0
; 7.0 3.0 0.0 49.0 55.0 0.0 46.0 0.0 0.0 0.0 2.0
; 8.0 2.0 0.0 54.0 55.0 0.0 49.0 0.0 0.0 0.0 2.0
; 7.0 3.0 0.0 56.0 65.0 0.0 46.0 0.0 0.0 0.0 3.0
; 8.0 2.0 0.0 56.0 67.0 0.0 49.0 0.0 0.0 0.0 3.0
; 9.0 1.0 0.0 56.0 67.0 0.0 56.0 0.0 0.0 0.0 3.0
; 10.0 3.0 0.0 65.0 67.0 0.0 60.0 0.0 0.0 0.0
3.0 ; 9.0 1.0 0.0 72.0 78.0 0.0 56.0 0.0 0.0 0.0 4.0
; 10.0 3.0 0.0 72.0 90.0 0.0 60.0 0.0 0.0 0.0
4.0 ; 11.0 2.0 0.0 72.0 91.0 0.0 72.0 0.0 0.0 0.0
4.0 ; 12.0 1.0 0.0 78.0 91.0 0.0 76.0 0.0 0.0 0.0
4.0 ; 13.0 3.0 0.0 90.0 91.0 0.0 83.0 0.0 0.0 0.0
4.0 ; 11.0 2.0 0.0 95.0 102.0 0.0 72.0 0.0 0.0 0.0
5.0 ; 13.0 3.0 0.0 95.0 120.0 0.0 83.0 0.0 0.0 0.0
5.0 ; 14.0 1.0 0.0 95.0 118.0 0.0 95.0 0.0 0.0 0.0
5.0 ; 15.0 2.0 0.0 102.0 120.0 0.0 96.0 0.0 0.0 0.0
5.0 ; 16.0 1.0 0.0 118.0 120.0 0.0 104.0 0.0 0.0 0.0
5.0 ; 15.0 2.0 0.0 120.0 139.0 0.0 96.0 0.0 0.0 0.0
0.0 ; 16.0 1.0 0.0 120.0 142.0 0.0 104.0 0.0 0.0 0.0
0.0 ; ----最大完工时间为----- 142.0 ----倒序排序的具体调度方案如下----- 16.0 1.0 0.0 104.0 128.0 0.0 104.0 0.0 0.0 0.0
1.0 ; 15.0 2.0 0.0 104.0 141.0 0.0 96.0 0.0 0.0 0.0
1.0 ; 14.0 3.0 0.0 104.0 127.0 0.0 95.0 0.0 0.0 0.0
1.0 ; 13.0 3.0 0.0 127.0 153.0 0.0 83.0 0.0 0.0 0.0
1.0 ; 12.0 1.0 0.0 128.0 141.0 0.0 76.0 0.0 0.0 0.0
1.0 ; 11.0 1.0 0.0 141.0 167.0 0.0 72.0 0.0 0.0 0.0
1.0 ; 10.0 2.0 0.0 141.0 161.0 0.0 60.0 0.0 0.0 0.0
1.0 ; 9.0 3.0 0.0 153.0 170.0 0.0 56.0 0.0 0.0 0.0
1.0 ; 8.0 2.0 0.0 161.0 173.0 0.0 49.0 0.0 0.0 0.0
1.0 ; 7.0 1.0 0.0 167.0 182.0 0.0 46.0 0.0 0.0 0.0
1.0 ; 6.0 3.0 0.0 170.0 179.0 0.0 34.0 0.0 0.0 0.0
1.0 ; 5.0 2.0 0.0 173.0 189.0 0.0 31.0 0.0 0.0 0.0
1.0 ; 4.0 3.0 0.0 179.0 202.0 0.0 31.0 0.0 0.0 0.0
1.0 ; 3.0 1.0 0.0 182.0 193.0 0.0 13.0 0.0 0.0 0.0
1.0 ; 2.0 2.0 0.0 189.0 202.0 0.0 12.0 0.0 0.0 0.0
1.0 ; 1.0 1.0 0.0 193.0 202.0 0.0 10.0 0.0 0.0 0.0
1.0 ; 4.0 3.0 0.0 202.0 203.0 0.0 31.0 0.0 0.0 0.0
0.0 ; 2.0 2.0 0.0 202.0 212.0 0.0 12.0 0.0 0.0 0.0
0.0 ; ----倒序排序的最大完工时间为----- 212.0 |
从结果可以看出,顺序排序的最大完工时间【142】要比逆序排序的最大完工时间【212】小的多。顺序排序的甘特图如下:
例2:还是以例1的同步启停并行机工时数据为例,分别使用模拟退火算法、遗传算法、粒子群算法、蚁群算法和教学算法进行该问题的优化求解,获取最大完工时间最小的排序。
求解异质并行机的几种算法参数及其说明请参看API,设计示例问题的优化程序如下:
import
easyopt.common.EasyArray; import
easyopt.shopSch.SchOptResult; import
easyopt.shopSch.Schedule; import
easyopt.shopSch.pms.SynPMS; public class
Example_SynPMSopt { public static void
main(String[] args) { double[] ptimes =
{9,23,11,24,16,9,15,12,17,20,26,13,26,23,37,24}; double[] rtimes =
{10,12,13,31,31,34,46,49,56,60,72,76,83,95,96,104}; int machQty =3
; double[] saParas =
{0.992,40,400,70}; double[] gaParas =
{400,40,0.7,0.6,70}; double[] acoParas =
{0.2,40,400,70}; double[] psoParas =
{0.9,2,2,40,400,70}; double[] tlboParas =
{40,400,70}; SynPMS synpms = new
SynPMS(); SchOptResult
saResult = synpms.optPMSSynRjCmaxBySA(ptimes, rtimes, machQty, saParas); SchOptResult
gaResult = synpms.optPMSSynRjCmaxByGA(ptimes, rtimes, machQty, gaParas); SchOptResult
acoResult = synpms.optPMSSynRjCmaxByACO(ptimes, rtimes, machQty, acoParas); SchOptResult
psoResult = synpms.optPMSSynRjCmaxByPSO(ptimes, rtimes, machQty, psoParas) ; SchOptResult
tlboResult = synpms.optPMSSynRjCmaxByTLBO(ptimes, rtimes, machQty, tlboParas); System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
优化输出结果如下:
----模拟退火算法获得的最优排序调度方案如下----- 6.0 1.0 0.0 34.0 43.0 0.0 34.0 0.0 0.0 0.0 1.0
; 4.0 2.0 0.0 34.0 43.0 0.0 31.0 0.0 0.0 0.0 1.0
; 3.0 3.0 0.0 34.0 43.0 0.0 13.0 0.0 0.0 0.0 1.0
; 4.0 2.0 0.0 60.0 75.0 0.0 31.0 0.0 0.0 0.0 2.0
; 3.0 3.0 0.0 60.0 62.0 0.0 13.0 0.0 0.0 0.0 2.0
; 10.0 1.0 0.0 60.0 80.0 0.0 60.0 0.0 0.0 0.0
2.0 ; 9.0 3.0 0.0 62.0 79.0 0.0 56.0 0.0 0.0 0.0 2.0
; 2.0 2.0 0.0 75.0 98.0 0.0 12.0 0.0 0.0 0.0 2.0
; 12.0 3.0 0.0 79.0 92.0 0.0 76.0 0.0 0.0 0.0
2.0 ; 11.0 1.0 0.0 80.0 106.0 0.0 72.0 0.0 0.0 0.0
2.0 ; 7.0 3.0 0.0 92.0 107.0 0.0 46.0 0.0 0.0 0.0
2.0 ; 15.0 2.0 0.0 98.0 135.0 0.0 96.0 0.0 0.0 0.0
2.0 ; 16.0 1.0 0.0 106.0 130.0 0.0 104.0 0.0 0.0 0.0
2.0 ; 13.0 3.0 0.0 107.0 133.0 0.0 83.0 0.0 0.0 0.0
2.0 ; 5.0 1.0 0.0 130.0 146.0 0.0 31.0 0.0 0.0 0.0
2.0 ; 14.0 3.0 0.0 133.0 146.0 0.0 95.0 0.0 0.0 0.0
2.0 ; 1.0 2.0 0.0 135.0 144.0 0.0 10.0 0.0 0.0 0.0
2.0 ; 8.0 2.0 0.0 144.0 146.0 0.0 49.0 0.0 0.0 0.0
2.0 ; 14.0 3.0 0.0 146.0 156.0 0.0 95.0 0.0 0.0 0.0
0.0 ; 8.0 2.0 0.0 146.0 156.0 0.0 49.0 0.0 0.0 0.0
0.0 ; ----模拟退火算法获得的最大完工时间为----- 156.0 ----遗传算法获得的最优排序调度方案如下----- 5.0 1.0 0.0 31.0 47.0 0.0 0.0
0.0 0.0 0.0 31.0 ; 1.0 2.0 0.0 31.0 40.0 0.0 0.0
0.0 0.0 0.0 10.0 ; 4.0 3.0 0.0 31.0 47.0 0.0 0.0
0.0 0.0 0.0 31.0 ; 2.0 2.0 0.0 40.0 47.0 0.0 0.0
0.0 0.0 0.0 12.0 ; 4.0 3.0 0.0 49.0 57.0 0.0 0.0
0.0 0.0 0.0 31.0 ; 2.0 2.0 0.0 49.0 65.0 0.0 0.0
0.0 0.0 0.0 12.0 ; 8.0 1.0 0.0 49.0 61.0 0.0 0.0
0.0 0.0 0.0 49.0 ; 7.0 3.0 0.0 57.0 72.0 0.0 0.0
0.0 0.0 0.0 46.0 ; 9.0 1.0 0.0 61.0 78.0 0.0 0.0
0.0 0.0 0.0 56.0 ; 10.0 2.0 0.0 65.0 85.0 0.0 0.0
0.0 0.0 0.0 60.0 ; 11.0 3.0 0.0 72.0 98.0 0.0 0.0
0.0 0.0 0.0 72.0 ; 6.0 1.0 0.0 78.0 87.0 0.0 0.0
0.0 0.0 0.0 34.0 ; 13.0 2.0 0.0 85.0 111.0 0.0 0.0
0.0 0.0 0.0 83.0 ; 3.0 1.0 0.0 87.0 98.0 0.0 0.0
0.0 0.0 0.0 13.0 ; 12.0 1.0 0.0 98.0 111.0 0.0 0.0
0.0 0.0 0.0 76.0 ; 15.0 3.0 0.0 98.0 134.0 0.0 0.0
0.0 0.0 0.0 96.0 ; 16.0 1.0 0.0 111.0 134.0 0.0 0.0
0.0 0.0 0.0 104.0 ; 14.0 2.0 0.0 111.0 134.0 0.0 0.0
0.0 0.0 0.0 95.0 ; 15.0 3.0 0.0 134.0 135.0 0.0 0.0
0.0 0.0 0.0 96.0 ; 16.0 1.0 0.0 134.0 135.0 0.0 0.0
0.0 0.0 0.0 104.0 ; ----遗传算法获得的最大完工时间为----- 135.0 ----粒子群算法获得的最优排序调度方案如下----- 8.0 1.0 0.0 49.0 61.0 0.0 49.0 0.0 0.0 0.0 1.0
; 2.0 2.0 0.0 49.0 72.0 0.0 12.0 0.0 0.0 0.0 1.0
; 1.0 3.0 0.0 49.0 58.0 0.0 10.0 0.0 0.0 0.0 1.0
; 4.0 3.0 0.0 58.0 82.0 0.0 31.0 0.0 0.0 0.0 1.0
; 10.0 1.0 0.0 61.0 81.0 0.0 60.0 0.0 0.0 0.0
1.0 ; 11.0 2.0 0.0 72.0 82.0 0.0 72.0 0.0 0.0 0.0
1.0 ; 5.0 1.0 0.0 81.0 82.0 0.0 31.0 0.0 0.0 0.0 1.0
; 11.0 2.0 0.0 83.0 99.0 0.0 72.0 0.0 0.0 0.0
2.0 ; 5.0 1.0 0.0 83.0 98.0 0.0 31.0 0.0 0.0 0.0 2.0
; 13.0 3.0 0.0 83.0 109.0 0.0 83.0 0.0 0.0 0.0
2.0 ; 6.0 1.0 0.0 98.0 107.0 0.0 34.0 0.0 0.0 0.0
2.0 ; 7.0 2.0 0.0 99.0 114.0 0.0 46.0 0.0 0.0 0.0
2.0 ; 15.0 1.0 0.0 107.0 144.0 0.0 96.0 0.0 0.0 0.0
2.0 ; 9.0 3.0 0.0 109.0 126.0 0.0 56.0 0.0 0.0 0.0
2.0 ; 12.0 2.0 0.0 114.0 127.0 0.0 76.0 0.0 0.0 0.0
2.0 ; 16.0 3.0 0.0 126.0 150.0 0.0 104.0 0.0 0.0 0.0
2.0 ; 14.0 2.0 0.0 127.0 150.0 0.0 95.0 0.0 0.0 0.0
2.0 ; 3.0 1.0 0.0 144.0 150.0 0.0 13.0 0.0 0.0 0.0
2.0 ; 3.0 1.0 0.0 150.0 155.0 0.0 13.0 0.0 0.0 0.0
0.0 ; ----粒子群算法获得的最大完工时间为----- 155.0 ----蚁群算法获得的最优排序调度方案如下----- 6.0 1.0 0.0 49.0 58.0 0.0 34.0 0.0 0.0 0.0 1.0
; 7.0 2.0 0.0 49.0 64.0 0.0 46.0 0.0 0.0 0.0 1.0
; 8.0 3.0 0.0 49.0 61.0 0.0 49.0 0.0 0.0 0.0 1.0
; 9.0 1.0 0.0 58.0 75.0 0.0 56.0 0.0 0.0 0.0 1.0
; 5.0 3.0 0.0 61.0 75.0 0.0 31.0 0.0 0.0 0.0 1.0
; 4.0 2.0 0.0 64.0 75.0 0.0 31.0 0.0 0.0 0.0 1.0
; 5.0 3.0 0.0 76.0 78.0 0.0 31.0 0.0 0.0 0.0 2.0
; 4.0 2.0 0.0 76.0 89.0 0.0 31.0 0.0 0.0 0.0 2.0
; 12.0 1.0 0.0 76.0 89.0 0.0 76.0 0.0 0.0 0.0
2.0 ; 1.0 3.0 0.0 78.0 87.0 0.0 10.0 0.0 0.0 0.0 2.0
; 3.0 3.0 0.0 87.0 98.0 0.0 13.0 0.0 0.0 0.0 2.0
; 13.0 1.0 0.0 89.0 115.0 0.0 83.0 0.0 0.0 0.0
2.0 ; 10.0 2.0 0.0 89.0 109.0 0.0 60.0 0.0 0.0 0.0
2.0 ; 2.0 3.0 0.0 98.0 121.0 0.0 12.0 0.0 0.0 0.0
2.0 ; 16.0 2.0 0.0 109.0 133.0 0.0 104.0 0.0 0.0 0.0
2.0 ; 11.0 1.0 0.0 115.0 141.0 0.0 72.0 0.0 0.0 0.0
2.0 ; 15.0 3.0 0.0 121.0 141.0 0.0 96.0 0.0 0.0 0.0
2.0 ; 14.0 2.0 0.0 133.0 141.0 0.0 95.0 0.0 0.0 0.0
2.0 ; 15.0 3.0 0.0 141.0 158.0 0.0 96.0 0.0 0.0 0.0
0.0 ; 14.0 2.0 0.0 141.0 156.0 0.0 95.0 0.0 0.0 0.0
0.0 ; ----蚁群算法获得的最大完工时间为----- 158.0 ----教学算法获得的最优排序调度方案如下----- 2.0 1.0 0.0 34.0 43.0 0.0 12.0 0.0 0.0 0.0 1.0
; 1.0 2.0 0.0 34.0 43.0 0.0 10.0 0.0 0.0 0.0 1.0
; 6.0 3.0 0.0 34.0 43.0 0.0 34.0 0.0 0.0 0.0 1.0
; 2.0 1.0 0.0 46.0 60.0 0.0 12.0 0.0 0.0 0.0 2.0
; 7.0 2.0 0.0 46.0 61.0 0.0 46.0 0.0 0.0 0.0 2.0
; 3.0 3.0 0.0 46.0 57.0 0.0 13.0 0.0 0.0 0.0 2.0
; 8.0 3.0 0.0 57.0 69.0 0.0 49.0 0.0 0.0 0.0 2.0
; 9.0 1.0 0.0 60.0 77.0 0.0 56.0 0.0 0.0 0.0 2.0
; 5.0 2.0 0.0 61.0 77.0 0.0 31.0 0.0 0.0 0.0 2.0
; 10.0 3.0 0.0 69.0 89.0 0.0 60.0 0.0 0.0 0.0
2.0 ; 11.0 2.0 0.0 77.0 103.0 0.0 72.0 0.0 0.0 0.0
2.0 ; 4.0 1.0 0.0 77.0 101.0 0.0 31.0 0.0 0.0 0.0
2.0 ; 13.0 3.0 0.0 89.0 115.0 0.0 83.0 0.0 0.0 0.0
2.0 ; 15.0 1.0 0.0 101.0 138.0 0.0 96.0 0.0 0.0 0.0
2.0 ; 14.0 2.0 0.0 103.0 126.0 0.0 95.0 0.0 0.0 0.0
2.0 ; 16.0 3.0 0.0 115.0 138.0 0.0 104.0 0.0 0.0 0.0
2.0 ; 12.0 2.0 0.0 126.0 138.0 0.0 76.0 0.0 0.0 0.0
2.0 ; 16.0 3.0 0.0 138.0 139.0 0.0 104.0 0.0 0.0 0.0
0.0 ; 12.0 2.0 0.0 138.0 139.0 0.0 76.0 0.0 0.0 0.0
0.0 ; ----教学算法获得的最大完工时间为----- 139.0 |
从优化结果可以看出,遗传算法获得最小值135,教学算法获得次小解139,其他三种算法获得排产完工时间比先到先服务【按释放时间排序】的规则调度结果要差。可以看出,根据比较简单的启发式规则安排生产有时也可以获得较好的解,当然选择合适的优化算法还是可以对启发式规则的结果进行优化提升的。以遗传算法优化计算结果绘制甘特图如下:
前述示例对使用SynPMS类中的方法进行Cmax目标优化求解过程进行描述,该类中进行Lmax目标优化的方法求解过程如此类似,只是使用过程中要选择不同的方法和设置的参数有所不同而已。
easyopt.shopSch.fsp包中主要包含流水车间调度计算和优化过程中涉及的类和方法。easyopt.shopSch.pms包中的类及其功能如下表。
类 |
说明 |
BFSP |
阻塞流水车间BFSP调度优化计算中涉及到的方法: 流水车间工序之间没有缓存,即上道工序加工结束只能停在该机器上,
直到下道工序对应的机器空闲方会输出到下道工序的机器,进而上道工序可以处理下一个作业的FSP调度计算程序 |
FSP |
流水车间调度优化计算中所使用的相关方法 |
HFSP |
混合流水车间HFSP调度优化计算中涉及到的方法: 流水车间工序之间没有缓存,即上道工序加工结束只能停在该机器上,
直到下道工序对应的机器空闲方会输出到下道工序的机器,进而上道工序可以处理下一个作业的FSP调度计算程序 |
NIFSP |
机器设备零空闲的FSP调度计算程序 |
NWFSP |
零等待流水作业车间调度相关方法No-wait flow shop scheduling
methods |
Rules4PFSP |
该类存放进行置换流水车间调度时的一些启发式规则算法 |
Rules4PFSP类主要封装了求解以完工时间最小为目标的置换流水车间调度问题的规则算法。
Rules4PFSP类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
int[][] |
CDS(int[][] processTimes) 根据输入的工时数据,利用CDS方法求解置换流水车间Fm|perm|Cmax问题的满意调度方案 |
int[][] |
gupta(int[][] processTimes) 根据输入的工时数据,利用gupta方法求解置换流水车间Fm|perm|Cmax问题的满意调度方案 |
int[][] |
johnson(int[][] processTimes)
根据输入的工时数据,利用Johnson方法求解置换流水车间F2|perm|Cmax问题的满意调度方案 |
int[][] |
palmer(int[][] processTimes)
根据输入的工时数据,利用Palmer方法求解置换流水车间Fm|perm|Cmax问题的满意调度方案 |
int[][] |
RA(int[][] processTimes) 根据输入的工时数据,利用RA方法求解置换流水车间Fm|perm|Cmax问题的满意调度方案 |
例1:考虑有两道工序的15项作业需要进行排产,以实现完工时间最短,各项作业在两台机器上的加工时间如下表:
JobId |
J1 |
J2 |
J3 |
J4 |
J5 |
J6 |
J7 |
J8 |
J9 |
J10 |
J11 |
J12 |
J13 |
J14 |
J15 |
M1 |
21 |
6 |
11 |
30 |
10 |
30 |
22 |
12 |
10 |
10 |
14 |
34 |
31 |
25 |
6 |
M2 |
26 |
28 |
10 |
11 |
8 |
24 |
11 |
17 |
13 |
30 |
8 |
28 |
26 |
13 |
30 |
利用Johnson规则进行求解的程序如下:
import easyopt.common.EasyArray; import easyopt.shopSch.fsp.Rules4PFSP; public class Example_Rule { public static void main(String[] args) { Rules4PFSP
rule =new Rules4PFSP(); int[][] times =
{{21,6,11,30,10,30,22,12,10,10,14,34,31,25,6},{26,28,10,11,8,24,11,17,13,30,8,28,26,13,30}}; int[][] sch =rule.johnson(times); System.out.println("----Johnson算法求解两阶段置换流水车间调度-----"); EasyArray.printArray(sch); } } |
执行后的排产结果如下:
----Johnson算法求解两阶段置换流水车间调度----- 0 1 0 6 ; 0 14 6 12 ; 0 8 12 22 ; 0 9 22 32 ; 0 7 32 44 ; 0 0 44 65 ; 0 11 65 99 ; 0 12 99 130 ; 0 5 130 160 ; 0 13 160 185 ; 0 3 185 215 ; 0 6 215 237 ; 0 2 237 248 ; 0 4 248 258 ; 0 10 258 272 ; 1 1 6 34 ; 1 14 34 64 ; 1 8 64 77 ; 1 9 77 107 ; 1 7 107 124 ; 1 0 124 150 ; 1 11 150 178 ; 1 12 178 204 ; 1 5 204 228 ; 1 13 228 241 ; 1 3 241 252 ; 1 6 252 263 ; 1 2 263 273 ; 1 4 273 281 ; 1 10 281 289 ; |
结合johnson算法详细使用说明可知,生成的调度结果第一列为机器编号,第二列为作业编号,第三列为开工时间,第四列为完工时间,机器编号和作业编号都从0开始编起。所以作业排序为:2、15、9、10、8、1、12、13、6、14、4、7、3、5、11,最迟完工时间为289。
例2:有个8作业4工序的置换流水车间调度问题,作业各个工序的加工工时如下表所示,分别使用CDS、Gupta、Palmer和RA规则算法获取其排序以及排序的具体方案和完工时间。
JobId |
J1 |
J2 |
J3 |
J4 |
J5 |
J6 |
J7 |
J8 |
M1 |
25 |
11 |
17 |
28 |
16 |
33 |
27 |
27 |
M2 |
34 |
25 |
9 |
34 |
22 |
6 |
31 |
32 |
M3 |
26 |
20 |
13 |
16 |
20 |
34 |
23 |
22 |
M4 |
24 |
15 |
34 |
28 |
34 |
34 |
9 |
20 |
程序设计如下:
import
easyopt.common.EasyArray; import
easyopt.shopSch.fsp.Rules4PFSP; public class
Example_Rule { public static void
main(String[] args) { Rules4PFSP
rule =new Rules4PFSP(); int[][]
times2 =
{{25,11,17,28,16,33,27,27},{34,25,9,34,22,6,31,32},{26,20,13,16,20,34,23,22},{24,15,34,28,34,34,9,20}}; int[][]
cdsSch =rule.CDS(times2); System.out.println("----CDS求解多阶段置换流水车间调度-----"); EasyArray.printArray(cdsSch); int[][]
guptaSch =rule.gupta(times2); System.out.println("----Gupta求解多阶段置换流水车间调度-----"); EasyArray.printArray(guptaSch); int[][]
palmerSch =rule.palmer(times2); System.out.println("----Palmer求解多阶段置换流水车间调度-----"); EasyArray.printArray(palmerSch); int[][]
raSch =rule.RA(times2); System.out.println("----RA求解多阶段置换流水车间调度-----"); EasyArray.printArray(raSch); } } |
执行结果如下所示:
----CDS求解多阶段置换流水车间调度----- 0 1 0 11 ; 0 4 11 27 ; 0 2 27 44 ; 0 5 44 77 ; 0 3 77 105 ; 0 0 105 130 ; 0 7 130 157 ; 0 6 157 184 ; 1 1 11 36 ; 1 4 36 58 ; 1 2 58 67 ; 1 5 77 83 ; 1 3 105 139 ; 1 0 139 173 ; 1 7 173 205 ; 1 6 205 236 ; 2 1 36 56 ; 2 4 58 78 ; 2 2 78 91 ; 2 5 91 125 ; 2 3 139 155 ; 2 0 173 199 ; 2 7 205 227 ; 2 6 236 259 ; 3 1 56 71 ; 3 4 78 112 ; 3 2 112 146 ; 3 5 146 180 ; 3 3 180 208 ; 3 0 208 232 ; 3 7 232 252 ; 3 6 259 268 ; ----Gupta求解多阶段置换流水车间调度----- 0 2 0 17 ; 0 1 17 28 ; 0 4 28 44 ; 0 5 44 77 ; 0 0 77 102 ; 0 3 102 130 ; 0 7 130 157 ; 0 6 157 184 ; 1 2 17 26 ; 1 1 28 53 ; 1 4 53 75 ; 1 5 77 83 ; 1 0 102 136 ; 1 3 136 170 ; 1 7 170 202 ; 1 6 202 233 ; 2 2 26 39 ; 2 1 53 73 ; 2 4 75 95 ; 2 5 95 129 ; 2 0 136 162 ; 2 3 170 186 ; 2 7 202 224 ; 2 6 233 256 ; 3 2 39 73 ; 3 1 73 88 ; 3 4 95 129 ; 3 5 129 163 ; 3 0 163 187 ; 3 3 187 215 ; 3 7 224 244 ; 3 6 256 265 ; ----Palmer求解多阶段置换流水车间调度----- 0 2 0 17 ; 0 4 17 33 ; 0 5 33 66 ; 0 1 66 77 ; 0 0 77 102 ; 0 3 102 130 ; 0 7 130 157 ; 0 6 157 184 ; 1 2 17 26 ; 1 4 33 55 ; 1 5 66 72 ; 1 1 77 102 ; 1 0 102 136 ; 1 3 136 170 ; 1 7 170 202 ; 1 6 202 233 ; 2 2 26 39 ; 2 4 55 75 ; 2 5 75 109 ; 2 1 109 129 ; 2 0 136 162 ; 2 3 170 186 ; 2 7 202 224 ; 2 6 233 256 ; 3 2 39 73 ; 3 4 75 109 ; 3 5 109 143 ; 3 1 143 158 ; 3 0 162 186 ; 3 3 186 214 ; 3 7 224 244 ; 3 6 256 265 ; ----RA求解多阶段置换流水车间调度----- 0 5 0 33 ; 0 4 33 49 ; 0 0 49 74 ; 0 3 74 102 ; 0 2 102 119 ; 0 7 119 146 ; 0 1 146 157 ; 0 6 157 184 ; 1 5 33 39 ; 1 4 49 71 ; 1 0 74 108 ; 1 3 108 142 ; 1 2 142 151 ; 1 7 151 183 ; 1 1 183 208 ; 1 6 208 239 ; 2 5 39 73 ; 2 4 73 93 ; 2 0 108 134 ; 2 3 142 158 ; 2 2 158 171 ; 2 7 183 205 ; 2 1 208 228 ; 2 6 239 262 ; 3 5 73 107 ; 3 4 107 141 ; 3 0 141 165 ; 3 3 165 193 ; 3 2 193 227 ; 3 7 227 247 ; 3 1 247 262 ; 3 6 262 271 ; |
根据四种算法获得的详细排产结果,可以整理出四种算法获得的排序和最大完工时间如下表所示:
算法 |
排序 |
Cmax |
CDS |
2->5->3->6->4->1->8->7 |
268 |
Gupta |
3->2->5->6->1->4->8->7 |
265 |
Palmer |
3->5->6->2->1->4->8->7 |
265 |
RA |
6->5->1->4->3->8->2->7 |
271 |
FSP类主要封装了置换流水车间调度问题计算和优化所使用的一些方法。
FSP类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getPFMsch(double[][]
ptimes, int[] seq) 基于作业时间、作业排序获得置换流水车间Fm的详细调度方案 |
double[][] |
getPFMsch(double[][]
ptimes, int[] seq, double[] dueTimes) 基于作业时间、作业排序获得置换流水车间问题的详细调度方案 |
double[][] |
getPFMSchRelease(double[][]
ptimes, int[] seq, double[] releaseTimes) 基于作业时间、作业排序获得置换流水车间Fm|perm,rj|*问题的详细调度方案 |
double[][] |
getPFMSchRelease(double[][]
ptimes, int[] seq, double[] releaseTimes, double[] dueTimes) 基于作业时间、作业排序、交付时间和释放时间获得置换流水车间的详细调度方案 |
SchOptResult |
optPFMCmaxByACO(double[][]
ptimes, double[] params) 利用蚁群算法进行置换流水车间Fm|perm|Cmax问题的优化求解 |
SchOptResult |
optPFMCmaxByGA(double[][]
ptimes, double[] params) 利用遗传算法进行置换流水车间Fm|perm|Cmax问题的优化求解 |
SchOptResult |
optPFMCmaxByPSO(double[][]
ptimes, double[] params) 利用粒子群算法进行置换流水车间Fm|perm|Cmax问题的优化求解 |
SchOptResult |
optPFMCmaxBySA(double[][]
ptimes, double[] params) 利用模拟退火算法进行置换流水车间Fm|perm|Cmax问题的优化求解 |
SchOptResult |
optPFMCmaxByTLBO(double[][]
ptimes, double[] params) 利用教学算法进行置换流水车间Fm|perm|Cmax问题的优化求解 |
SchOptResult |
optPFMCtotalByACO(double[][]
ptimes, double[] params) 利用蚁群算法进行置换流水车间Fm|perm|Ctotal问题的优化求解 |
SchOptResult |
optPFMCtotalByGA(double[][]
ptimes, double[] params) 利用遗传算法进行置换流水车间Fm|perm|Ctotal问题的优化求解 |
SchOptResult |
optPFMCtotalByPSO(double[][]
ptimes, double[] params) 利用粒子群算法进行置换流水车间Fm|perm|Ctotal问题的优化求解 |
SchOptResult |
optPFMCtotalBySA(double[][]
ptimes, double[] params) 利用模拟退火算法进行置换流水车间Fm|perm|Ctotal问题的优化求解 |
SchOptResult |
optPFMCtotalByTLBO(double[][]
ptimes, double[] params) 利用教学算法进行置换流水车间Fm|perm|Ctotal问题的优化求解 |
SchOptResult |
optPFMLmaxByACO(double[][]
ptimes, double[] params, double[] dueTimes) 利用蚁群算法进行置换流水车间Fm|perm|Lmax问题的优化求解 |
SchOptResult |
optPFMLmaxByGA(double[][]
ptimes, double[] params, double[] dueTimes) 利用遗传算法进行置换流水车间Fm|perm|Lmax优化求解 |
SchOptResult |
optPFMLmaxByPSO(double[][]
ptimes, double[] params, double[] dueTimes) 利用粒子群算法进行置换流水车间Fm|perm|Lmax问题的优化求解 |
SchOptResult |
optPFMLmaxBySA(double[][]
ptimes, double[] params, double[] dueTimes) 利用模拟退火算法进行置换流水车间Fm|perm|Lmax问题的优化求解 |
SchOptResult |
optPFMLmaxByTLBO(double[][]
ptimes, double[] params, double[] dueTimes) 利用教学算法进行置换流水车间Fm|perm|Lmax问题的优化求解 |
SchOptResult |
optPFMLtotalByACO(double[][]
ptimes, double[] params, double[] dueTimes) 利用蚁群算法进行置换流水车间Fm|perm|Ltotal问题的优化求解 |
SchOptResult |
optPFMLtotalByGA(double[][]
ptimes, double[] params, double[] dueTimes) 利用遗传算法进行置换流水车间Fm|perm|Ltotal问题的优化求解 |
SchOptResult |
optPFMLtotalByPSO(double[][]
ptimes, double[] params, double[] dueTimes) 利用粒子群算法进行置换流水车间Fm|perm|Ltotal问题的优化求解 |
SchOptResult |
optPFMLtotalBySA(double[][]
ptimes, double[] params, double[] dueTimes) 利用模拟退火算法进行置换流水车间Fm|perm|Ltotal问题的优化求解 |
SchOptResult |
optPFMLtotalByTLBO(double[][]
ptimes, double[] params, double[] dueTimes) 利用教学算法进行置换流水车间Fm|perm|Ltotal问题的优化求解 |
SchOptResult |
optPFMRjCmaxByACO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用蚁群算法进行置换流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optPFMRjCmaxByGA(double[][]
ptimes, double[] params, double[] releaseTimes) 利用遗传算法进行置换流水车间Fm|prmu,rj|Cmax问题的优化求解 |
SchOptResult |
optPFMRjCmaxByPSO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用粒子群算法进行置换流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optPFMRjCmaxBySA(double[][]
ptimes, double[] params, double[] releaseTimes) 利用模拟退火算法进行置换流水车间Fm|prmu,rj|Cmax问题的优化求解 |
SchOptResult |
optPFMRjCmaxByTLBO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用教学算法进行置换流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optPFMRjLmaxByACO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用蚁群算法进行置换流水车间Fm|perm,rj|Lmax问题的优化求解 |
SchOptResult |
optPFMRjLmaxByGA(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用遗传算法进行置换流水车间Fm|prmu,rj|Lmax问题的优化求解 |
SchOptResult |
optPFMRjLmaxByPSO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用粒子群算法进行置换流水车间Fm|perm,rj|Lmax问题的优化求解 |
SchOptResult |
optPFMRjLmaxBySA(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用模拟退火算法进行置换流水车间Fm|prmu,rj|Lmax问题的优化求解 |
SchOptResult |
optPFMRjLmaxByTLBO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用教学算法进行置换流水车间Fm|perm,rj|Lmax问题的优化求解 |
double[][] |
optPFMschByCDS(double[][]
ptimes) 使用CDS规则根据作业时间获得置换流水车间Fm||Cmax问题的详细调度方案 |
double[][] |
optPFMschByEDD(double[][]
ptimes, double[] dueTimes) 基于最早交付时间优先EDD规则的置换流水车间排序 |
double[][] |
optPFMschByGupta(double[][]
ptimes) 使用Gupta规则根据作业时间获得置换流水车间Fm||Cmax问题的详细调度方案 |
double[][] |
optPFMschByJohnson(double[]
p1times, double[] p2times) 使用Johnson规则根据作业时间获得置换流水车间F2||Cmax问题的详细调度方案 |
double[][] |
optPFMschByLPT(double[][]
ptimes, double[] dueTimes) 基于最长作业时长优先优先LPT规则的置换流水车间排序 |
double[][] |
optPFMschByPalmer(double[][]
ptimes) 使用Palmer[斜率指标法]规则根据作业时间获得置换流水车间Fm||Cmax问题的详细调度方案 |
double[][] |
optPFMschBySPT(double[][]
ptimes, double[] dueTimes) 基于最短作业时长优先优先SPT规则的置换流水车间排序 |
例1:考虑7作业5工序的置换流水车间调度问题,各作业在各个工序的加工时间如下表所示,请利用FSP类中的方法实现如下两种作业排序的详细调度方案:
(1)
顺序排序:1、2、3、4、5、6、7;
(2)
逆序排序:7、6、5、4、3、2、1。
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
1 |
13 |
31 |
20 |
29 |
20 |
2 |
23 |
26 |
13 |
34 |
8 |
3 |
16 |
8 |
32 |
21 |
12 |
4 |
5 |
5 |
27 |
11 |
19 |
5 |
20 |
17 |
9 |
5 |
13 |
6 |
9 |
8 |
30 |
5 |
21 |
7 |
22 |
24 |
30 |
19 |
33 |
程序实现如下:
import easyopt.common.EasyArray; import easyopt.shopSch.fsp.FSP; public class Example_FSP { public void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; int[] seq1 = {1,2,3,4,5,6,7}; int[] seq2 = {7,6,5,4,3,2,1}; FSP fsp =new
FSP(); double[][] sch1 = fsp.getPFMsch(ptimes, seq1); System.out.println("---顺序排产结果---"); EasyArray.printArray(sch1); double[][] sch2 = fsp.getPFMsch(ptimes, seq2); System.out.println("---逆序排产结果---"); EasyArray.printArray(sch2); } } |
程序执行结果如下:
---顺序排产结果--- 1.0 1.0 1.0 0.0 13.0 ; 1.0 2.0 2.0 13.0 44.0 ; 1.0 3.0 3.0 44.0 64.0 ; 1.0 4.0 4.0 64.0 93.0 ; 1.0 5.0 5.0 93.0 113.0 ; 2.0 1.0 1.0 13.0 36.0 ; 2.0 2.0 2.0 44.0 70.0 ; 2.0 3.0 3.0 70.0 83.0 ; 2.0 4.0 4.0 93.0 127.0 ; 2.0 5.0 5.0 127.0 135.0 ; 3.0 1.0 1.0 36.0 52.0 ; 3.0 2.0 2.0 70.0 78.0 ; 3.0 3.0 3.0 83.0 115.0 ; 3.0 4.0 4.0 127.0 148.0 ; 3.0 5.0 5.0 148.0 160.0 ; 4.0 1.0 1.0 52.0 57.0 ; 4.0 2.0 2.0 78.0 83.0 ; 4.0 3.0 3.0 115.0 142.0 ; 4.0 4.0 4.0 148.0 159.0 ; 4.0 5.0 5.0 160.0 179.0 ; 5.0 1.0 1.0 57.0 77.0 ; 5.0 2.0 2.0 83.0 100.0 ; 5.0 3.0 3.0 142.0 151.0 ; 5.0 4.0 4.0 159.0 164.0 ; 5.0 5.0 5.0 179.0 192.0 ; 6.0 1.0 1.0 77.0 86.0 ; 6.0 2.0 2.0 100.0 108.0 ; 6.0 3.0 3.0 151.0 181.0 ; 6.0 4.0 4.0 181.0 186.0 ; 6.0 5.0 5.0 192.0 213.0 ; 7.0 1.0 1.0 86.0 108.0 ; 7.0 2.0 2.0 108.0 132.0 ; 7.0 3.0 3.0 181.0 211.0 ; 7.0 4.0 4.0 211.0 230.0 ; 7.0 5.0 5.0 230.0 263.0 ; ---逆序排产结果--- 7.0 1.0 1.0 0.0 22.0 ; 7.0 2.0 2.0 22.0 46.0 ; 7.0 3.0 3.0 46.0 76.0 ; 7.0 4.0 4.0 76.0 95.0 ; 7.0 5.0 5.0 95.0 128.0 ; 6.0 1.0 1.0 22.0 31.0 ; 6.0 2.0 2.0 46.0 54.0 ; 6.0 3.0 3.0 76.0 106.0 ; 6.0 4.0 4.0 106.0 111.0 ; 6.0 5.0 5.0 128.0 149.0 ; 5.0 1.0 1.0 31.0 51.0 ; 5.0 2.0 2.0 54.0 71.0 ; 5.0 3.0 3.0 106.0 115.0 ; 5.0 4.0 4.0 115.0 120.0 ; 5.0 5.0 5.0 149.0 162.0 ; 4.0 1.0 1.0 51.0 56.0 ; 4.0 2.0 2.0 71.0 76.0 ; 4.0 3.0 3.0 115.0 142.0 ; 4.0 4.0 4.0 142.0 153.0 ; 4.0 5.0 5.0 162.0 181.0 ; 3.0 1.0 1.0 56.0 72.0 ; 3.0 2.0 2.0 76.0 84.0 ; 3.0 3.0 3.0 142.0 174.0 ; 3.0 4.0 4.0 174.0 195.0 ; 3.0 5.0 5.0 195.0 207.0 ; 2.0 1.0 1.0 72.0 95.0 ; 2.0 2.0 2.0 95.0 121.0 ; 2.0 3.0 3.0 174.0 187.0 ; 2.0 4.0 4.0 195.0 229.0 ; 2.0 5.0 5.0 229.0 237.0 ; 1.0 1.0 1.0 95.0 108.0 ; 1.0 2.0 2.0 121.0 152.0 ; 1.0 3.0 3.0 187.0 207.0 ; 1.0 4.0 4.0 229.0 258.0 ; 1.0 5.0 5.0 258.0 278.0 ; |
其中顺序排产的最大完工时间为263,逆序排产的最大完工时间为278,两种方案的调度甘特图分别如下图所示。
例2:现有10作业5工序的置换流水车间调度问题,各作业具有特定的释放时间,具体数据如下表。试利用FSP类中的优化方法搜索完工时间最小的排序方案。
表1 作业工序工时表
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
1 |
12 |
32 |
20 |
22 |
15 |
2 |
28 |
31 |
13 |
27 |
14 |
3 |
17 |
12 |
16 |
28 |
24 |
4 |
28 |
22 |
15 |
9 |
8 |
5 |
27 |
28 |
22 |
32 |
31 |
6 |
9 |
23 |
34 |
25 |
23 |
7 |
22 |
24 |
34 |
25 |
5 |
8 |
21 |
32 |
28 |
32 |
30 |
9 |
14 |
9 |
10 |
27 |
16 |
10 |
30 |
28 |
13 |
22 |
24 |
表2 作业释放时间表
JobId |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
releaseTime |
0 |
12 |
24 |
27 |
30 |
36 |
39 |
45 |
57 |
63 |
程序设计如下:
import easyopt.common.EasyArray; import easyopt.shopSch.SchOptResult; import easyopt.shopSch.Schedule; import easyopt.shopSch.fsp.FSP; public class Example_FSP { public void main(String[] args) { double[][] ptimes = {{12,32,20,22,15},{28,31,13,27,14},{17,12,16,28,24},{28,22,15,9,8},{27,28,22,32,31},{9,23,34,25,23},{22,24,34,25,5},{21,32,28,32,30},{14,9,10,27,16},{30,28,13,22,24}}; double[] releaseTimes = {0,12,24,27,30,36,39,45,57,63}; double[] saParas = {0.992,40,400,70}; double[] gaParas = {400,40,0.7,0.6,70}; double[] acoParas = {0.2,40,400,70}; double[] psoParas = {0.9,2,2,40,400,70}; double[] tlboParas = {40,400,70}; FSP fsp =new
FSP(); SchOptResult
saResult = fsp.optPFMRjCmaxBySA(ptimes, saParas, releaseTimes); SchOptResult
gaResult = fsp.optPFMRjCmaxByGA(ptimes, gaParas, releaseTimes); SchOptResult
acoResult = fsp.optPFMRjCmaxByACO(ptimes, acoParas, releaseTimes); SchOptResult
psoResult = fsp.optPFMRjCmaxByPSO(ptimes, psoParas, releaseTimes) ; SchOptResult
tlboResult = fsp.optPFMRjCmaxByTLBO(ptimes, tlboParas, releaseTimes) ; System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
运行结果如下:
----模拟退火算法获得的最优排序调度方案如下----- 1.0 1.0 1.0 0.0 12.0 0.0 0.0 ; 1.0 2.0 2.0 12.0 44.0 0.0 0.0 ; 1.0 3.0 3.0 44.0 64.0 0.0 0.0 ; 1.0 4.0 4.0 64.0 86.0 0.0 0.0 ; 1.0 5.0 5.0 86.0 101.0 0.0 0.0 ; 3.0 1.0 1.0 24.0 41.0 0.0 24.0 ; 3.0 2.0 2.0 44.0 56.0 0.0 24.0 ; 3.0 3.0 3.0 64.0 80.0 0.0 24.0 ; 3.0 4.0 4.0 86.0 114.0 0.0 24.0 ; 3.0 5.0 5.0 114.0 138.0 0.0 24.0 ; 5.0 1.0 1.0 41.0 68.0 0.0 30.0 ; 5.0 2.0 2.0 68.0 96.0 0.0 30.0 ; 5.0 3.0 3.0 96.0 118.0 0.0 30.0 ; 5.0 4.0 4.0 118.0 150.0 0.0 30.0 ; 5.0 5.0 5.0 150.0 181.0 0.0 30.0 ; 9.0 1.0 1.0 68.0 82.0 0.0 57.0 ; 9.0 2.0 2.0 96.0 105.0 0.0 57.0 ; 9.0 3.0 3.0 118.0 128.0 0.0 57.0 ; 9.0 4.0 4.0 150.0 177.0 0.0 57.0 ; 9.0 5.0 5.0 181.0 197.0 0.0 57.0 ; 8.0 1.0 1.0 82.0 103.0 0.0 45.0 ; 8.0 2.0 2.0 105.0 137.0 0.0 45.0 ; 8.0 3.0 3.0 137.0 165.0 0.0 45.0 ; 8.0 4.0 4.0 177.0 209.0 0.0 45.0 ; 8.0 5.0 5.0 209.0 239.0 0.0 45.0 ; 10.0 1.0 1.0 103.0 133.0 0.0 63.0 ; 10.0 2.0 2.0 137.0 165.0 0.0 63.0 ; 10.0 3.0 3.0 165.0 178.0 0.0 63.0 ; 10.0 4.0 4.0 209.0 231.0 0.0 63.0 ; 10.0 5.0 5.0 239.0 263.0 0.0 63.0 ; 6.0 1.0 1.0 133.0 142.0 0.0 36.0 ; 6.0 2.0 2.0 165.0 188.0 0.0 36.0 ; 6.0 3.0 3.0 188.0 222.0 0.0 36.0 ; 6.0 4.0 4.0 231.0 256.0 0.0 36.0 ; 6.0 5.0 5.0 263.0 286.0 0.0 36.0 ; 2.0 1.0 1.0 142.0 170.0 0.0 12.0 ; 2.0 2.0 2.0 188.0 219.0 0.0 12.0 ; 2.0 3.0 3.0 222.0 235.0 0.0 12.0 ; 2.0 4.0 4.0 256.0 283.0 0.0 12.0 ; 2.0 5.0 5.0 286.0 300.0 0.0 12.0 ; 4.0 1.0 1.0 170.0 198.0 0.0 27.0 ; 4.0 2.0 2.0 219.0 241.0 0.0 27.0 ; 4.0 3.0 3.0 241.0 256.0 0.0 27.0 ; 4.0 4.0 4.0 283.0 292.0 0.0 27.0 ; 4.0 5.0 5.0 300.0 308.0 0.0 27.0 ; 7.0 1.0 1.0 198.0 220.0 0.0 39.0 ; 7.0 2.0 2.0 241.0 265.0 0.0 39.0 ; 7.0 3.0 3.0 265.0 299.0 0.0 39.0 ; 7.0 4.0 4.0 299.0 324.0 0.0 39.0 ; 7.0 5.0 5.0 324.0 329.0 0.0 39.0 ; ----模拟退火算法获得的最大完工时间为----- 329.0 ----遗传算法获得的最优排序调度方案如下----- 1 1 1 0 12 0 0 ; 1 2 2 12 44 0 0 ; 1 3 3 44 64 0 0 ; 1 4 4 64 86 0 0 ; 1 5 5 86 101 0 0 ; 3 1 1 24 41 0 24 ; 3 2 2 44 56 0 24 ; 3 3 3 64 80 0 24 ; 3 4 4 86 114 0 24 ; 3 5 5 114 138 0 24 ; 6 1 1 41 50 0 36 ; 6 2 2 56 79 0 36 ; 6 3 3 80 114 0 36 ; 6 4 4 114 139 0 36 ; 6 5 5 139 162 0 36 ; 5 1 1 50 77 0 30 ; 5 2 2 79 107 0 30 ; 5 3 3 114 136 0 30 ; 5 4 4 139 171 0 30 ; 5 5 5 171 202 0 30 ; 8 1 1 77 98 0 45 ; 8 2 2 107 139 0 45 ; 8 3 3 139 167 0 45 ; 8 4 4 171 203 0 45 ; 8 5 5 203 233 0 45 ; 10 1 1 98 128 0 63 ; 10 2 2 139 167 0 63 ; 10 3 3 167 180 0 63 ; 10 4 4 203 225 0 63 ; 10 5 5 233 257 0 63 ; 2 1 1 128 156 0 12 ; 2 2 2 167 198 0 12 ; 2 3 3 198 211 0 12 ; 2 4 4 225 252 0 12 ; 2 5 5 257 271 0 12 ; 4 1 1 156 184 0 27 ; 4 2 2 198 220 0 27 ; 4 3 3 220 235 0 27 ; 4 4 4 252 261 0 27 ; 4 5 5 271 279 0 27 ; 9 1 1 184 198 0 57 ; 9 2 2 220 229 0 57 ; 9 3 3 235 245 0 57 ; 9 4 4 261 288 0 57 ; 9 5 5 288 304 0 57 ; 7 1 1 198 220 0 39 ; 7 2 2 229 253 0 39 ; 7 3 3 253 287 0 39 ; 7 4 4 288 313 0 39 ; 7 5 5 313 318 0 39 ; ----遗传算法获得的最大完工时间为----- 318.0 ----粒子群算法获得的最优排序调度方案如下----- 1.0 1.0 1.0 0.0 12.0 0.0 0.0 ; 1.0 2.0 2.0 12.0 44.0 0.0 0.0 ; 1.0 3.0 3.0 44.0 64.0 0.0 0.0 ; 1.0 4.0 4.0 64.0 86.0 0.0 0.0 ; 1.0 5.0 5.0 86.0 101.0 0.0 0.0 ; 2.0 1.0 1.0 12.0 40.0 0.0 12.0 ; 2.0 2.0 2.0 44.0 75.0 0.0 12.0 ; 2.0 3.0 3.0 75.0 88.0 0.0 12.0 ; 2.0 4.0 4.0 88.0 115.0 0.0 12.0 ; 2.0 5.0 5.0 115.0 129.0 0.0 12.0 ; 3.0 1.0 1.0 40.0 57.0 0.0 24.0 ; 3.0 2.0 2.0 75.0 87.0 0.0 24.0 ; 3.0 3.0 3.0 88.0 104.0 0.0 24.0 ; 3.0 4.0 4.0 115.0 143.0 0.0 24.0 ; 3.0 5.0 5.0 143.0 167.0 0.0 24.0 ; 5.0 1.0 1.0 57.0 84.0 0.0 30.0 ; 5.0 2.0 2.0 87.0 115.0 0.0 30.0 ; 5.0 3.0 3.0 115.0 137.0 0.0 30.0 ; 5.0 4.0 4.0 143.0 175.0 0.0 30.0 ; 5.0 5.0 5.0 175.0 206.0 0.0 30.0 ; 8.0 1.0 1.0 84.0 105.0 0.0 45.0 ; 8.0 2.0 2.0 115.0 147.0 0.0 45.0 ; 8.0 3.0 3.0 147.0 175.0 0.0 45.0 ; 8.0 4.0 4.0 175.0 207.0 0.0 45.0 ; 8.0 5.0 5.0 207.0 237.0 0.0 45.0 ; 10.0 1.0 1.0 105.0 135.0 0.0 63.0 ; 10.0 2.0 2.0 147.0 175.0 0.0 63.0 ; 10.0 3.0 3.0 175.0 188.0 0.0 63.0 ; 10.0 4.0 4.0 207.0 229.0 0.0 63.0 ; 10.0 5.0 5.0 237.0 261.0 0.0 63.0 ; 9.0 1.0 1.0 135.0 149.0 0.0 57.0 ; 9.0 2.0 2.0 175.0 184.0 0.0 57.0 ; 9.0 3.0 3.0 188.0 198.0 0.0 57.0 ; 9.0 4.0 4.0 229.0 256.0 0.0 57.0 ; 9.0 5.0 5.0 261.0 277.0 0.0 57.0 ; 6.0 1.0 1.0 149.0 158.0 0.0 36.0 ; 6.0 2.0 2.0 184.0 207.0 0.0 36.0 ; 6.0 3.0 3.0 207.0 241.0 0.0 36.0 ; 6.0 4.0 4.0 256.0 281.0 0.0 36.0 ; 6.0 5.0 5.0 281.0 304.0 0.0 36.0 ; 4.0 1.0 1.0 158.0 186.0 0.0 27.0 ; 4.0 2.0 2.0 207.0 229.0 0.0 27.0 ; 4.0 3.0 3.0 241.0 256.0 0.0 27.0 ; 4.0 4.0 4.0 281.0 290.0 0.0 27.0 ; 4.0 5.0 5.0 304.0 312.0 0.0 27.0 ; 7.0 1.0 1.0 186.0 208.0 0.0 39.0 ; 7.0 2.0 2.0 229.0 253.0 0.0 39.0 ; 7.0 3.0 3.0 256.0 290.0 0.0 39.0 ; 7.0 4.0 4.0 290.0 315.0 0.0 39.0 ; 7.0 5.0 5.0 315.0 320.0 0.0 39.0 ; ----粒子群算法获得的最大完工时间为----- 320.0 ----蚁群算法获得的最优排序调度方案如下----- 1.0 1.0 1.0 0.0 12.0 0.0 0.0 ; 1.0 2.0 2.0 12.0 44.0 0.0 0.0 ; 1.0 3.0 3.0 44.0 64.0 0.0 0.0 ; 1.0 4.0 4.0 64.0 86.0 0.0 0.0 ; 1.0 5.0 5.0 86.0 101.0 0.0 0.0 ; 3.0 1.0 1.0 24.0 41.0 0.0 24.0 ; 3.0 2.0 2.0 44.0 56.0 0.0 24.0 ; 3.0 3.0 3.0 64.0 80.0 0.0 24.0 ; 3.0 4.0 4.0 86.0 114.0 0.0 24.0 ; 3.0 5.0 5.0 114.0 138.0 0.0 24.0 ; 6.0 1.0 1.0 41.0 50.0 0.0 36.0 ; 6.0 2.0 2.0 56.0 79.0 0.0 36.0 ; 6.0 3.0 3.0 80.0 114.0 0.0 36.0 ; 6.0 4.0 4.0 114.0 139.0 0.0 36.0 ; 6.0 5.0 5.0 139.0 162.0 0.0 36.0 ; 8.0 1.0 1.0 50.0 71.0 0.0 45.0 ; 8.0 2.0 2.0 79.0 111.0 0.0 45.0 ; 8.0 3.0 3.0 114.0 142.0 0.0 45.0 ; 8.0 4.0 4.0 142.0 174.0 0.0 45.0 ; 8.0 5.0 5.0 174.0 204.0 0.0 45.0 ; 2.0 1.0 1.0 71.0 99.0 0.0 12.0 ; 2.0 2.0 2.0 111.0 142.0 0.0 12.0 ; 2.0 3.0 3.0 142.0 155.0 0.0 12.0 ; 2.0 4.0 4.0 174.0 201.0 0.0 12.0 ; 2.0 5.0 5.0 204.0 218.0 0.0 12.0 ; 10.0 1.0 1.0 99.0 129.0 0.0 63.0 ; 10.0 2.0 2.0 142.0 170.0 0.0 63.0 ; 10.0 3.0 3.0 170.0 183.0 0.0 63.0 ; 10.0 4.0 4.0 201.0 223.0 0.0 63.0 ; 10.0 5.0 5.0 223.0 247.0 0.0 63.0 ; 5.0 1.0 1.0 129.0 156.0 0.0 30.0 ; 5.0 2.0 2.0 170.0 198.0 0.0 30.0 ; 5.0 3.0 3.0 198.0 220.0 0.0 30.0 ; 5.0 4.0 4.0 223.0 255.0 0.0 30.0 ; 5.0 5.0 5.0 255.0 286.0 0.0 30.0 ; 4.0 1.0 1.0 156.0 184.0 0.0 27.0 ; 4.0 2.0 2.0 198.0 220.0 0.0 27.0 ; 4.0 3.0 3.0 220.0 235.0 0.0 27.0 ; 4.0 4.0 4.0 255.0 264.0 0.0 27.0 ; 4.0 5.0 5.0 286.0 294.0 0.0 27.0 ; 9.0 1.0 1.0 184.0 198.0 0.0 57.0 ; 9.0 2.0 2.0 220.0 229.0 0.0 57.0 ; 9.0 3.0 3.0 235.0 245.0 0.0 57.0 ; 9.0 4.0 4.0 264.0 291.0 0.0 57.0 ; 9.0 5.0 5.0 294.0 310.0 0.0 57.0 ; 7.0 1.0 1.0 198.0 220.0 0.0 39.0 ; 7.0 2.0 2.0 229.0 253.0 0.0 39.0 ; 7.0 3.0 3.0 253.0 287.0 0.0 39.0 ; 7.0 4.0 4.0 291.0 316.0 0.0 39.0 ; 7.0 5.0 5.0 316.0 321.0 0.0 39.0 ; ----蚁群算法获得的最大完工时间为----- 321.0 ----教学算法获得的最优排序调度方案如下----- 1.0 1.0 1.0 0.0 12.0 0.0 0.0 ; 1.0 2.0 2.0 12.0 44.0 0.0 0.0 ; 1.0 3.0 3.0 44.0 64.0 0.0 0.0 ; 1.0 4.0 4.0 64.0 86.0 0.0 0.0 ; 1.0 5.0 5.0 86.0 101.0 0.0 0.0 ; 2.0 1.0 1.0 12.0 40.0 0.0 12.0 ; 2.0 2.0 2.0 44.0 75.0 0.0 12.0 ; 2.0 3.0 3.0 75.0 88.0 0.0 12.0 ; 2.0 4.0 4.0 88.0 115.0 0.0 12.0 ; 2.0 5.0 5.0 115.0 129.0 0.0 12.0 ; 3.0 1.0 1.0 40.0 57.0 0.0 24.0 ; 3.0 2.0 2.0 75.0 87.0 0.0 24.0 ; 3.0 3.0 3.0 88.0 104.0 0.0 24.0 ; 3.0 4.0 4.0 115.0 143.0 0.0 24.0 ; 3.0 5.0 5.0 143.0 167.0 0.0 24.0 ; 5.0 1.0 1.0 57.0 84.0 0.0 30.0 ; 5.0 2.0 2.0 87.0 115.0 0.0 30.0 ; 5.0 3.0 3.0 115.0 137.0 0.0 30.0 ; 5.0 4.0 4.0 143.0 175.0 0.0 30.0 ; 5.0 5.0 5.0 175.0 206.0 0.0 30.0 ; 8.0 1.0 1.0 84.0 105.0 0.0 45.0 ; 8.0 2.0 2.0 115.0 147.0 0.0 45.0 ; 8.0 3.0 3.0 147.0 175.0 0.0 45.0 ; 8.0 4.0 4.0 175.0 207.0 0.0 45.0 ; 8.0 5.0 5.0 207.0 237.0 0.0 45.0 ; 9.0 1.0 1.0 105.0 119.0 0.0 57.0 ; 9.0 2.0 2.0 147.0 156.0 0.0 57.0 ; 9.0 3.0 3.0 175.0 185.0 0.0 57.0 ; 9.0 4.0 4.0 207.0 234.0 0.0 57.0 ; 9.0 5.0 5.0 237.0 253.0 0.0 57.0 ; 10.0 1.0 1.0 119.0 149.0 0.0 63.0 ; 10.0 2.0 2.0 156.0 184.0 0.0 63.0 ; 10.0 3.0 3.0 185.0 198.0 0.0 63.0 ; 10.0 4.0 4.0 234.0 256.0 0.0 63.0 ; 10.0 5.0 5.0 256.0 280.0 0.0 63.0 ; 6.0 1.0 1.0 149.0 158.0 0.0 36.0 ; 6.0 2.0 2.0 184.0 207.0 0.0 36.0 ; 6.0 3.0 3.0 207.0 241.0 0.0 36.0 ; 6.0 4.0 4.0 256.0 281.0 0.0 36.0 ; 6.0 5.0 5.0 281.0 304.0 0.0 36.0 ; 4.0 1.0 1.0 158.0 186.0 0.0 27.0 ; 4.0 2.0 2.0 207.0 229.0 0.0 27.0 ; 4.0 3.0 3.0 241.0 256.0 0.0 27.0 ; 4.0 4.0 4.0 281.0 290.0 0.0 27.0 ; 4.0 5.0 5.0 304.0 312.0 0.0 27.0 ; 7.0 1.0 1.0 186.0 208.0 0.0 39.0 ; 7.0 2.0 2.0 229.0 253.0 0.0 39.0 ; 7.0 3.0 3.0 256.0 290.0 0.0 39.0 ; 7.0 4.0 4.0 290.0 315.0 0.0 39.0 ; 7.0 5.0 5.0 315.0 320.0 0.0 39.0 ; ----教学算法获得的最大完工时间为----- 320.0 |
五种算法优化的结果分别为:329、318、320、321、320,单纯从这一次优化结果看,遗传算法最好,模拟退火算法最差,由于这些算法都是随机搜索算法,每次优化的结果不一定完全相同,所以可以多次运行这些算法进行结果比较。
以遗传算法获得最优结果318的排产方案绘制甘特图如下:
前述示例对使用FSP类中的方法进行Cmax目标优化求解过程进行描述,该类中进行Lmax目标优化的方法求解过程如此类似,只是使用过程中要选择不同的方法和设置的参数有所不同而已,不再赘述。
NWFSP类主要封装了零等待流水车间调度问题计算和优化所使用的一些方法。
NWFSP类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getSchedule(double[][] ptimes, double[] dueTimes, int[]
seq) 基于作业时间、作业排序获得零等待零等待流水车间的详细调度方案 |
double[][] |
getSchedule(double[][] ptimes, int[] seq) 基于作业时间、作业排序获得零等待零等待流水车间的详细调度方案 |
double[][] |
getSchRelease(double[][] ptimes, int[] seq, double[]
releaseTimes) 基于作业时间、作业排序获得零等待流水车间的详细调度方案 |
double[][] |
getSchRelease(double[][] ptimes, int[] seq, double[]
releaseTimes, double[] dueTimes) 基于作业时间、作业排序获得零等待流水车间的详细调度方案 |
SchOptResult |
optCmaxByACO(double[][] ptimes, double[] params) 利用蚁群算法进行零等待流水车间Fm|perm,no-wait|Cmax问题的优化求解 |
SchOptResult |
optCmaxByGA(double[][] ptimes, double[] params) 利用遗传算法进行零等待流水车间Fm|perm,no-wait|Cmax问题的优化求解 |
SchOptResult |
optCmaxByPSO(double[][] ptimes, double[] params) 利用粒子群算法进行零等待流水车间Fm|perm,no-wait|Cmax问题的优化求解 |
SchOptResult |
optCmaxBySA(double[][] ptimes, double[] params) 利用模拟退火算法进行零等待流水车间Fm|perm,no-wait|Cmax问题的优化求解 |
SchOptResult |
optCmaxByTLBO(double[][] ptimes, double[] params) 利用教学算法进行零等待流水车间Fm|perm,no-wait|Cmax问题的优化求解 |
SchOptResult |
optCtotalByACO(double[][] ptimes, double[] params) 利用蚁群算法进行零等待流水车间Fm|perm,no-wait|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByGA(double[][] ptimes, double[] params) 利用遗传算法进行零等待流水车间Fm|perm,no-wait|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByPSO(double[][] ptimes, double[] params) 利用粒子群算法进行零等待流水车间Fm|perm,no-wait|Ctotal问题的优化求解 |
SchOptResult |
optCtotalBySA(double[][] ptimes, double[] params) 利用模拟退火算法进行零等待流水车间Fm|perm,no-wait|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByTLBO(double[][] ptimes, double[] params) 利用教学算法进行零等待流水车间Fm|perm,no-wait|Ctotal问题的优化求解 |
SchOptResult |
optLmaxByACO(double[][] ptimes, double[] params, double[]
dueTimes) 利用蚁群算法进行零等待流水车间Fm|perm,no-wait|Lmax问题的优化求解 |
SchOptResult |
optLmaxByGA(double[][] ptimes, double[] params, double[]
dueTimes) 利用遗传算法进行零等待流水车间Fm|perm,no-wait|Lmax问题的优化求解 |
SchOptResult |
optLmaxByPSO(double[][] ptimes, double[] params, double[]
dueTimes) 利用粒子群算法进行零等待流水车间Fm|perm,no-wait|Lmax问题的优化求解 |
SchOptResult |
optLmaxBySA(double[][] ptimes, double[] params, double[]
dueTimes) 利用模拟退火算法进行零等待流水车间Fm|perm,no-wait|Lmax问题的优化求解 |
SchOptResult |
optLmaxByTLBO(double[][] ptimes, double[] params, double[]
dueTimes) 利用教学算法进行零等待流水车间Fm|perm,no-wait|Lmax问题的优化求解 |
SchOptResult |
optLtotalByACO(double[][] ptimes, double[] params, double[]
dueTimes) 利用蚁群算法进行零等待流水车间Fm|perm,no-wait|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByGA(double[][] ptimes, double[] params, double[]
dueTimes) 利用遗传算法进行零等待流水车间Fm|perm,no-wait|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByPSO(double[][] ptimes, double[] params, double[]
dueTimes) 利用粒子群算法进行零等待流水车间Fm|perm,no-wait|Ltotal问题的优化求解 |
SchOptResult |
optLtotalBySA(double[][] ptimes, double[] params, double[]
dueTimes) 利用模拟退火算法进行零等待流水车间Fm|perm,no-wait|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByTLBO(double[][] ptimes, double[] params, double[]
dueTimes) 利用教学算法进行零等待流水车间Fm|perm,no-wait|Ltotal问题的优化求解 |
SchOptResult |
optRjCmaxByACO(double[][] ptimes, double[] params, double[]
releaseTimes) 利用蚁群算法进行零等待流水车间Fm|perm,no-wait,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByGA(double[][] ptimes, double[] params, double[]
releaseTimes) 利用遗传算法进行零等待流水车间Fm|perm,no-wait,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByPSO(double[][] ptimes, double[] params, double[]
releaseTimes) 利用粒子群算法进行零等待流水车间Fm|perm,no-wait,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxBySA(double[][] ptimes, double[] params, double[]
releaseTimes) 利用模拟退火算法进行零等待流水车间Fm|perm,no-wait,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByTLBO(double[][] ptimes, double[] params, double[]
releaseTimes) 利用教学算法进行零等待流水车间Fm|perm,no-wait,rj|Cmax问题的优化求解 |
SchOptResult |
optRjLmaxByACO(double[][] ptimes, double[] params, double[]
releaseTimes, double[] dueTimes) 利用蚁群算法进行零等待流水车间Fm|perm,no-wait,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByGA(double[][] ptimes, double[] params, double[]
releaseTimes, double[] dueTimes) 利用遗传算法进行零等待流水车间Fm|perm,no-wait,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByPSO(double[][] ptimes, double[] params, double[]
releaseTimes, double[] dueTimes) 利用粒子群算法进行零等待流水车间Fm|perm,no-wait,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxBySA(double[][] ptimes, double[] params, double[]
releaseTimes, double[] dueTimes) 利用模拟退火算法进行零等待流水车间Fm|perm,no-wait,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByTLBO(double[][] ptimes, double[] params, double[]
releaseTimes, double[] dueTimes) 利用教学算法进行零等待流水车间Fm|perm,no-wait,rj|Lmax问题的优化求解 |
例1:考虑7作业5工序的置换流水车间调度问题,各作业在各个工序的加工时间如下表所示,请利用NWFSP类中的方法实现如下两种作业排序的详细调度方案:
(1)
顺序排序:1、2、3、4、5、6、7;
(2)
逆序排序:7、6、5、4、3、2、1。
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
1 |
13 |
31 |
20 |
29 |
20 |
2 |
23 |
26 |
13 |
34 |
8 |
3 |
16 |
8 |
32 |
21 |
12 |
4 |
5 |
5 |
27 |
11 |
19 |
5 |
20 |
17 |
9 |
5 |
13 |
6 |
9 |
8 |
30 |
5 |
21 |
7 |
22 |
24 |
30 |
19 |
33 |
程序实现如下:
import easyopt.common.EasyArray; import easyopt.shopSch.fsp.NWFSP; public class Example_NWFSP { public void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; int[] seq1 = {1,2,3,4,5,6,7}; int[] seq2 = {7,6,5,4,3,2,1}; NWFSP nwfsp =new NWFSP(); double[][] sch1 =nwfsp.getSchedule(ptimes, seq1); System.out.println("---顺序排产结果---"); EasyArray.printArray(sch1); double[][] sch2 = nwfsp.getSchedule(ptimes, seq2); System.out.println("---逆序排产结果---"); EasyArray.printArray(sch2); } } |
执行结果如下:
---顺序排产结果--- 1.0 1.0 1.0 0.0 13.0 ; 1.0 2.0 2.0 13.0 44.0 ; 1.0 3.0 3.0 44.0 64.0 ; 1.0 4.0 4.0 64.0 93.0 ; 1.0 5.0 5.0 93.0 113.0 ; 2.0 1.0 1.0 31.0 54.0 ; 2.0 2.0 2.0 54.0 80.0 ; 2.0 3.0 3.0 80.0 93.0 ; 2.0 4.0 4.0 93.0 127.0 ; 2.0 5.0 5.0 127.0 135.0 ; 3.0 1.0 1.0 71.0 87.0 ; 3.0 2.0 2.0 87.0 95.0 ; 3.0 3.0 3.0 95.0 127.0 ; 3.0 4.0 4.0 127.0 148.0 ; 3.0 5.0 5.0 148.0 160.0 ; 4.0 1.0 1.0 117.0 122.0 ; 4.0 2.0 2.0 122.0 127.0 ; 4.0 3.0 3.0 127.0 154.0 ; 4.0 4.0 4.0 154.0 165.0 ; 4.0 5.0 5.0 165.0 184.0 ; 5.0 1.0 1.0 133.0 153.0 ; 5.0 2.0 2.0 153.0 170.0 ; 5.0 3.0 3.0 170.0 179.0 ; 5.0 4.0 4.0 179.0 184.0 ; 5.0 5.0 5.0 184.0 197.0 ; 6.0 1.0 1.0 162.0 171.0 ; 6.0 2.0 2.0 171.0 179.0 ; 6.0 3.0 3.0 179.0 209.0 ; 6.0 4.0 4.0 209.0 214.0 ; 6.0 5.0 5.0 214.0 235.0 ; 7.0 1.0 1.0 171.0 193.0 ; 7.0 2.0 2.0 193.0 217.0 ; 7.0 3.0 3.0 217.0 247.0 ; 7.0 4.0 4.0 247.0 266.0 ; 7.0 5.0 5.0 266.0 299.0 ; ---逆序排产结果--- 7.0 1.0 1.0 0.0 22.0 ; 7.0 2.0 2.0 22.0 46.0 ; 7.0 3.0 3.0 46.0 76.0 ; 7.0 4.0 4.0 76.0 95.0 ; 7.0 5.0 5.0 95.0 128.0 ; 6.0 1.0 1.0 76.0 85.0 ; 6.0 2.0 2.0 85.0 93.0 ; 6.0 3.0 3.0 93.0 123.0 ; 6.0 4.0 4.0 123.0 128.0 ; 6.0 5.0 5.0 128.0 149.0 ; 5.0 1.0 1.0 98.0 118.0 ; 5.0 2.0 2.0 118.0 135.0 ; 5.0 3.0 3.0 135.0 144.0 ; 5.0 4.0 4.0 144.0 149.0 ; 5.0 5.0 5.0 149.0 162.0 ; 4.0 1.0 1.0 134.0 139.0 ; 4.0 2.0 2.0 139.0 144.0 ; 4.0 3.0 3.0 144.0 171.0 ; 4.0 4.0 4.0 171.0 182.0 ; 4.0 5.0 5.0 182.0 201.0 ; 3.0 1.0 1.0 147.0 163.0 ; 3.0 2.0 2.0 163.0 171.0 ; 3.0 3.0 3.0 171.0 203.0 ; 3.0 4.0 4.0 203.0 224.0 ; 3.0 5.0 5.0 224.0 236.0 ; 2.0 1.0 1.0 163.0 186.0 ; 2.0 2.0 2.0 186.0 212.0 ; 2.0 3.0 3.0 212.0 225.0 ; 2.0 4.0 4.0 225.0 259.0 ; 2.0 5.0 5.0 259.0 267.0 ; 1.0 1.0 1.0 199.0 212.0 ; 1.0 2.0 2.0 212.0 243.0 ; 1.0 3.0 3.0 243.0 263.0 ; 1.0 4.0 4.0 263.0 292.0 ; 1.0 5.0 5.0 292.0 312.0 ; |
其中顺序排产的最大完工时间为299,逆序排产的最大完工时间为312,两种方案的调度甘特图分别如下图所示。
例2:采用NWFSP中相关优化方法对例1中的问题优化求解,获取Cmax最小的排序方案。
程序设计如下:
import easyopt.common.EasyArray; import easyopt.shopSch.SchOptResult; import easyopt.shopSch.Schedule; import easyopt.shopSch.fsp.NWFSP; public class Example_NWFSP { public void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; double[] saParas = {0.992,40,400,70}; double[] gaParas = {400,40,0.7,0.6,70}; double[] acoParas = {0.2,40,400,70}; double[] psoParas = {0.9,2,2,40,400,70}; double[] tlboParas = {40,400,70}; NWFSP nwfsp =new NWFSP(); SchOptResult
saResult = nwfsp.optCmaxBySA(ptimes, gaParas); SchOptResult
gaResult = nwfsp.optCmaxByGA(ptimes, gaParas); SchOptResult
acoResult = nwfsp.optCmaxByACO(ptimes, acoParas); SchOptResult
psoResult = nwfsp.optCmaxByPSO(ptimes, psoParas); SchOptResult
tlboResult = nwfsp.optCmaxByTLBO(ptimes, tlboParas); System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
执行结果如下:
----模拟退火算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 3.0 1.0 1.0 13.0 29.0 ; 3.0 2.0 2.0 29.0 37.0 ; 3.0 3.0 3.0 37.0 69.0 ; 3.0 4.0 4.0 69.0 90.0 ; 3.0 5.0 5.0 90.0 102.0 ; 1.0 1.0 1.0 29.0 42.0 ; 1.0 2.0 2.0 42.0 73.0 ; 1.0 3.0 3.0 73.0 93.0 ; 1.0 4.0 4.0 93.0 122.0 ; 1.0 5.0 5.0 122.0 142.0 ; 7.0 1.0 1.0 51.0 73.0 ; 7.0 2.0 2.0 73.0 97.0 ; 7.0 3.0 3.0 97.0 127.0 ; 7.0 4.0 4.0 127.0 146.0 ; 7.0 5.0 5.0 146.0 179.0 ; 2.0 1.0 1.0 84.0 107.0 ; 2.0 2.0 2.0 107.0 133.0 ; 2.0 3.0 3.0 133.0 146.0 ; 2.0 4.0 4.0 146.0 180.0 ; 2.0 5.0 5.0 180.0 188.0 ; 6.0 1.0 1.0 136.0 145.0 ; 6.0 2.0 2.0 145.0 153.0 ; 6.0 3.0 3.0 153.0 183.0 ; 6.0 4.0 4.0 183.0 188.0 ; 6.0 5.0 5.0 188.0 209.0 ; 5.0 1.0 1.0 158.0 178.0 ; 5.0 2.0 2.0 178.0 195.0 ; 5.0 3.0 3.0 195.0 204.0 ; 5.0 4.0 4.0 204.0 209.0 ; 5.0 5.0 5.0 209.0 222.0 ; ----模拟退火算法获得的最大完工时间为----- 222.0 ----遗传算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 3.0 1.0 1.0 13.0 29.0 ; 3.0 2.0 2.0 29.0 37.0 ; 3.0 3.0 3.0 37.0 69.0 ; 3.0 4.0 4.0 69.0 90.0 ; 3.0 5.0 5.0 90.0 102.0 ; 1.0 1.0 1.0 29.0 42.0 ; 1.0 2.0 2.0 42.0 73.0 ; 1.0 3.0 3.0 73.0 93.0 ; 1.0 4.0 4.0 93.0 122.0 ; 1.0 5.0 5.0 122.0 142.0 ; 7.0 1.0 1.0 51.0 73.0 ; 7.0 2.0 2.0 73.0 97.0 ; 7.0 3.0 3.0 97.0 127.0 ; 7.0 4.0 4.0 127.0 146.0 ; 7.0 5.0 5.0 146.0 179.0 ; 2.0 1.0 1.0 84.0 107.0 ; 2.0 2.0 2.0 107.0 133.0 ; 2.0 3.0 3.0 133.0 146.0 ; 2.0 4.0 4.0 146.0 180.0 ; 2.0 5.0 5.0 180.0 188.0 ; 6.0 1.0 1.0 136.0 145.0 ; 6.0 2.0 2.0 145.0 153.0 ; 6.0 3.0 3.0 153.0 183.0 ; 6.0 4.0 4.0 183.0 188.0 ; 6.0 5.0 5.0 188.0 209.0 ; 5.0 1.0 1.0 158.0 178.0 ; 5.0 2.0 2.0 178.0 195.0 ; 5.0 3.0 3.0 195.0 204.0 ; 5.0 4.0 4.0 204.0 209.0 ; 5.0 5.0 5.0 209.0 222.0 ; ----遗传算法获得的最大完工时间为----- 222.0 ----粒子群算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 3.0 1.0 1.0 13.0 29.0 ; 3.0 2.0 2.0 29.0 37.0 ; 3.0 3.0 3.0 37.0 69.0 ; 3.0 4.0 4.0 69.0 90.0 ; 3.0 5.0 5.0 90.0 102.0 ; 1.0 1.0 1.0 29.0 42.0 ; 1.0 2.0 2.0 42.0 73.0 ; 1.0 3.0 3.0 73.0 93.0 ; 1.0 4.0 4.0 93.0 122.0 ; 1.0 5.0 5.0 122.0 142.0 ; 7.0 1.0 1.0 51.0 73.0 ; 7.0 2.0 2.0 73.0 97.0 ; 7.0 3.0 3.0 97.0 127.0 ; 7.0 4.0 4.0 127.0 146.0 ; 7.0 5.0 5.0 146.0 179.0 ; 2.0 1.0 1.0 84.0 107.0 ; 2.0 2.0 2.0 107.0 133.0 ; 2.0 3.0 3.0 133.0 146.0 ; 2.0 4.0 4.0 146.0 180.0 ; 2.0 5.0 5.0 180.0 188.0 ; 6.0 1.0 1.0 136.0 145.0 ; 6.0 2.0 2.0 145.0 153.0 ; 6.0 3.0 3.0 153.0 183.0 ; 6.0 4.0 4.0 183.0 188.0 ; 6.0 5.0 5.0 188.0 209.0 ; 5.0 1.0 1.0 158.0 178.0 ; 5.0 2.0 2.0 178.0 195.0 ; 5.0 3.0 3.0 195.0 204.0 ; 5.0 4.0 4.0 204.0 209.0 ; 5.0 5.0 5.0 209.0 222.0 ; ----粒子群算法获得的最大完工时间为----- 222.0 ----蚁群算法获得的最优排序调度方案如下----- 6.0 1.0 1.0 0.0 9.0 ; 6.0 2.0 2.0 9.0 17.0 ; 6.0 3.0 3.0 17.0 47.0 ; 6.0 4.0 4.0 47.0 52.0 ; 6.0 5.0 5.0 52.0 73.0 ; 1.0 1.0 1.0 9.0 22.0 ; 1.0 2.0 2.0 22.0 53.0 ; 1.0 3.0 3.0 53.0 73.0 ; 1.0 4.0 4.0 73.0 102.0 ; 1.0 5.0 5.0 102.0 122.0 ; 3.0 1.0 1.0 49.0 65.0 ; 3.0 2.0 2.0 65.0 73.0 ; 3.0 3.0 3.0 73.0 105.0 ; 3.0 4.0 4.0 105.0 126.0 ; 3.0 5.0 5.0 126.0 138.0 ; 7.0 1.0 1.0 65.0 87.0 ; 7.0 2.0 2.0 87.0 111.0 ; 7.0 3.0 3.0 111.0 141.0 ; 7.0 4.0 4.0 141.0 160.0 ; 7.0 5.0 5.0 160.0 193.0 ; 2.0 1.0 1.0 98.0 121.0 ; 2.0 2.0 2.0 121.0 147.0 ; 2.0 3.0 3.0 147.0 160.0 ; 2.0 4.0 4.0 160.0 194.0 ; 2.0 5.0 5.0 194.0 202.0 ; 4.0 1.0 1.0 157.0 162.0 ; 4.0 2.0 2.0 162.0 167.0 ; 4.0 3.0 3.0 167.0 194.0 ; 4.0 4.0 4.0 194.0 205.0 ; 4.0 5.0 5.0 205.0 224.0 ; 5.0 1.0 1.0 173.0 193.0 ; 5.0 2.0 2.0 193.0 210.0 ; 5.0 3.0 3.0 210.0 219.0 ; 5.0 4.0 4.0 219.0 224.0 ; 5.0 5.0 5.0 224.0 237.0 ; ----蚁群算法获得的最大完工时间为----- 237.0 ----教学算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 3.0 1.0 1.0 13.0 29.0 ; 3.0 2.0 2.0 29.0 37.0 ; 3.0 3.0 3.0 37.0 69.0 ; 3.0 4.0 4.0 69.0 90.0 ; 3.0 5.0 5.0 90.0 102.0 ; 1.0 1.0 1.0 29.0 42.0 ; 1.0 2.0 2.0 42.0 73.0 ; 1.0 3.0 3.0 73.0 93.0 ; 1.0 4.0 4.0 93.0 122.0 ; 1.0 5.0 5.0 122.0 142.0 ; 7.0 1.0 1.0 51.0 73.0 ; 7.0 2.0 2.0 73.0 97.0 ; 7.0 3.0 3.0 97.0 127.0 ; 7.0 4.0 4.0 127.0 146.0 ; 7.0 5.0 5.0 146.0 179.0 ; 2.0 1.0 1.0 84.0 107.0 ; 2.0 2.0 2.0 107.0 133.0 ; 2.0 3.0 3.0 133.0 146.0 ; 2.0 4.0 4.0 146.0 180.0 ; 2.0 5.0 5.0 180.0 188.0 ; 6.0 1.0 1.0 136.0 145.0 ; 6.0 2.0 2.0 145.0 153.0 ; 6.0 3.0 3.0 153.0 183.0 ; 6.0 4.0 4.0 183.0 188.0 ; 6.0 5.0 5.0 188.0 209.0 ; 5.0 1.0 1.0 158.0 178.0 ; 5.0 2.0 2.0 178.0 195.0 ; 5.0 3.0 3.0 195.0 204.0 ; 5.0 4.0 4.0 204.0 209.0 ; 5.0 5.0 5.0 209.0 222.0 ; ----教学算法获得的最大完工时间为----- 222.0 |
可以看出五种优化算法优化的结果分别为222、222、222、237和222,其中模拟退火算法、遗传算法、粒子群算法、教学算法均能够获得222这个较小的结果,但是蚁群算法的结果稍差。
以遗传算法获得的结果制作甘特图如下:
前述示例对使用NWFSP类中的方法进行Cmax目标优化求解过程进行描述,该类中进行Lmax目标优化的方法求解过程如此类似,只是使用过程中要选择不同的方法和设置的参数有所不同而已,不再赘述。
NIFSP类主要封装了零空闲流水车间调度问题计算和优化所使用的一些方法。
NIFSP类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getSchedule(double[][]
ptimes, double[] dueTimes, int[] seq) 基于作业时间、作业排序获得零等待零空闲流水车间的详细调度方案 |
double[][] |
getSchedule(double[][]
processTimes, int[] sequence) 根据输入的作业顺序和作业工序工时数组,获取每台机器设备的详细开工和完工时间 |
double[][] |
getSchRelease(double[][]
ptimes, int[] seq, double[] releaseTimes) 基于作业时间、作业排序获得零空闲流水车间的详细调度方案 |
double[][] |
getSchRelease(double[][]
ptimes, int[] seq, double[] releaseTimes, double[] dueTimes) 基于作业时间、作业排序获得零空闲流水车间的详细调度方案 |
SchOptResult |
optCmaxByACO(double[][]
ptimes, double[] params) 利用蚁群算法进行零空闲流水车间Fm|perm,no-idle|Cmax问题的优化求解 |
SchOptResult |
optCmaxByGA(double[][]
ptimes, double[] params) 利用遗传算法进行零空闲流水车间Fm|perm,no-idle|Cmax问题的优化求解 |
SchOptResult |
optCmaxByPSO(double[][]
ptimes, double[] params) 利用粒子群算法进行零空闲流水车间Fm|perm,no-idle|Cmax问题的优化求解 |
SchOptResult |
optCmaxBySA(double[][]
ptimes, double[] params) 利用模拟退火算法进行零空闲流水车间Fm|perm,no-idle|Cmax问题的优化求解 |
SchOptResult |
optCmaxByTLBO(double[][]
ptimes, double[] params) 利用教学算法进行零空闲流水车间Fm|perm,no-idle|Cmax问题的优化求解 |
SchOptResult |
optCtotalByACO(double[][]
ptimes, double[] params) 利用蚁群算法进行零空闲流水车间Fm|perm,no-idle|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByGA(double[][]
ptimes, double[] params) 利用遗传算法进行零空闲流水车间Fm|perm,no-idle|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByPSO(double[][]
ptimes, double[] params) 利用粒子群算法进行零空闲流水车间Fm|perm,no-idle|Ctotal问题的优化求解 |
SchOptResult |
optCtotalBySA(double[][]
ptimes, double[] params) 利用模拟退火算法进行零空闲流水车间Fm|perm,no-idle|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByTLBO(double[][]
ptimes, double[] params) 利用教学算法进行零空闲流水车间Fm|perm,no-idle|Ctotal问题的优化求解 |
SchOptResult |
optLmaxByACO(double[][]
ptimes, double[] params, double[] dueTimes) 利用蚁群算法进行零空闲流水车间Fm|perm,no-idle|Lmax问题的优化求解 |
SchOptResult |
optLmaxByGA(double[][]
ptimes, double[] params, double[] dueTimes) 利用遗传算法进行零空闲流水车间Fm|perm,no-idle|Lmax问题的优化求解 |
SchOptResult |
optLmaxByPSO(double[][]
ptimes, double[] params, double[] dueTimes) 利用粒子群算法进行零空闲流水车间Fm|perm,no-idle|Lmax问题的优化求解 |
SchOptResult |
optLmaxBySA(double[][]
ptimes, double[] params, double[] dueTimes) 利用模拟退火算法进行零空闲流水车间Fm|perm,no-idle|Lmax问题的优化求解 |
SchOptResult |
optLmaxByTLBO(double[][]
ptimes, double[] params, double[] dueTimes) 利用教学算法进行零空闲流水车间Fm|perm,no-idle|Lmax问题的优化求解 |
SchOptResult |
optLtotalByACO(double[][]
ptimes, double[] params, double[] dueTimes) 利用蚁群算法进行零空闲流水车间Fm|perm,no-idle|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByGA(double[][]
ptimes, double[] params, double[] dueTimes) 利用遗传算法进行零空闲流水车间Fm|perm,no-idle|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByPSO(double[][]
ptimes, double[] params, double[] dueTimes) 利用粒子群算法进行零空闲流水车间Fm|perm,no-idle|Ltotal问题的优化求解 |
SchOptResult |
optLtotalBySA(double[][]
ptimes, double[] params, double[] dueTimes) 利用模拟退火算法进行零空闲流水车间Fm|perm,no-idle|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByTLBO(double[][]
ptimes, double[] params, double[] dueTimes) 利用教学算法进行零空闲流水车间Fm|perm,no-idle|Ltotal问题的优化求解 |
SchOptResult |
optRjCmaxByACO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用蚁群算法进行零空闲流水车间Fm|perm,no-idle,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByGA(double[][]
ptimes, double[] params, double[] releaseTimes) 利用遗传算法进行零空闲流水车间Fm|perm,no-idle,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByPSO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用粒子群算法进行零空闲流水车间Fm|perm,no-idle,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxBySA(double[][]
ptimes, double[] params, double[] releaseTimes) 利用模拟退火算法进行零空闲流水车间Fm|perm,no-idle,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByTLBO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用教学算法进行零空闲流水车间Fm|perm,no-idle,rj|Cmax问题的优化求解 |
SchOptResult |
optRjLmaxByACO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用蚁群算法进行零空闲流水车间Fm|perm,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByGA(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用遗传算法进行零空闲流水车间Fm|prmu,rj|Lmax的优化求解 |
SchOptResult |
optRjLmaxByPSO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用粒子群算法进行零空闲流水车间Fm|perm,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxBySA(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用模拟退火算法进行零空闲流水车间Fm||prmu,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByTLBO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用教学算法进行零空闲流水车间Fm|perm,rj|Lmax问题的优化求解 |
double[][] |
optRjLsumByFCFS(double[][]
ptimes, double[] dtimes, double[] rtimes) 利用FCFS进行零空闲流水车间Fm|perm,rj|Lsum问题的优化求解 |
SchOptResult |
optRjLsumByFGA(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用遗传算法进行零空闲流水车间Fm|prmu,rj|Lmax的优化求解 |
double[][] |
optRjLsumByFIG(double[][]
ptimes, double[] dtimes, double[] rtimes) 利用改进【初始排序使用FCFS规则获得】迭代贪婪算法进行零空闲流水车间Fm|perm,rj|Lsum问题的优化求解 |
double[][] |
optRjLsumByFMIG(double[][]
ptimes, double[] dtimes, double[] rtimes) 利用改进【初始排序使用FCFS规则获得,pairwise多次循环】迭代贪婪算法进行零空闲流水车间Fm|perm,rj|Lsum问题的优化求解 |
SchOptResult |
optRjLsumByFSA(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用改进【初始解使用FCFS获得】模拟退火算法进行零空闲流水车间Fm||prmu,rj|Lsum问题的优化求解 |
double[][] |
optRjLsumByIG(double[][]
ptimes, double[] dtimes, double[] rtimes) 利用迭代贪婪算法进行零空闲流水车间Fm|perm,rj|Lsum问题的优化求解 |
double[][] |
optRjLsumByMIG(double[][]
ptimes, double[] dtimes, double[] rtimes) 利用改进【pairwise多循环】迭代贪婪算法进行零空闲流水车间Fm|perm,rj|Lsum问题的优化求解 |
例1:考虑7作业5工序的置换流水车间调度问题,各作业在各个工序的加工时间如下表所示,请利用NIFSP类中的方法实现如下两种作业排序的详细调度方案:
(1)
顺序排序:1、2、3、4、5、6、7;
(2)
逆序排序:7、6、5、4、3、2、1。
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
1 |
13 |
31 |
20 |
29 |
20 |
2 |
23 |
26 |
13 |
34 |
8 |
3 |
16 |
8 |
32 |
21 |
12 |
4 |
5 |
5 |
27 |
11 |
19 |
5 |
20 |
17 |
9 |
5 |
13 |
6 |
9 |
8 |
30 |
5 |
21 |
7 |
22 |
24 |
30 |
19 |
33 |
程序实现如下:
import easyopt.common.EasyArray; import easyopt.shopSch.fsp.NIFSP; public class Example_NIFSP { public void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; int[] seq1 = {1,2,3,4,5,6,7}; int[] seq2 = {7,6,5,4,3,2,1}; NIFSP nifsp =new NIFSP(); double[][] sch1 =
nifsp.getSchedule(ptimes, seq1); System.out.println("---顺序排产结果---"); EasyArray.printArray(sch1); double[][] sch2 = nifsp.getSchedule(ptimes, seq2); System.out.println("---逆序排产结果---"); EasyArray.printArray(sch2); } } |
执行结果如下:
---顺序排产结果--- 1.0 1.0 1.0 0.0 13.0 ; 2.0 1.0 1.0 13.0 36.0 ; 3.0 1.0 1.0 36.0 52.0 ; 4.0 1.0 1.0 52.0 57.0 ; 5.0 1.0 1.0 57.0 77.0 ; 6.0 1.0 1.0 77.0 86.0 ; 7.0 1.0 1.0 86.0 108.0 ; 1.0 2.0 2.0 13.0 44.0 ; 2.0 2.0 2.0 44.0 70.0 ; 3.0 2.0 2.0 70.0 78.0 ; 4.0 2.0 2.0 78.0 83.0 ; 5.0 2.0 2.0 83.0 100.0 ; 6.0 2.0 2.0 100.0 108.0 ; 7.0 2.0 2.0 108.0 132.0 ; 1.0 3.0 3.0 50.0 70.0 ; 2.0 3.0 3.0 70.0 83.0 ; 3.0 3.0 3.0 83.0 115.0 ; 4.0 3.0 3.0 115.0 142.0 ; 5.0 3.0 3.0 142.0 151.0 ; 6.0 3.0 3.0 151.0 181.0 ; 7.0 3.0 3.0 181.0 211.0 ; 1.0 4.0 4.0 106.0 135.0 ; 2.0 4.0 4.0 135.0 169.0 ; 3.0 4.0 4.0 169.0 190.0 ; 4.0 4.0 4.0 190.0 201.0 ; 5.0 4.0 4.0 201.0 206.0 ; 6.0 4.0 4.0 206.0 211.0 ; 7.0 4.0 4.0 211.0 230.0 ; 1.0 5.0 5.0 162.0 182.0 ; 2.0 5.0 5.0 182.0 190.0 ; 3.0 5.0 5.0 190.0 202.0 ; 4.0 5.0 5.0 202.0 221.0 ; 5.0 5.0 5.0 221.0 234.0 ; 6.0 5.0 5.0 234.0 255.0 ; 7.0 5.0 5.0 255.0 288.0 ; ---逆序排产结果--- 7.0 1.0 1.0 0.0 22.0 ; 6.0 1.0 1.0 22.0 31.0 ; 5.0 1.0 1.0 31.0 51.0 ; 4.0 1.0 1.0 51.0 56.0 ; 3.0 1.0 1.0 56.0 72.0 ; 2.0 1.0 1.0 72.0 95.0 ; 1.0 1.0 1.0 95.0 108.0 ; 7.0 2.0 2.0 33.0 57.0 ; 6.0 2.0 2.0 57.0 65.0 ; 5.0 2.0 2.0 65.0 82.0 ; 4.0 2.0 2.0 82.0 87.0 ; 3.0 2.0 2.0 87.0 95.0 ; 2.0 2.0 2.0 95.0 121.0 ; 1.0 2.0 2.0 121.0 152.0 ; 7.0 3.0 3.0 57.0 87.0 ; 6.0 3.0 3.0 87.0 117.0 ; 5.0 3.0 3.0 117.0 126.0 ; 4.0 3.0 3.0 126.0 153.0 ; 3.0 3.0 3.0 153.0 185.0 ; 2.0 3.0 3.0 185.0 198.0 ; 1.0 3.0 3.0 198.0 218.0 ; 7.0 4.0 4.0 145.0 164.0 ; 6.0 4.0 4.0 164.0 169.0 ; 5.0 4.0 4.0 169.0 174.0 ; 4.0 4.0 4.0 174.0 185.0 ; 3.0 4.0 4.0 185.0 206.0 ; 2.0 4.0 4.0 206.0 240.0 ; 1.0 4.0 4.0 240.0 269.0 ; 7.0 5.0 5.0 164.0 197.0 ; 6.0 5.0 5.0 197.0 218.0 ; 5.0 5.0 5.0 218.0 231.0 ; 4.0 5.0 5.0 231.0 250.0 ; 3.0 5.0 5.0 250.0 262.0 ; 2.0 5.0 5.0 262.0 270.0 ; 1.0 5.0 5.0 270.0 290.0 ; |
其中顺序排产的最大完工时间为288,逆序排产的最大完工时间为290,两种方案的调度甘特图分别如下图所示。
例2:采用NIFSP中相关优化方法对例1中的问题优化求解,获取Cmax最小的排序方案。
程序设计如下:
import easyopt.common.EasyArray; import easyopt.shopSch.SchOptResult; import easyopt.shopSch.Schedule; import easyopt.shopSch.fsp.NIFSP; public class Example_NIFSP { public void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; double[] saParas = {0.992,40,400,70}; double[] gaParas = {400,40,0.7,0.6,70}; double[] acoParas = {0.2,40,400,70}; double[] psoParas = {0.9,2,2,40,400,70}; double[] tlboParas = {40,400,70}; NIFSP nifsp =new NIFSP(); SchOptResult
saResult = nifsp.optCmaxBySA(ptimes, saParas); SchOptResult
gaResult = nifsp.optCmaxByGA(ptimes, gaParas); SchOptResult
acoResult = nifsp.optCmaxByACO(ptimes, acoParas); SchOptResult
psoResult = nifsp.optCmaxByPSO(ptimes, psoParas); SchOptResult
tlboResult = nifsp.optCmaxByTLBO(ptimes, tlboParas); System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
执行结果如下:
----模拟退火算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 6.0 1.0 1.0 5.0 14.0 ; 1.0 1.0 1.0 14.0 27.0 ; 7.0 1.0 1.0 27.0 49.0 ; 5.0 1.0 1.0 49.0 69.0 ; 2.0 1.0 1.0 69.0 92.0 ; 3.0 1.0 1.0 92.0 108.0 ; 4.0 2.0 2.0 14.0 19.0 ; 6.0 2.0 2.0 19.0 27.0 ; 1.0 2.0 2.0 27.0 58.0 ; 7.0 2.0 2.0 58.0 82.0 ; 5.0 2.0 2.0 82.0 99.0 ; 2.0 2.0 2.0 99.0 125.0 ; 3.0 2.0 2.0 125.0 133.0 ; 4.0 3.0 3.0 19.0 46.0 ; 6.0 3.0 3.0 46.0 76.0 ; 1.0 3.0 3.0 76.0 96.0 ; 7.0 3.0 3.0 96.0 126.0 ; 5.0 3.0 3.0 126.0 135.0 ; 2.0 3.0 3.0 135.0 148.0 ; 3.0 3.0 3.0 148.0 180.0 ; 4.0 4.0 4.0 81.0 92.0 ; 6.0 4.0 4.0 92.0 97.0 ; 1.0 4.0 4.0 97.0 126.0 ; 7.0 4.0 4.0 126.0 145.0 ; 5.0 4.0 4.0 145.0 150.0 ; 2.0 4.0 4.0 150.0 184.0 ; 3.0 4.0 4.0 184.0 205.0 ; 4.0 5.0 5.0 92.0 111.0 ; 6.0 5.0 5.0 111.0 132.0 ; 1.0 5.0 5.0 132.0 152.0 ; 7.0 5.0 5.0 152.0 185.0 ; 5.0 5.0 5.0 185.0 198.0 ; 2.0 5.0 5.0 198.0 206.0 ; 3.0 5.0 5.0 206.0 218.0 ; ----模拟退火算法获得的最大完工时间为----- 218.0 ----遗传算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 6.0 1.0 1.0 5.0 14.0 ; 1.0 1.0 1.0 14.0 27.0 ; 7.0 1.0 1.0 27.0 49.0 ; 5.0 1.0 1.0 49.0 69.0 ; 2.0 1.0 1.0 69.0 92.0 ; 3.0 1.0 1.0 92.0 108.0 ; 4.0 2.0 2.0 14.0 19.0 ; 6.0 2.0 2.0 19.0 27.0 ; 1.0 2.0 2.0 27.0 58.0 ; 7.0 2.0 2.0 58.0 82.0 ; 5.0 2.0 2.0 82.0 99.0 ; 2.0 2.0 2.0 99.0 125.0 ; 3.0 2.0 2.0 125.0 133.0 ; 4.0 3.0 3.0 19.0 46.0 ; 6.0 3.0 3.0 46.0 76.0 ; 1.0 3.0 3.0 76.0 96.0 ; 7.0 3.0 3.0 96.0 126.0 ; 5.0 3.0 3.0 126.0 135.0 ; 2.0 3.0 3.0 135.0 148.0 ; 3.0 3.0 3.0 148.0 180.0 ; 4.0 4.0 4.0 81.0 92.0 ; 6.0 4.0 4.0 92.0 97.0 ; 1.0 4.0 4.0 97.0 126.0 ; 7.0 4.0 4.0 126.0 145.0 ; 5.0 4.0 4.0 145.0 150.0 ; 2.0 4.0 4.0 150.0 184.0 ; 3.0 4.0 4.0 184.0 205.0 ; 4.0 5.0 5.0 92.0 111.0 ; 6.0 5.0 5.0 111.0 132.0 ; 1.0 5.0 5.0 132.0 152.0 ; 7.0 5.0 5.0 152.0 185.0 ; 5.0 5.0 5.0 185.0 198.0 ; 2.0 5.0 5.0 198.0 206.0 ; 3.0 5.0 5.0 206.0 218.0 ; ----遗传算法获得的最大完工时间为----- 218.0 ----粒子群算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 6.0 1.0 1.0 5.0 14.0 ; 1.0 1.0 1.0 14.0 27.0 ; 7.0 1.0 1.0 27.0 49.0 ; 2.0 1.0 1.0 49.0 72.0 ; 5.0 1.0 1.0 72.0 92.0 ; 3.0 1.0 1.0 92.0 108.0 ; 4.0 2.0 2.0 14.0 19.0 ; 6.0 2.0 2.0 19.0 27.0 ; 1.0 2.0 2.0 27.0 58.0 ; 7.0 2.0 2.0 58.0 82.0 ; 2.0 2.0 2.0 82.0 108.0 ; 5.0 2.0 2.0 108.0 125.0 ; 3.0 2.0 2.0 125.0 133.0 ; 4.0 3.0 3.0 19.0 46.0 ; 6.0 3.0 3.0 46.0 76.0 ; 1.0 3.0 3.0 76.0 96.0 ; 7.0 3.0 3.0 96.0 126.0 ; 2.0 3.0 3.0 126.0 139.0 ; 5.0 3.0 3.0 139.0 148.0 ; 3.0 3.0 3.0 148.0 180.0 ; 4.0 4.0 4.0 81.0 92.0 ; 6.0 4.0 4.0 92.0 97.0 ; 1.0 4.0 4.0 97.0 126.0 ; 7.0 4.0 4.0 126.0 145.0 ; 2.0 4.0 4.0 145.0 179.0 ; 5.0 4.0 4.0 179.0 184.0 ; 3.0 4.0 4.0 184.0 205.0 ; 4.0 5.0 5.0 92.0 111.0 ; 6.0 5.0 5.0 111.0 132.0 ; 1.0 5.0 5.0 132.0 152.0 ; 7.0 5.0 5.0 152.0 185.0 ; 2.0 5.0 5.0 185.0 193.0 ; 5.0 5.0 5.0 193.0 206.0 ; 3.0 5.0 5.0 206.0 218.0 ; ----粒子群算法获得的最大完工时间为----- 218.0 ----蚁群算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 7.0 1.0 1.0 5.0 27.0 ; 5.0 1.0 1.0 27.0 47.0 ; 2.0 1.0 1.0 47.0 70.0 ; 6.0 1.0 1.0 70.0 79.0 ; 1.0 1.0 1.0 79.0 92.0 ; 3.0 1.0 1.0 92.0 108.0 ; 4.0 2.0 2.0 24.0 29.0 ; 7.0 2.0 2.0 29.0 53.0 ; 5.0 2.0 2.0 53.0 70.0 ; 2.0 2.0 2.0 70.0 96.0 ; 6.0 2.0 2.0 96.0 104.0 ; 1.0 2.0 2.0 104.0 135.0 ; 3.0 2.0 2.0 135.0 143.0 ; 4.0 3.0 3.0 30.0 57.0 ; 7.0 3.0 3.0 57.0 87.0 ; 5.0 3.0 3.0 87.0 96.0 ; 2.0 3.0 3.0 96.0 109.0 ; 6.0 3.0 3.0 109.0 139.0 ; 1.0 3.0 3.0 139.0 159.0 ; 3.0 3.0 3.0 159.0 191.0 ; 4.0 4.0 4.0 88.0 99.0 ; 7.0 4.0 4.0 99.0 118.0 ; 5.0 4.0 4.0 118.0 123.0 ; 2.0 4.0 4.0 123.0 157.0 ; 6.0 4.0 4.0 157.0 162.0 ; 1.0 4.0 4.0 162.0 191.0 ; 3.0 4.0 4.0 191.0 212.0 ; 4.0 5.0 5.0 99.0 118.0 ; 7.0 5.0 5.0 118.0 151.0 ; 5.0 5.0 5.0 151.0 164.0 ; 2.0 5.0 5.0 164.0 172.0 ; 6.0 5.0 5.0 172.0 193.0 ; 1.0 5.0 5.0 193.0 213.0 ; 3.0 5.0 5.0 213.0 225.0 ; ----蚁群算法获得的最大完工时间为----- 225.0 ----教学算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 6.0 1.0 1.0 5.0 14.0 ; 1.0 1.0 1.0 14.0 27.0 ; 7.0 1.0 1.0 27.0 49.0 ; 2.0 1.0 1.0 49.0 72.0 ; 5.0 1.0 1.0 72.0 92.0 ; 3.0 1.0 1.0 92.0 108.0 ; 4.0 2.0 2.0 14.0 19.0 ; 6.0 2.0 2.0 19.0 27.0 ; 1.0 2.0 2.0 27.0 58.0 ; 7.0 2.0 2.0 58.0 82.0 ; 2.0 2.0 2.0 82.0 108.0 ; 5.0 2.0 2.0 108.0 125.0 ; 3.0 2.0 2.0 125.0 133.0 ; 4.0 3.0 3.0 19.0 46.0 ; 6.0 3.0 3.0 46.0 76.0 ; 1.0 3.0 3.0 76.0 96.0 ; 7.0 3.0 3.0 96.0 126.0 ; 2.0 3.0 3.0 126.0 139.0 ; 5.0 3.0 3.0 139.0 148.0 ; 3.0 3.0 3.0 148.0 180.0 ; 4.0 4.0 4.0 81.0 92.0 ; 6.0 4.0 4.0 92.0 97.0 ; 1.0 4.0 4.0 97.0 126.0 ; 7.0 4.0 4.0 126.0 145.0 ; 2.0 4.0 4.0 145.0 179.0 ; 5.0 4.0 4.0 179.0 184.0 ; 3.0 4.0 4.0 184.0 205.0 ; 4.0 5.0 5.0 92.0 111.0 ; 6.0 5.0 5.0 111.0 132.0 ; 1.0 5.0 5.0 132.0 152.0 ; 7.0 5.0 5.0 152.0 185.0 ; 2.0 5.0 5.0 185.0 193.0 ; 5.0 5.0 5.0 193.0 206.0 ; 3.0 5.0 5.0 206.0 218.0 ; ----教学算法获得的最大完工时间为----- 218.0 |
可以看出五种优化算法优化的结果分别为218、218、218、225和218,其中模拟退火、遗传算法、粒子群算法、教学算法均能够获得218这个较小的结果,但是蚁群算法的结果稍差。
以遗传算法获得的结果制作甘特图如下:
前述示例对使用NWFSP类中的方法进行Cmax目标优化求解过程进行描述,该类中进行Lmax目标优化的方法求解过程如此类似,只是使用过程中要选择不同的方法和设置的参数有所不同而已,不再赘述。
BFSP类主要封装了阻塞流水车间调度问题计算和优化所使用的一些方法。
BFSP类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getSchedule(double[][]
ptimes, double[] dueTimes, int[] seq) 基于作业时间、作业排序获得零等待阻塞流水车间的详细调度方案 |
double[][] |
getSchedule(double[][]
ptimes, int[] seq) 根据输入的作业顺序和作业工序工时数组,获取每台机器设备的详细开工和完工时间 |
double[][] |
getSchRelease(double[][]
ptimes, int[] seq, double[] releaseTimes) 基于作业时间、作业排序获得阻塞流水车间的详细调度方案 |
double[][] |
getSchRelease(double[][]
ptimes, int[] seq, double[] releaseTimes, double[] dueTimes) 基于作业时间、作业排序获得阻塞流水车间的详细调度方案 |
SchOptResult |
optCmaxByACO(double[][]
ptimes, double[] params) 利用蚁群算法进行阻塞流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCmaxByGA(double[][]
ptimes, double[] params) 利用遗传算法进行阻塞流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCmaxByPSO(double[][]
ptimes, double[] params) 利用粒子群算法进行阻塞流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCmaxBySA(double[][]
ptimes, double[] params) 利用模拟退火算法进行阻塞流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCmaxByTLBO(double[][]
ptimes, double[] params) 利用教学算法进行阻塞流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCtotalByACO(double[][]
ptimes, double[] params) 利用蚁群算法进行阻塞流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByGA(double[][]
ptimes, double[] params) 利用遗传算法进行阻塞流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByPSO(double[][]
ptimes, double[] params) 利用粒子群算法进行阻塞流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optCtotalBySA(double[][]
ptimes, double[] params) 利用模拟退火算法进行阻塞流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByTLBO(double[][]
ptimes, double[] params) 利用教学算法进行阻塞流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optLmaxByACO(double[][]
ptimes, double[] params, double[] dueTimes) 利用蚁群算法进行阻塞流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLmaxByGA(double[][]
ptimes, double[] params, double[] dueTimes) 利用遗传算法进行阻塞流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLmaxByPSO(double[][]
ptimes, double[] params, double[] dueTimes) 利用粒子群算法进行阻塞流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLmaxBySA(double[][]
ptimes, double[] params, double[] dueTimes) 利用模拟退火算法进行阻塞流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLmaxByTLBO(double[][]
ptimes, double[] params, double[] dueTimes) 利用教学算法进行阻塞流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLtotalByACO(double[][]
ptimes, double[] params, double[] dueTimes) 利用蚁群算法进行阻塞流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByGA(double[][]
ptimes, double[] params, double[] dueTimes) 利用遗传算法进行阻塞流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByPSO(double[][]
ptimes, double[] params, double[] dueTimes) 利用粒子群算法进行阻塞流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optLtotalBySA(double[][]
ptimes, double[] params, double[] dueTimes) 利用模拟退火算法进行阻塞流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByTLBO(double[][]
ptimes, double[] params, double[] dueTimes) 利用教学算法进行阻塞流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optRjCmaxByACO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用蚁群算法进行阻塞流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByGA(double[][]
ptimes, double[] params, double[] releaseTimes) 利用遗传算法进行阻塞流水车间Fm|prmu,rj|Cmax的优化求解 |
SchOptResult |
optRjCmaxByPSO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用粒子群算法进行阻塞流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxBySA(double[][]
ptimes, double[] params, double[] releaseTimes) 利用模拟退火算法进行阻塞流水车间Fm||prmu,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByTLBO(double[][]
ptimes, double[] params, double[] releaseTimes) 利用教学算法进行阻塞流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optRjLmaxByACO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用蚁群算法进行阻塞流水车间Fm|perm,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByGA(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用遗传算法进行阻塞流水车间Fm|prmu,rj|Lmax的优化求解 |
SchOptResult |
optRjLmaxByPSO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用粒子群算法进行阻塞流水车间Fm|perm,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxBySA(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用模拟退火算法进行阻塞流水车间Fm||prmu,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByTLBO(double[][]
ptimes, double[] params, double[] releaseTimes, double[] dueTimes) 利用教学算法进行阻塞流水车间Fm|perm,rj|Lmax问题的优化求解 |
例1:考虑7作业5工序的置换流水车间调度问题,各作业在各个工序的加工时间如下表所示,请利用BFSP类中的方法实现如下两种作业排序的详细调度方案:
(1)
顺序排序:1、2、3、4、5、6、7;
(2)
逆序排序:7、6、5、4、3、2、1。
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
1 |
13 |
31 |
20 |
29 |
20 |
2 |
23 |
26 |
13 |
34 |
8 |
3 |
16 |
8 |
32 |
21 |
12 |
4 |
5 |
5 |
27 |
11 |
19 |
5 |
20 |
17 |
9 |
5 |
13 |
6 |
9 |
8 |
30 |
5 |
21 |
7 |
22 |
24 |
30 |
19 |
33 |
程序实现如下:
import easyopt.common.EasyArray; import easyopt.shopSch.fsp.BFSP; public class Example_BFSP { public void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; int[] seq1 = {1,2,3,4,5,6,7}; int[] seq2 = {7,6,5,4,3,2,1}; BFSP bfsp =new BFSP(); double[][] sch1 =
bfsp.getSchedule(ptimes, seq1); System.out.println("---顺序排产结果---"); EasyArray.printArray(sch1); double[][] sch2 = bfsp.getSchedule(ptimes, seq2); System.out.println("---逆序排产结果---"); EasyArray.printArray(sch2); } } |
执行结果如下:
---顺序排产结果--- 1.0 1.0 1.0 0.0 13.0 ; 1.0 2.0 2.0 13.0 44.0 ; 1.0 3.0 3.0 44.0 64.0 ; 1.0 4.0 4.0 64.0 93.0 ; 1.0 5.0 5.0 93.0 113.0 ; 2.0 1.0 1.0 13.0 36.0 ; 2.0 2.0 2.0 44.0 70.0 ; 2.0 3.0 3.0 70.0 83.0 ; 2.0 4.0 4.0 93.0 127.0 ; 2.0 5.0 5.0 127.0 135.0 ; 3.0 1.0 1.0 44.0 60.0 ; 3.0 2.0 2.0 70.0 78.0 ; 3.0 3.0 3.0 93.0 125.0 ; 3.0 4.0 4.0 127.0 148.0 ; 3.0 5.0 5.0 148.0 160.0 ; 4.0 1.0 1.0 70.0 75.0 ; 4.0 2.0 2.0 93.0 98.0 ; 4.0 3.0 3.0 127.0 154.0 ; 4.0 4.0 4.0 154.0 165.0 ; 4.0 5.0 5.0 165.0 184.0 ; 5.0 1.0 1.0 93.0 113.0 ; 5.0 2.0 2.0 127.0 144.0 ; 5.0 3.0 3.0 154.0 163.0 ; 5.0 4.0 4.0 165.0 170.0 ; 5.0 5.0 5.0 184.0 197.0 ; 6.0 1.0 1.0 127.0 136.0 ; 6.0 2.0 2.0 154.0 162.0 ; 6.0 3.0 3.0 165.0 195.0 ; 6.0 4.0 4.0 195.0 200.0 ; 6.0 5.0 5.0 200.0 221.0 ; 7.0 1.0 1.0 154.0 176.0 ; 7.0 2.0 2.0 176.0 200.0 ; 7.0 3.0 3.0 200.0 230.0 ; 7.0 4.0 4.0 230.0 249.0 ; 7.0 5.0 5.0 249.0 282.0 ; ---逆序排产结果--- 7.0 1.0 1.0 0.0 22.0 ; 7.0 2.0 2.0 22.0 46.0 ; 7.0 3.0 3.0 46.0 76.0 ; 7.0 4.0 4.0 76.0 95.0 ; 7.0 5.0 5.0 95.0 128.0 ; 6.0 1.0 1.0 22.0 31.0 ; 6.0 2.0 2.0 46.0 54.0 ; 6.0 3.0 3.0 76.0 106.0 ; 6.0 4.0 4.0 106.0 111.0 ; 6.0 5.0 5.0 128.0 149.0 ; 5.0 1.0 1.0 46.0 66.0 ; 5.0 2.0 2.0 76.0 93.0 ; 5.0 3.0 3.0 106.0 115.0 ; 5.0 4.0 4.0 128.0 133.0 ; 5.0 5.0 5.0 149.0 162.0 ; 4.0 1.0 1.0 76.0 81.0 ; 4.0 2.0 2.0 106.0 111.0 ; 4.0 3.0 3.0 128.0 155.0 ; 4.0 4.0 4.0 155.0 166.0 ; 4.0 5.0 5.0 166.0 185.0 ; 3.0 1.0 1.0 106.0 122.0 ; 3.0 2.0 2.0 128.0 136.0 ; 3.0 3.0 3.0 155.0 187.0 ; 3.0 4.0 4.0 187.0 208.0 ; 3.0 5.0 5.0 208.0 220.0 ; 2.0 1.0 1.0 128.0 151.0 ; 2.0 2.0 2.0 155.0 181.0 ; 2.0 3.0 3.0 187.0 200.0 ; 2.0 4.0 4.0 208.0 242.0 ; 2.0 5.0 5.0 242.0 250.0 ; 1.0 1.0 1.0 155.0 168.0 ; 1.0 2.0 2.0 187.0 218.0 ; 1.0 3.0 3.0 218.0 238.0 ; 1.0 4.0 4.0 242.0 271.0 ; 1.0 5.0 5.0 271.0 291.0 ; |
其中顺序排产的最大完工时间为282,逆序排产的最大完工时间为291,两种方案的调度甘特图分别如下图所示。
例2:采用BFSP中相关优化方法对例1中的问题优化求解,获取Cmax最小的排序方案。
程序设计如下:
import easyopt.common.EasyArray; import easyopt.shopSch.SchOptResult; import easyopt.shopSch.Schedule; import easyopt.shopSch.fsp.BFSP; public class Example_BFSP { public void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; double[] saParas = {0.992,40,400,70}; double[] gaParas = {400,40,0.7,0.6,70}; double[] acoParas = {0.2,40,400,70}; double[] psoParas = {0.9,2,2,40,400,70}; double[] tlboParas = {40,400,70}; BFSP bfsp =new BFSP(); SchOptResult
saResult = bfsp.optCmaxBySA(ptimes, gaParas); SchOptResult
gaResult = bfsp.optCmaxByGA(ptimes, gaParas); SchOptResult
acoResult = bfsp.optCmaxByACO(ptimes, acoParas); SchOptResult
psoResult = bfsp.optCmaxByPSO(ptimes, psoParas); SchOptResult
tlboResult = bfsp.optCmaxByTLBO(ptimes, tlboParas); System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
执行结果如下:
----模拟退火算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 3.0 1.0 1.0 5.0 21.0 ; 3.0 2.0 2.0 21.0 29.0 ; 3.0 3.0 3.0 37.0 69.0 ; 3.0 4.0 4.0 69.0 90.0 ; 3.0 5.0 5.0 90.0 102.0 ; 1.0 1.0 1.0 21.0 34.0 ; 1.0 2.0 2.0 37.0 68.0 ; 1.0 3.0 3.0 69.0 89.0 ; 1.0 4.0 4.0 90.0 119.0 ; 1.0 5.0 5.0 119.0 139.0 ; 7.0 1.0 1.0 37.0 59.0 ; 7.0 2.0 2.0 69.0 93.0 ; 7.0 3.0 3.0 93.0 123.0 ; 7.0 4.0 4.0 123.0 142.0 ; 7.0 5.0 5.0 142.0 175.0 ; 2.0 1.0 1.0 69.0 92.0 ; 2.0 2.0 2.0 93.0 119.0 ; 2.0 3.0 3.0 123.0 136.0 ; 2.0 4.0 4.0 142.0 176.0 ; 2.0 5.0 5.0 176.0 184.0 ; 6.0 1.0 1.0 93.0 102.0 ; 6.0 2.0 2.0 123.0 131.0 ; 6.0 3.0 3.0 142.0 172.0 ; 6.0 4.0 4.0 176.0 181.0 ; 6.0 5.0 5.0 184.0 205.0 ; 5.0 1.0 1.0 123.0 143.0 ; 5.0 2.0 2.0 143.0 160.0 ; 5.0 3.0 3.0 176.0 185.0 ; 5.0 4.0 4.0 185.0 190.0 ; 5.0 5.0 5.0 205.0 218.0 ; ----模拟退火算法获得的最大完工时间为----- 218.0 ----遗传算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 3.0 1.0 1.0 5.0 21.0 ; 3.0 2.0 2.0 21.0 29.0 ; 3.0 3.0 3.0 37.0 69.0 ; 3.0 4.0 4.0 69.0 90.0 ; 3.0 5.0 5.0 90.0 102.0 ; 1.0 1.0 1.0 21.0 34.0 ; 1.0 2.0 2.0 37.0 68.0 ; 1.0 3.0 3.0 69.0 89.0 ; 1.0 4.0 4.0 90.0 119.0 ; 1.0 5.0 5.0 119.0 139.0 ; 7.0 1.0 1.0 37.0 59.0 ; 7.0 2.0 2.0 69.0 93.0 ; 7.0 3.0 3.0 93.0 123.0 ; 7.0 4.0 4.0 123.0 142.0 ; 7.0 5.0 5.0 142.0 175.0 ; 2.0 1.0 1.0 69.0 92.0 ; 2.0 2.0 2.0 93.0 119.0 ; 2.0 3.0 3.0 123.0 136.0 ; 2.0 4.0 4.0 142.0 176.0 ; 2.0 5.0 5.0 176.0 184.0 ; 6.0 1.0 1.0 93.0 102.0 ; 6.0 2.0 2.0 123.0 131.0 ; 6.0 3.0 3.0 142.0 172.0 ; 6.0 4.0 4.0 176.0 181.0 ; 6.0 5.0 5.0 184.0 205.0 ; 5.0 1.0 1.0 123.0 143.0 ; 5.0 2.0 2.0 143.0 160.0 ; 5.0 3.0 3.0 176.0 185.0 ; 5.0 4.0 4.0 185.0 190.0 ; 5.0 5.0 5.0 205.0 218.0 ; ----遗传算法获得的最大完工时间为----- 218.0 ----粒子群算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 6.0 1.0 1.0 5.0 14.0 ; 6.0 2.0 2.0 14.0 22.0 ; 6.0 3.0 3.0 37.0 67.0 ; 6.0 4.0 4.0 67.0 72.0 ; 6.0 5.0 5.0 72.0 93.0 ; 2.0 1.0 1.0 14.0 37.0 ; 2.0 2.0 2.0 37.0 63.0 ; 2.0 3.0 3.0 67.0 80.0 ; 2.0 4.0 4.0 80.0 114.0 ; 2.0 5.0 5.0 114.0 122.0 ; 7.0 1.0 1.0 37.0 59.0 ; 7.0 2.0 2.0 67.0 91.0 ; 7.0 3.0 3.0 91.0 121.0 ; 7.0 4.0 4.0 121.0 140.0 ; 7.0 5.0 5.0 140.0 173.0 ; 1.0 1.0 1.0 67.0 80.0 ; 1.0 2.0 2.0 91.0 122.0 ; 1.0 3.0 3.0 122.0 142.0 ; 1.0 4.0 4.0 142.0 171.0 ; 1.0 5.0 5.0 173.0 193.0 ; 3.0 1.0 1.0 91.0 107.0 ; 3.0 2.0 2.0 122.0 130.0 ; 3.0 3.0 3.0 142.0 174.0 ; 3.0 4.0 4.0 174.0 195.0 ; 3.0 5.0 5.0 195.0 207.0 ; 5.0 1.0 1.0 122.0 142.0 ; 5.0 2.0 2.0 142.0 159.0 ; 5.0 3.0 3.0 174.0 183.0 ; 5.0 4.0 4.0 195.0 200.0 ; 5.0 5.0 5.0 207.0 220.0 ; ----粒子群算法获得的最大完工时间为----- 220.0 ----蚁群算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 6.0 1.0 1.0 5.0 14.0 ; 6.0 2.0 2.0 14.0 22.0 ; 6.0 3.0 3.0 37.0 67.0 ; 6.0 4.0 4.0 67.0 72.0 ; 6.0 5.0 5.0 72.0 93.0 ; 2.0 1.0 1.0 14.0 37.0 ; 2.0 2.0 2.0 37.0 63.0 ; 2.0 3.0 3.0 67.0 80.0 ; 2.0 4.0 4.0 80.0 114.0 ; 2.0 5.0 5.0 114.0 122.0 ; 7.0 1.0 1.0 37.0 59.0 ; 7.0 2.0 2.0 67.0 91.0 ; 7.0 3.0 3.0 91.0 121.0 ; 7.0 4.0 4.0 121.0 140.0 ; 7.0 5.0 5.0 140.0 173.0 ; 1.0 1.0 1.0 67.0 80.0 ; 1.0 2.0 2.0 91.0 122.0 ; 1.0 3.0 3.0 122.0 142.0 ; 1.0 4.0 4.0 142.0 171.0 ; 1.0 5.0 5.0 173.0 193.0 ; 3.0 1.0 1.0 91.0 107.0 ; 3.0 2.0 2.0 122.0 130.0 ; 3.0 3.0 3.0 142.0 174.0 ; 3.0 4.0 4.0 174.0 195.0 ; 3.0 5.0 5.0 195.0 207.0 ; 5.0 1.0 1.0 122.0 142.0 ; 5.0 2.0 2.0 142.0 159.0 ; 5.0 3.0 3.0 174.0 183.0 ; 5.0 4.0 4.0 195.0 200.0 ; 5.0 5.0 5.0 207.0 220.0 ; ----蚁群算法获得的最大完工时间为----- 220.0 ----教学算法获得的最优排序调度方案如下----- 4.0 1.0 1.0 0.0 5.0 ; 4.0 2.0 2.0 5.0 10.0 ; 4.0 3.0 3.0 10.0 37.0 ; 4.0 4.0 4.0 37.0 48.0 ; 4.0 5.0 5.0 48.0 67.0 ; 3.0 1.0 1.0 5.0 21.0 ; 3.0 2.0 2.0 21.0 29.0 ; 3.0 3.0 3.0 37.0 69.0 ; 3.0 4.0 4.0 69.0 90.0 ; 3.0 5.0 5.0 90.0 102.0 ; 1.0 1.0 1.0 21.0 34.0 ; 1.0 2.0 2.0 37.0 68.0 ; 1.0 3.0 3.0 69.0 89.0 ; 1.0 4.0 4.0 90.0 119.0 ; 1.0 5.0 5.0 119.0 139.0 ; 7.0 1.0 1.0 37.0 59.0 ; 7.0 2.0 2.0 69.0 93.0 ; 7.0 3.0 3.0 93.0 123.0 ; 7.0 4.0 4.0 123.0 142.0 ; 7.0 5.0 5.0 142.0 175.0 ; 2.0 1.0 1.0 69.0 92.0 ; 2.0 2.0 2.0 93.0 119.0 ; 2.0 3.0 3.0 123.0 136.0 ; 2.0 4.0 4.0 142.0 176.0 ; 2.0 5.0 5.0 176.0 184.0 ; 6.0 1.0 1.0 93.0 102.0 ; 6.0 2.0 2.0 123.0 131.0 ; 6.0 3.0 3.0 142.0 172.0 ; 6.0 4.0 4.0 176.0 181.0 ; 6.0 5.0 5.0 184.0 205.0 ; 5.0 1.0 1.0 123.0 143.0 ; 5.0 2.0 2.0 143.0 160.0 ; 5.0 3.0 3.0 176.0 185.0 ; 5.0 4.0 4.0 185.0 190.0 ; 5.0 5.0 5.0 205.0 218.0 ; ----教学算法获得的最大完工时间为----- 218.0 |
可以看出五种优化算法优化的结果分别为218、218、220、220和218,优化结果接近。
以教学算法获得的结果制作甘特图如下:
前述示例对使用BFSP类中的方法进行Cmax目标优化求解过程进行描述,该类中进行Lmax目标优化的方法求解过程如此类似,只是使用过程中要选择不同的方法和设置的参数有所不同而已,不再赘述。
HFSP类主要封装了混合流水车间调度问题计算和优化所使用的一些方法
HFSP类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getSchedule(double[][] ptimes, int[] machQtys, double[]
dueTimes, int[] seq) 基于作业时间、作业排序获得零等待混合流水车间的详细调度方案 |
double[][] |
getSchedule(double[][] ptimes, int[] machQtys, int[]
seq) 基于作业时间、各工序机器数量、作业排序获得混合流水车间FFc的详细调度方案 |
double[][] |
getSchRelease(double[][] ptimes, int[] machQtys, int[]
seq, double[] releaseTimes) 基于作业时间、作业排序获得混合流水车间的详细调度方案 |
double[][] |
getSchRelease(double[][] ptimes, int[] machQtys, int[]
seq, double[] releaseTimes, double[] dueTimes) 基于作业时间、作业排序获得混合流水车间的详细调度方案 |
SchOptResult |
optCmaxByACO(double[][] ptimes, int[] machQtys, double[]
params) 利用蚁群算法进行混合流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCmaxByGA(double[][] ptimes, int[] machQtys, double[]
params) 利用遗传算法进行混合流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCmaxByPSO(double[][] ptimes, int[] machQtys, double[]
params) 利用粒子群算法进行混合流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCmaxBySA(double[][] ptimes, int[] machQtys, double[]
params) 利用模拟退火算法进行混合流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCmaxByTLBO(double[][] ptimes, int[] machQtys, double[]
params) 利用教学算法进行混合流水车间Fm|perm,block|Cmax问题的优化求解 |
SchOptResult |
optCtotalByACO(double[][] ptimes, int[] machQtys, double[]
params) 利用蚁群算法进行混合流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByGA(double[][] ptimes, int[] machQtys, double[]
params) 利用遗传算法进行混合流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByPSO(double[][] ptimes, int[] machQtys, double[]
params) 利用粒子群算法进行混合流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optCtotalBySA(double[][] ptimes, int[] machQtys, double[]
params) 利用模拟退火算法进行混合流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optCtotalByTLBO(double[][] ptimes, int[] machQtys, double[]
params) 利用教学算法进行混合流水车间Fm|perm,block|Ctotal问题的优化求解 |
SchOptResult |
optLmaxByACO(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用蚁群算法进行混合流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLmaxByGA(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用遗传算法进行混合流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLmaxByPSO(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用粒子群算法进行混合流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLmaxBySA(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用模拟退火算法进行混合流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLmaxByTLBO(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用教学算法进行混合流水车间Fm|perm,block|Lmax问题的优化求解 |
SchOptResult |
optLtotalByACO(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用蚁群算法进行混合流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByGA(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用遗传算法进行混合流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByPSO(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用粒子群算法进行混合流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optLtotalBySA(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用模拟退火算法进行混合流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optLtotalByTLBO(double[][] ptimes, int[] machQtys, double[]
params, double[] dueTimes) 利用教学算法进行混合流水车间Fm|perm,block|Ltotal问题的优化求解 |
SchOptResult |
optRjCmaxByACO(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes) 利用蚁群算法进行混合流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByGA(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes) 利用遗传算法进行混合流水车间Fm|prmu,rj|Cmax的优化求解 |
SchOptResult |
optRjCmaxByPSO(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes) 利用粒子群算法进行混合流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxBySA(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes) 利用模拟退火算法进行混合流水车间Fm||prmu,rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByTLBO(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes) 利用教学算法进行混合流水车间Fm|perm,rj|Cmax问题的优化求解 |
SchOptResult |
optRjLmaxByACO(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes, double[] dueTimes) 利用蚁群算法进行混合流水车间Fm|perm,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByGA(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes, double[] dueTimes) 利用遗传算法进行混合流水车间Fm|prmu,rj|Lmax的优化求解 |
SchOptResult |
optRjLmaxByPSO(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes, double[] dueTimes) 利用粒子群算法进行混合流水车间Fm|perm,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxBySA(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes, double[] dueTimes) 利用模拟退火算法进行混合流水车间Fm||prmu,rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByTLBO(double[][] ptimes, int[] machQtys, double[]
params, double[] releaseTimes, double[] dueTimes) 利用教学算法进行混合流水车间Fm|perm,rj|Lmax问题的优化求解
|
例1:考虑7作业5工序的置换流水车间调度问题,其中各作业在各个工序的加工时间如下表所示,其中进行五道工序加工的机器数量分别为:1、2、2、1、2,请利用HFSP类中的方法实现如下两种作业排序的详细调度方案:
(1)
顺序排序:1、2、3、4、5、6、7;
(2)
逆序排序:7、6、5、4、3、2、1。
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
1 |
13 |
31 |
20 |
29 |
20 |
2 |
23 |
26 |
13 |
34 |
8 |
3 |
16 |
8 |
32 |
21 |
12 |
4 |
5 |
5 |
27 |
11 |
19 |
5 |
20 |
17 |
9 |
5 |
13 |
6 |
9 |
8 |
30 |
5 |
21 |
7 |
22 |
24 |
30 |
19 |
33 |
程序实现如下:
import easyopt.common.EasyArray; import easyopt.shopSch.fsp.HFSP; public class Example_HFSP { public void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; int[] machQty = {1,2,2,1,2}; int[] seq1 = {1,2,3,4,5,6,7}; int[] seq2 = {7,6,5,4,3,2,1}; HFSP hfsp =new HFSP(); double[][] sch1 =hfsp.getSchedule(ptimes, machQty, seq1); System.out.println("---顺序排产结果---"); EasyArray.printArray(sch1); double[][] sch2 = hfsp.getSchedule(ptimes, machQty, seq2); System.out.println("---逆序排产结果---"); EasyArray.printArray(sch2); } } |
执行结果如下:
---顺序排产结果--- 1.0 1.0 1.0 0.0 13.0 ; 2.0 1.0 1.0 13.0 36.0 ; 3.0 1.0 1.0 36.0 52.0 ; 4.0 1.0 1.0 52.0 57.0 ; 5.0 1.0 1.0 57.0 77.0 ; 6.0 1.0 1.0 77.0 86.0 ; 7.0 1.0 1.0 86.0 108.0 ; 1.0 2.0 2.0 13.0 44.0 ; 2.0 3.0 2.0 36.0 62.0 ; 3.0 2.0 2.0 52.0 60.0 ; 4.0 2.0 2.0 60.0 65.0 ; 5.0 3.0 2.0 77.0 94.0 ; 6.0 2.0 2.0 86.0 94.0 ; 7.0 2.0 2.0 108.0 132.0 ; 1.0 4.0 3.0 44.0 64.0 ; 2.0 5.0 3.0 62.0 75.0 ; 3.0 4.0 3.0 64.0 96.0 ; 4.0 5.0 3.0 75.0 102.0 ; 5.0 4.0 3.0 96.0 105.0 ; 6.0 5.0 3.0 102.0 132.0 ; 7.0 4.0 3.0 132.0 162.0 ; 1.0 6.0 4.0 64.0 93.0 ; 2.0 6.0 4.0 93.0 127.0 ; 3.0 6.0 4.0 127.0 148.0 ; 4.0 6.0 4.0 148.0 159.0 ; 5.0 6.0 4.0 159.0 164.0 ; 6.0 6.0 4.0 164.0 169.0 ; 7.0 6.0 4.0 169.0 188.0 ; 1.0 7.0 5.0 93.0 113.0 ; 2.0 8.0 5.0 127.0 135.0 ; 3.0 7.0 5.0 148.0 160.0 ; 4.0 8.0 5.0 159.0 178.0 ; 5.0 7.0 5.0 164.0 177.0 ; 6.0 7.0 5.0 177.0 198.0 ; 7.0 8.0 5.0 188.0 221.0 ; ---逆序排产结果--- 7.0 1.0 1.0 0.0 22.0 ; 6.0 1.0 1.0 22.0 31.0 ; 5.0 1.0 1.0 31.0 51.0 ; 4.0 1.0 1.0 51.0 56.0 ; 3.0 1.0 1.0 56.0 72.0 ; 2.0 1.0 1.0 72.0 95.0 ; 1.0 1.0 1.0 95.0 108.0 ; 7.0 2.0 2.0 22.0 46.0 ; 6.0 3.0 2.0 31.0 39.0 ; 5.0 3.0 2.0 51.0 68.0 ; 4.0 2.0 2.0 56.0 61.0 ; 3.0 2.0 2.0 72.0 80.0 ; 2.0 3.0 2.0 95.0 121.0 ; 1.0 2.0 2.0 108.0 139.0 ; 7.0 4.0 3.0 46.0 76.0 ; 6.0 5.0 3.0 39.0 69.0 ; 5.0 5.0 3.0 69.0 78.0 ; 4.0 4.0 3.0 76.0 103.0 ; 3.0 5.0 3.0 80.0 112.0 ; 2.0 4.0 3.0 121.0 134.0 ; 1.0 5.0 3.0 139.0 159.0 ; 6.0 6.0 4.0 69.0 74.0 ; 7.0 6.0 4.0 76.0 95.0 ; 5.0 6.0 4.0 95.0 100.0 ; 4.0 6.0 4.0 103.0 114.0 ; 3.0 6.0 4.0 114.0 135.0 ; 2.0 6.0 4.0 135.0 169.0 ; 1.0 6.0 4.0 169.0 198.0 ; 6.0 7.0 5.0 74.0 95.0 ; 5.0 8.0 5.0 100.0 113.0 ; 7.0 7.0 5.0 95.0 128.0 ; 4.0 8.0 5.0 114.0 133.0 ; 3.0 7.0 5.0 135.0 147.0 ; 2.0 8.0 5.0 169.0 177.0 ; 1.0 7.0 5.0 198.0 218.0 ; |
其中顺序排产的最大完工时间为221,逆序排产的最大完工时间为218,两种方案的调度甘特图分别如下图所示。
例2:采用HFSP中相关优化方法对例1中的问题优化求解,获取Cmax最小的排序方案。
程序设计如下:
import easyopt.common.EasyArray; import easyopt.shopSch.SchOptResult; import easyopt.shopSch.Schedule; import easyopt.shopSch.fsp.HFSP; public class Example_HFSP { public
void main(String[] args) { double[][] ptimes = {{13,31,20,29,20},{23,26,13,34,8},{16,8,32,21,12},{5,5,27,11,19},{20,17,9,5,13},{9,8,30,5,21},{22,24,30,19,33}}; int[]
machQty = {1,2,2,1,2}; double[] saParas = {0.992,40,400,70}; double[] gaParas = {400,40,0.7,0.6,70}; double[] acoParas = {0.2,40,400,70}; double[] psoParas = {0.9,2,2,40,400,70}; double[] tlboParas = {40,400,70}; HFSP hfsp =new HFSP(); SchOptResult
saResult = hfsp.optCmaxBySA(ptimes,machQty,saParas); SchOptResult
gaResult = hfsp.optCmaxByGA(ptimes, machQty,gaParas); SchOptResult
acoResult = hfsp.optCmaxByACO(ptimes,machQty,acoParas); SchOptResult
psoResult = hfsp.optCmaxByPSO(ptimes,machQty,psoParas); SchOptResult
tlboResult = hfsp.optCmaxByTLBO(ptimes,machQty,tlboParas); System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
执行结果如下:
----模拟退火算法获得的最优排序调度方案如下----- 3.0 1.0 1.0 0.0 16.0 ; 4.0 1.0 1.0 16.0 21.0 ; 1.0 1.0 1.0 21.0 34.0 ; 7.0 1.0 1.0 34.0 56.0 ; 5.0 1.0 1.0 56.0 76.0 ; 6.0 1.0 1.0 76.0 85.0 ; 2.0 1.0 1.0 85.0 108.0 ; 3.0 2.0 2.0 16.0 24.0 ; 4.0 3.0 2.0 21.0 26.0 ; 1.0 2.0 2.0 34.0 65.0 ; 7.0 3.0 2.0 56.0 80.0 ; 5.0 2.0 2.0 76.0 93.0 ; 6.0 3.0 2.0 85.0 93.0 ; 2.0 2.0 2.0 108.0 134.0 ; 3.0 4.0 3.0 24.0 56.0 ; 4.0 5.0 3.0 26.0 53.0 ; 1.0 5.0 3.0 65.0 85.0 ; 7.0 4.0 3.0 80.0 110.0 ; 5.0 5.0 3.0 93.0 102.0 ; 6.0 5.0 3.0 102.0 132.0 ; 2.0 4.0 3.0 134.0 147.0 ; 3.0 6.0 4.0 56.0 77.0 ; 4.0 6.0 4.0 77.0 88.0 ; 1.0 6.0 4.0 88.0 117.0 ; 7.0 6.0 4.0 117.0 136.0 ; 5.0 6.0 4.0 136.0 141.0 ; 6.0 6.0 4.0 141.0 146.0 ; 2.0 6.0 4.0 147.0 181.0 ; 3.0 7.0 5.0 77.0 89.0 ; 4.0 8.0 5.0 88.0 107.0 ; 1.0 7.0 5.0 117.0 137.0 ; 7.0 8.0 5.0 136.0 169.0 ; 5.0 7.0 5.0 141.0 154.0 ; 6.0 7.0 5.0 154.0 175.0 ; 2.0 8.0 5.0 181.0 189.0 ; ----模拟退火算法获得的最大完工时间为----- 189.0 ----遗传算法获得的最优排序调度方案如下----- 1.0 1.0 1.0 0.0 13.0 ; 4.0 1.0 1.0 13.0 18.0 ; 2.0 1.0 1.0 18.0 41.0 ; 6.0 1.0 1.0 41.0 50.0 ; 7.0 1.0 1.0 50.0 72.0 ; 5.0 1.0 1.0 72.0 92.0 ; 3.0 1.0 1.0 92.0 108.0 ; 1.0 2.0 2.0 13.0 44.0 ; 4.0 3.0 2.0 18.0 23.0 ; 2.0 3.0 2.0 41.0 67.0 ; 6.0 2.0 2.0 50.0 58.0 ; 7.0 2.0 2.0 72.0 96.0 ; 5.0 3.0 2.0 92.0 109.0 ; 3.0 2.0 2.0 108.0 116.0 ; 1.0 4.0 3.0 44.0 64.0 ; 4.0 5.0 3.0 23.0 50.0 ; 2.0 5.0 3.0 67.0 80.0 ; 6.0 4.0 3.0 64.0 94.0 ; 7.0 5.0 3.0 96.0 126.0 ; 5.0 4.0 3.0 109.0 118.0 ; 3.0 4.0 3.0 118.0 150.0 ; 4.0 6.0 4.0 50.0 61.0 ; 1.0 6.0 4.0 64.0 93.0 ; 2.0 6.0 4.0 93.0 127.0 ; 6.0 6.0 4.0 127.0 132.0 ; 7.0 6.0 4.0 132.0 151.0 ; 5.0 6.0 4.0 151.0 156.0 ; 3.0 6.0 4.0 156.0 177.0 ; 4.0 7.0 5.0 61.0 80.0 ; 2.0 8.0 5.0 127.0 135.0 ; 1.0 7.0 5.0 93.0 113.0 ; 6.0 7.0 5.0 132.0 153.0 ; 7.0 8.0 5.0 151.0 184.0 ; 5.0 7.0 5.0 156.0 169.0 ; 3.0 7.0 5.0 177.0 189.0 ; ----遗传算法获得的最大完工时间为----- 189.0 ----粒子群算法获得的最优排序调度方案如下----- 1.0 1.0 1.0 0.0 13.0 ; 4.0 1.0 1.0 13.0 18.0 ; 2.0 1.0 1.0 18.0 41.0 ; 6.0 1.0 1.0 41.0 50.0 ; 7.0 1.0 1.0 50.0 72.0 ; 5.0 1.0 1.0 72.0 92.0 ; 3.0 1.0 1.0 92.0 108.0 ; 1.0 2.0 2.0 13.0 44.0 ; 4.0 3.0 2.0 18.0 23.0 ; 2.0 3.0 2.0 41.0 67.0 ; 6.0 2.0 2.0 50.0 58.0 ; 7.0 2.0 2.0 72.0 96.0 ; 5.0 3.0 2.0 92.0 109.0 ; 3.0 2.0 2.0 108.0 116.0 ; 1.0 4.0 3.0 44.0 64.0 ; 4.0 5.0 3.0 23.0 50.0 ; 2.0 5.0 3.0 67.0 80.0 ; 6.0 4.0 3.0 64.0 94.0 ; 7.0 5.0 3.0 96.0 126.0 ; 5.0 4.0 3.0 109.0 118.0 ; 3.0 4.0 3.0 118.0 150.0 ; 4.0 6.0 4.0 50.0 61.0 ; 1.0 6.0 4.0 64.0 93.0 ; 2.0 6.0 4.0 93.0 127.0 ; 6.0 6.0 4.0 127.0 132.0 ; 7.0 6.0 4.0 132.0 151.0 ; 5.0 6.0 4.0 151.0 156.0 ; 3.0 6.0 4.0 156.0 177.0 ; 4.0 7.0 5.0 61.0 80.0 ; 2.0 8.0 5.0 127.0 135.0 ; 1.0 7.0 5.0 93.0 113.0 ; 6.0 7.0 5.0 132.0 153.0 ; 7.0 8.0 5.0 151.0 184.0 ; 5.0 7.0 5.0 156.0 169.0 ; 3.0 7.0 5.0 177.0 189.0 ; ----粒子群算法获得的最大完工时间为----- 189.0 ----蚁群算法获得的最优排序调度方案如下----- 1.0 1.0 1.0 0.0 13.0 ; 4.0 1.0 1.0 13.0 18.0 ; 2.0 1.0 1.0 18.0 41.0 ; 6.0 1.0 1.0 41.0 50.0 ; 7.0 1.0 1.0 50.0 72.0 ; 5.0 1.0 1.0 72.0 92.0 ; 3.0 1.0 1.0 92.0 108.0 ; 1.0 2.0 2.0 13.0 44.0 ; 4.0 3.0 2.0 18.0 23.0 ; 2.0 3.0 2.0 41.0 67.0 ; 6.0 2.0 2.0 50.0 58.0 ; 7.0 2.0 2.0 72.0 96.0 ; 5.0 3.0 2.0 92.0 109.0 ; 3.0 2.0 2.0 108.0 116.0 ; 1.0 4.0 3.0 44.0 64.0 ; 4.0 5.0 3.0 23.0 50.0 ; 2.0 5.0 3.0 67.0 80.0 ; 6.0 4.0 3.0 64.0 94.0 ; 7.0 5.0 3.0 96.0 126.0 ; 5.0 4.0 3.0 109.0 118.0 ; 3.0 4.0 3.0 118.0 150.0 ; 4.0 6.0 4.0 50.0 61.0 ; 1.0 6.0 4.0 64.0 93.0 ; 2.0 6.0 4.0 93.0 127.0 ; 6.0 6.0 4.0 127.0 132.0 ; 7.0 6.0 4.0 132.0 151.0 ; 5.0 6.0 4.0 151.0 156.0 ; 3.0 6.0 4.0 156.0 177.0 ; 4.0 7.0 5.0 61.0 80.0 ; 2.0 8.0 5.0 127.0 135.0 ; 1.0 7.0 5.0 93.0 113.0 ; 6.0 7.0 5.0 132.0 153.0 ; 7.0 8.0 5.0 151.0 184.0 ; 5.0 7.0 5.0 156.0 169.0 ; 3.0 7.0 5.0 177.0 189.0 ; ----蚁群算法获得的最大完工时间为----- 189.0 ----教学算法获得的最优排序调度方案如下----- 1.0 1.0 1.0 0.0 13.0 ; 4.0 1.0 1.0 13.0 18.0 ; 7.0 1.0 1.0 18.0 40.0 ; 5.0 1.0 1.0 40.0 60.0 ; 6.0 1.0 1.0 60.0 69.0 ; 3.0 1.0 1.0 69.0 85.0 ; 2.0 1.0 1.0 85.0 108.0 ; 1.0 2.0 2.0 13.0 44.0 ; 4.0 3.0 2.0 18.0 23.0 ; 7.0 3.0 2.0 40.0 64.0 ; 5.0 2.0 2.0 60.0 77.0 ; 6.0 3.0 2.0 69.0 77.0 ; 3.0 2.0 2.0 85.0 93.0 ; 2.0 3.0 2.0 108.0 134.0 ; 1.0 4.0 3.0 44.0 64.0 ; 4.0 5.0 3.0 23.0 50.0 ; 7.0 5.0 3.0 64.0 94.0 ; 5.0 4.0 3.0 77.0 86.0 ; 6.0 4.0 3.0 86.0 116.0 ; 3.0 5.0 3.0 94.0 126.0 ; 2.0 4.0 3.0 134.0 147.0 ; 4.0 6.0 4.0 50.0 61.0 ; 1.0 6.0 4.0 64.0 93.0 ; 7.0 6.0 4.0 94.0 113.0 ; 5.0 6.0 4.0 113.0 118.0 ; 6.0 6.0 4.0 118.0 123.0 ; 3.0 6.0 4.0 126.0 147.0 ; 2.0 6.0 4.0 147.0 181.0 ; 4.0 7.0 5.0 61.0 80.0 ; 7.0 8.0 5.0 113.0 146.0 ; 1.0 7.0 5.0 93.0 113.0 ; 5.0 7.0 5.0 118.0 131.0 ; 6.0 7.0 5.0 131.0 152.0 ; 3.0 8.0 5.0 147.0 159.0 ; 2.0 7.0 5.0 181.0 189.0 ; ----教学算法获得的最大完工时间为----- 189.0 |
可以看出五种优化算法优化的结果均为189,具有较好的优化能力。
以教学算法获得的结果制作甘特图如下:
前述示例对使用NWFSP类中的方法进行Cmax目标优化求解过程进行描述,该类中进行Lmax目标优化的方法求解过程如此类似,只是使用过程中要选择不同的方法和设置的参数有所不同而已,不再赘述。
easyopt.shopSch.jsp包中将包含作业车间调度计算和优化过程中涉及的类和方法,当前版本只包含一个基本的JSP类和一个JSP运算中的辅助类JSPCommon。
类 |
说明 |
JSP |
基本作业车间JSP调度优化计算中涉及到的方法: 基本作业车间具有的特点是车间具有m台机器设备,n项作业都需要经过m道工序方能完成,但是每项作业
的工艺路径不相同,如何安排不同机器上这n个作业的加工顺序,实现某些特定指标最优。 |
JSPCommon |
JSP运算过程中所用到的一些通用方法,主要是一些辅助处理的方法,例如输入工艺参数的有效性判断、生成可行排序方案或随机排序方案等 |
JSPCommon类主要封装了求解JSP调度问题过程中使用的一些辅助方法。
JSPCommon类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getCheckSequence(double[][] procData, int[][] seq) 基于作业时间、各设备上的作业排序进行排序的死锁检测,主要用于手工计算实验中用户输入的排序有效性检验 |
int |
getMachQty(double[][] ptimes) 根据输入的工时数据获得最大机器的编码,也就是问题涉及的最多机器数量 |
java.lang.String |
getRandSequence(double[][] procData) 根据有效的工艺参数,随机返回各个机器上的作业顺序字符串,但不保证作业排序没有死锁现象 |
java.lang.String |
getRandSequenceGood(double[][] procData) 根据有效的工艺参数,随机返回各个机器上的作业顺序字符串,保证作业排序没有死锁现象 |
int |
judgePTimes(double[][] ptimes) 对作业时间的判断程序,因为要求输入的工时数据为二维数组,每一行表示一个作业的工艺信息,奇数列【2i-1】表示该作业第i道工序所用机器编码,偶数列【2i】表示该作业在第i道工序所用的时间, 所以本方法主要判断【1】作业时间不是偶数列,【2】数据有负数,【3】奇数列机器的编号比1小 【4】某台设备编码没有出现在某一行; |
int |
judgeSequenceArray(int[][] sequences) 根据输入的排序二维数组,每一行表示一台设备上各个作业的先后顺序,主要判断每台设备上作业顺序码是否完备-不能小于零,每个数字只能出现一次 |
例1:考虑有六台设备的作业车间需要完成10项作业,这10项作业的工艺参数如下表所示。
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
Proc6 |
||||||
MachId |
pTime |
MachId |
pTime |
MachId |
pTime |
MachId |
pTime |
MachId |
pTime |
MachId |
pTime |
|
1 |
2 |
13 |
5 |
19 |
3 |
33 |
1 |
23 |
4 |
38 |
6 |
33 |
2 |
4 |
37 |
1 |
21 |
2 |
25 |
5 |
11 |
6 |
36 |
3 |
14 |
3 |
2 |
23 |
5 |
42 |
1 |
7 |
3 |
21 |
6 |
27 |
4 |
19 |
4 |
6 |
34 |
5 |
26 |
1 |
18 |
4 |
19 |
2 |
39 |
3 |
28 |
5 |
3 |
34 |
5 |
12 |
4 |
31 |
1 |
38 |
2 |
22 |
6 |
11 |
6 |
3 |
16 |
4 |
26 |
5 |
13 |
1 |
40 |
6 |
25 |
2 |
18 |
7 |
5 |
27 |
3 |
15 |
2 |
11 |
1 |
12 |
4 |
29 |
6 |
38 |
8 |
4 |
9 |
6 |
30 |
2 |
16 |
3 |
13 |
5 |
8 |
1 |
21 |
9 |
2 |
39 |
3 |
13 |
5 |
7 |
4 |
23 |
6 |
15 |
1 |
36 |
10 |
2 |
27 |
6 |
22 |
1 |
32 |
5 |
24 |
4 |
10 |
3 |
5 |
试利用JSPCommon类中的方法完成如下两项工作:
(1)
判断每台设备上各个作业按照如下排序能够顺利开展生产活动,即排序之间有没有死锁现象?
MachId |
jobId1 |
jobId2 |
jobId3 |
jobId4 |
jobId5 |
jobId6 |
jobId7 |
jobId8 |
jobId9 |
jobId10 |
1 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
2 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
3 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
4 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
5 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
6 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
上表的排序其实是让每前三台设备根据作业的编号逐次加工,后三台设备根据作业编号逆序逐次加工,但是因为不同作业在同一机器上所要完成的工序不同,可能会造成上述排序死锁。
(2)
生成一个不存在死锁的作业排序。
完成该问题的两个方法详细使用说明如下:
public double[][] getCheckSequence(double[][] procData,
int[][] seq) 基于作业时间、各设备上的作业排序进行每个排序的死锁检测,主要用于手工计算实验中用户输入的排序有效性检验 参数: procData - 作业的工艺数据二维数组,行为作业、【2i-1】列为工序i所用机器编码,【2i】列为工序i所用时间 seq - 各台设备上不同加工顺序的作业编号二维数组,作业编号从1开始,每一行表示一台设备上排序的作业 返回: 返回各机器上排序的检测结果,共六列,第一列:机器编号,第二类:排序列号,第三列:作业编号
第四列:作业工序号,第五列:作业时间,第六列:是否有效;0-没解,存在死锁之后,1-可解;若返回值第六列出现0,则表示当前排序存在死锁 |
public java.lang.String
getRandSequenceGood(double[][] procData) 根据有效的工艺参数,随机返回各个机器上的作业顺序字符串,保证作业排序没有死锁现象 参数: procData - 作业的工艺数据二维数组,行为作业、【2i-1】列为工序i所用机器编码,从1开始编码, 【2i】列为工序i所用时间 返回: 返回排序字符串 |
完成上述两个问题的程序如下:
import easyopt.common.EasyArray; import easyopt.shopSch.jsp.JSPCommon; public class Example_JSPCommon { public void main(String[] args) { double[][] procData =
{{2,13,5,19,3,33,1,23,4,38,6,33},{4,37,1,21,2,25,5,11,6,36,3,14},{2,23,5,42,1,7,3,21,6,27,4,19},{6,34,5,26,1,18,4,19,2,39,3,28},{3,34,5,12,4,31,1,38,2,22,6,11},{3,16,4,26,5,13,1,40,6,25,2,18},{5,27,3,15,2,11,1,12,4,29,6,38},{4,9,6,30,2,16,3,13,5,8,1,21},{2,39,3,13,5,7,4,23,6,15,1,36},{2,27,6,22,1,32,5,24,4,10,3,5}}; int[][] seq =
{{1,2,3,4,5,6,7,8,9,10},{1,2,3,4,5,6,7,8,9,10},{1,2,3,4,5,6,7,8,9,10},{10,9,8,7,6,5,4,3,2,1},{10,9,8,7,6,5,4,3,2,1},{10,9,8,7,6,5,4,3,2,1}}; JSPCommon
jspCommon = new JSPCommon(); double[][] result = jspCommon.getCheckSequence(procData, seq); System.out.println("--死锁检验结果--"); EasyArray.printArray(result); int a = jspCommon.judgePTimes(procData); if(a==0) {//若为0表示输入工艺参数存在错误,具体参看judgePTimes方法说明 String
goodSeq = jspCommon.getRandSequenceGood(procData); System.out.println("--随机生成没有死锁的排序如下--"); System.out.println(goodSeq); } } } |
执行结果如下:
--死锁检验结果-- 1.0 1.0 1.0 4.0 23.0 0.0 ; 1.0 2.0 2.0 2.0 21.0 0.0 ; 1.0 3.0 3.0 3.0 7.0 0.0 ; 1.0 4.0 4.0 3.0 18.0 0.0 ; 1.0 5.0 5.0 4.0 38.0 0.0 ; 1.0 6.0 6.0 4.0 40.0 0.0 ; 1.0 7.0 7.0 4.0 12.0 0.0 ; 1.0 8.0 8.0 6.0 21.0 0.0 ; 1.0 9.0 9.0 6.0 36.0 0.0 ; 1.0 10.0 10.0 3.0 32.0 0.0 ; 2.0 1.0 1.0 1.0
13.0 1.0 ; 2.0 2.0 2.0 3.0 25.0 0.0 ; 2.0 3.0 3.0 1.0 23.0 0.0 ; 2.0 4.0 4.0 5.0 39.0 0.0 ; 2.0 5.0 5.0 5.0 22.0 0.0 ; 2.0 6.0 6.0 6.0 18.0 0.0 ; 2.0 7.0 7.0 3.0 11.0 0.0 ; 2.0 8.0 8.0 3.0 16.0 0.0 ; 2.0 9.0 9.0 1.0 39.0 0.0 ; 2.0 10.0 10.0 1.0 27.0 0.0 ; 3.0 1.0 1.0 3.0 33.0 0.0 ; 3.0 2.0 2.0 6.0 14.0 0.0 ; 3.0 3.0 3.0 4.0 21.0 0.0 ; 3.0 4.0 4.0 6.0 28.0 0.0 ; 3.0 5.0 5.0 1.0 34.0 0.0 ; 3.0 6.0 6.0 1.0 16.0 0.0 ; 3.0 7.0 7.0 2.0 15.0 0.0 ; 3.0 8.0 8.0 4.0 13.0 0.0 ; 3.0 9.0 9.0 2.0 13.0 0.0 ; 3.0 10.0 10.0 6.0 5.0 0.0 ; 4.0 1.0 10.0 5.0 10.0 0.0 ; 4.0 2.0 9.0 4.0 23.0 0.0 ; 4.0 3.0 8.0 1.0 9.0 0.0 ; 4.0 4.0 7.0 5.0 29.0 0.0 ; 4.0 5.0 6.0 2.0 26.0 0.0 ; 4.0 6.0 5.0 3.0 31.0 0.0 ; 4.0 7.0 4.0 4.0 19.0 0.0 ; 4.0 8.0 3.0 6.0 19.0 0.0 ; 4.0 9.0 2.0 1.0 37.0 0.0 ; 4.0 10.0 1.0 5.0 38.0 0.0 ; 5.0 1.0 10.0 4.0 24.0 0.0 ; 5.0 2.0 9.0 3.0 7.0 0.0 ; 5.0 3.0 8.0 5.0 8.0 0.0 ; 5.0 4.0 7.0 1.0 27.0 0.0 ; 5.0 5.0 6.0 3.0 13.0 0.0 ; 5.0 6.0 5.0 2.0 12.0 0.0 ; 5.0 7.0 4.0 2.0 26.0 0.0 ; 5.0 8.0 3.0 2.0 42.0 0.0 ; 5.0 9.0 2.0 4.0 11.0 0.0 ; 5.0 10.0 1.0 2.0 19.0 0.0 ; 6.0 1.0 10.0 2.0 22.0 0.0 ; 6.0 2.0 9.0 5.0 15.0 0.0 ; 6.0 3.0 8.0 2.0 30.0 0.0 ; 6.0 4.0 7.0 6.0 38.0 0.0 ; 6.0 5.0 6.0 5.0 25.0 0.0 ; 6.0 6.0 5.0 6.0 11.0 0.0 ; 6.0 7.0 4.0 1.0 34.0 0.0 ; 6.0 8.0 3.0 5.0 27.0 0.0 ; 6.0 9.0 2.0 5.0 36.0 0.0 ; 6.0 10.0 1.0 6.0 33.0 0.0 ; --随机生成没有死锁的排序如下-- 2 4 3 10 5 6 1 7 9 8 ;3 10 9 1 7 8 2 5 4 6
;5 6 7 9 1 8 3 2 4 10 ;8 2 6 5 4 9 10 7 1 3 ;7 4 5 1 3 6 9 2 10 8 ;4 10 8 9 2
3 6 1 7 5 ; |
从死锁判定结果看,按照设定的排序只能开始一项任务,即作业1的第一道工序任务可以在机器2上开工,其他作业的任务都无法开工,具体可以参看下图:
图中J后面第一个数字为作业编号,第二个数字为该作业的工序编号,从图中可以看出,J1_1可以在机器2【即M2】上开工,但是后续最先可以开工的任务从机器1到机器6分别为:J1_4、J2_3、J1_3、J10_5、J10_4、J10_2,这些作业的前一个工序任务都没有开工,而且在这些任务开工之后,所以给定的作业排序存在死锁现象,无法开工。
上述程序最后输出的为一种随机可行排序,不存在死锁现象。
JSP类主要封装了求解基本JSP调度问题的计算和优化方法。
JSP类封装的方法及其作用如下表所示。
限定符和类型 |
方法和说明 |
double[][] |
getSchedule(double[][] procData, double[] dueTimes, int[]
seq) 基于作业时间、作业排序获得零等待阻塞流水车间的详细调度方案 |
double[][] |
getSchedule(double[][] procData, double[] dueTimes, int[][]
seq) 基于各个作业的工艺参数、各设备上作业的排序以及作业的交付时间获得作业车间JSP的详细调度方案:手工计算实验中使用 |
double[][] |
getSchedule(double[][] procData, int[] seq) 基于各个作业的工艺参数和连续的作业排序获得基本作业车间Jm的详细调度方案:主要用于优化算法中解编码的详细调度方案生成 |
double[][] |
getSchedule(double[][] procData, int[][] seq) 基于各个作业的工艺参数、各设备上作业的排序获得作业车间JSP的详细调度方案:手工计算实验中使用 |
double[][] |
getSchRelease(double[][] procData, double[] dtimes, int[][]
seq, double[] releaseTimes) 基于各个作业的工艺参数、各设备上作业的排序和各作业的释放时间、交付时间获得作业车间JSP的详细调度方案 |
double[][] |
getSchRelease(double[][] procData, double[] dueTimes,
int[] seq, double[] releaseTimes) 基于作业时间、作业排序获得零等待阻塞流水车间的详细调度方案 |
double[][] |
getSchRelease(double[][] procData, int[][] seq, double[]
releaseTimes) 基于各个作业的工艺参数、各设备上作业的排序和各作业的释放时间获得作业车间JSP的详细调度方案:手工实验的计算程序 |
double[][] |
getSchRelease(double[][] procData, int[] seq, double[]
releaseTimes) 基于各个作业的工艺参数、释放时间和连续的作业排序数组获得基本作业车间Jm的详细调度方案:主要用于优化算法中解编码的详细调度方案生成 |
SchOptResult |
optCmaxByACO(double[][] procData, double[] params) 利用蚁群算法进行基本作业车间Jm||Cmax问题的优化求解 |
SchOptResult |
optCmaxByGA(double[][] procData, double[] params) 利用遗传算法进行基本作业车间Jm||Cmax问题的优化求解 |
SchOptResult |
optCmaxByPSO(double[][] procData, double[] params) 利用粒子群算法进行基本作业车间Jm||Cmax问题的优化求解 |
SchOptResult |
optCmaxBySA(double[][] procData, double[] params) 利用模拟退火算法进行基本作业车间Jm||Cmax问题的优化求解 |
SchOptResult |
optCmaxByTLBO(double[][] procData, double[] params) 利用教学算法进行基本作业车间Jm||Cmax问题的优化求解 |
SchOptResult |
optCtotalByACO(double[][] procData, double[] params)
利用蚁群算法进行基本作业车间Jm||Ctotal问题的优化求解 |
SchOptResult |
optCtotalByGA(double[][] procData, double[] params) 利用遗传算法进行基本作业车间Jm||Ctotal问题的优化求解 |
SchOptResult |
optCtotalByPSO(double[][] procData, double[] params)
利用粒子群算法进行基本作业车间Jm||Ctotal问题的优化求解 |
SchOptResult |
optCtotalBySA(double[][] procData, double[] params) 利用模拟退火算法进行基本作业车间Jm||Ctotal问题的优化求解 |
SchOptResult |
optCtotalByTLBO(double[][] procData, double[] params)
利用教学算法进行基本作业车间Jm||Ctotal问题的优化求解 |
SchOptResult |
optLmaxByACO(double[][] procData, double[] params, double[]
dueTimes) 利用蚁群算法进行基本作业车间Jm||Lmax问题的优化求解 |
SchOptResult |
optLmaxByGA(double[][] procData, double[] params, double[]
dueTimes) 利用遗传算法进行基本作业车间Jm||Lmax问题的优化求解 |
SchOptResult |
optLmaxByPSO(double[][] procData, double[] params, double[]
dueTimes) 利用粒子群算法进行基本作业车间Jm||Lmax问题的优化求解 |
SchOptResult |
optLmaxBySA(double[][] procData, double[] params, double[]
dueTimes) 利用模拟退火算法进行基本作业车间Jm||Lmax问题的优化求解 |
SchOptResult |
optLmaxByTLBO(double[][] procData, double[] params, double[]
dueTimes) 利用教学算法进行基本作业车间Jm||Lmax问题的优化求解 |
SchOptResult |
optLtotalByACO(double[][] procData, double[] params,
double[] dueTimes) 利用蚁群算法进行基本作业车间Jm||Ltotal问题的优化求解 |
SchOptResult |
optLtotalByGA(double[][] procData, double[] params, double[]
dueTimes) 利用遗传算法进行基本作业车间Jm||Ltotal问题的优化求解 |
SchOptResult |
optLtotalByPSO(double[][] procData, double[] params,
double[] dueTimes) 利用粒子群算法进行基本作业车间Jm||Ltotal问题的优化求解 |
SchOptResult |
optLtotalBySA(double[][] procData, double[] params, double[]
dueTimes) 利用模拟退火算法进行基本作业车间Jm||Ltotal问题的优化求解 |
SchOptResult |
optLtotalByTLBO(double[][] procData, double[] params,
double[] dueTimes) 利用教学算法进行基本作业车间Jm||Ltotal问题的优化求解 |
SchOptResult |
optRjCmaxByACO(double[][] procData, double[] params,
double[] releaseTimes) 利用蚁群算法进行基本作业车间Jm|rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByGA(double[][] procData, double[] params, double[]
releaseTimes) 利用遗传算法进行基本作业车间Jm|rj|Cmax的优化求解 |
SchOptResult |
optRjCmaxByPSO(double[][] procData, double[] params,
double[] releaseTimes) 利用粒子群算法进行基本作业车间Jm|rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxBySA(double[][] procData, double[] params, double[]
releaseTimes) 利用模拟退火算法进行基本作业车间Jm|rj|Cmax问题的优化求解 |
SchOptResult |
optRjCmaxByTLBO(double[][] procData, double[] params,
double[] releaseTimes) 利用教学算法进行基本作业车间Jm|rj|Cmax问题的优化求解 |
SchOptResult |
optRjLmaxByACO(double[][] procData, double[] params,
double[] releaseTimes, double[] dueTimes) 利用蚁群算法进行基本作业车间Jm|rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByGA(double[][] procData, double[] params, double[]
releaseTimes, double[] dueTimes) 利用遗传算法进行基本作业车间Jm|rj|Lmax的优化求解 |
SchOptResult |
optRjLmaxByPSO(double[][] procData, double[] params,
double[] releaseTimes, double[] dueTimes) 利用粒子群算法进行基本作业车间Jm|rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxBySA(double[][] procData, double[] params, double[]
releaseTimes, double[] dueTimes) 利用模拟退火算法进行基本作业车间Jm|rj|Lmax问题的优化求解 |
SchOptResult |
optRjLmaxByTLBO(double[][] procData, double[] params,
double[] releaseTimes, double[] dueTimes) 利用教学算法进行基本作业车间Jm|rj|Lmax问题的优化求解 |
例1:考虑有六台设备的作业车间需要完成10项作业,这10项作业的工艺参数如下表所示。
JobId |
Proc1 |
Proc2 |
Proc3 |
Proc4 |
Proc5 |
Proc6 |
||||||
MachId |
pTime |
MachId |
pTime |
MachId |
pTime |
MachId |
pTime |
MachId |
pTime |
MachId |
pTime |
|
1 |
2 |
13 |
5 |
19 |
3 |
33 |
1 |
23 |
4 |
38 |
6 |
33 |
2 |
4 |
37 |
1 |
21 |
2 |
25 |
5 |
11 |
6 |
36 |
3 |
14 |
3 |
2 |
23 |
5 |
42 |
1 |
7 |
3 |
21 |
6 |
27 |
4 |
19 |
4 |
6 |
34 |
5 |
26 |
1 |
18 |
4 |
19 |
2 |
39 |
3 |
28 |
5 |
3 |
34 |
5 |
12 |
4 |
31 |
1 |
38 |
2 |
22 |
6 |
11 |
6 |
3 |
16 |
4 |
26 |
5 |
13 |
1 |
40 |
6 |
25 |
2 |
18 |
7 |
5 |
27 |
3 |
15 |
2 |
11 |
1 |
12 |
4 |
29 |
6 |
38 |
8 |
4 |
9 |
6 |
30 |
2 |
16 |
3 |
13 |
5 |
8 |
1 |
21 |
9 |
2 |
39 |
3 |
13 |
5 |
7 |
4 |
23 |
6 |
15 |
1 |
36 |
10 |
2 |
27 |
6 |
22 |
1 |
32 |
5 |
24 |
4 |
10 |
3 |
5 |
试利用JSP类中的方法实现如下排序的详细调度方案:
MachId |
jobId1 |
jobId2 |
jobId3 |
jobId4 |
jobId5 |
jobId6 |
jobId7 |
jobId8 |
jobId9 |
jobId10 |
1 |
2 |
4 |
3 |
10 |
5 |
6 |
1 |
7 |
9 |
8 |
2 |
3 |
10 |
9 |
1 |
7 |
8 |
2 |
5 |
4 |
6 |
3 |
5 |
6 |
7 |
9 |
1 |
8 |
3 |
2 |
4 |
10 |
4 |
8 |
2 |
6 |
5 |
4 |
9 |
10 |
7 |
1 |
3 |
5 |
7 |
4 |
5 |
1 |
3 |
6 |
9 |
2 |
10 |
8 |
6 |
4 |
10 |
8 |
9 |
2 |
3 |
6 |
1 |
7 |
5 |
程序设计如下:
import easyopt.common.EasyArray; import easyopt.shopSch.Schedule; import easyopt.shopSch.jsp.JSP; public class Example_JSP { public void main(String[] args) { double[][] procData =
{{2,13,5,19,3,33,1,23,4,38,6,33},{4,37,1,21,2,25,5,11,6,36,3,14},{2,23,5,42,1,7,3,21,6,27,4,19},{6,34,5,26,1,18,4,19,2,39,3,28},{3,34,5,12,4,31,1,38,2,22,6,11},{3,16,4,26,5,13,1,40,6,25,2,18},{5,27,3,15,2,11,1,12,4,29,6,38},{4,9,6,30,2,16,3,13,5,8,1,21},{2,39,3,13,5,7,4,23,6,15,1,36},{2,27,6,22,1,32,5,24,4,10,3,5}}; int[][] seq =
{{2,4,3,10,5,6,1,7,9,8},{3,10,9,1,7,8,2,5,4,6},{5,6,7,9,1,8,3,2,4,10},{8,2,6,5,4,9,10,7,1,3},{7,4,5,1,3,6,9,2,10,8},{4,10,8,9,2,3,6,1,7,5}}; JSP jsp =new JSP(); double[][] sch1 = jsp.getSchedule(procData, seq); System.out.println("--排序结果--"); EasyArray.printArray(sch1); } } |
执行后的排产结果如下:
--排序结果-- 3.0 2.0 1.0 0.0 23.0 ; 5.0 3.0 1.0 0.0 34.0 ; 8.0 4.0 1.0 0.0 9.0 ; 7.0 5.0 1.0 0.0 27.0 ; 4.0 6.0 1.0 0.0 34.0 ; 10.0 2.0 1.0 23.0 50.0 ; 6.0 3.0 1.0 34.0 50.0 ; 2.0 4.0 1.0 9.0 46.0 ; 4.0 5.0 2.0 34.0 60.0 ; 10.0 6.0 2.0 50.0 72.0 ; 2.0 1.0 2.0 46.0 67.0 ; 9.0 2.0 1.0 50.0 89.0 ; 7.0 3.0 2.0 50.0 65.0 ; 6.0 4.0 2.0 50.0 76.0 ; 5.0 5.0 2.0 60.0 72.0 ; 8.0 6.0 2.0 72.0 102.0 ; 4.0 1.0 3.0 67.0 85.0 ; 1.0 2.0 1.0 89.0 102.0 ; 9.0 3.0 2.0 89.0 102.0 ; 5.0 4.0 3.0 76.0 107.0 ; 1.0 5.0 2.0 102.0 121.0 ; 7.0 2.0 3.0 102.0 113.0 ; 1.0 3.0 3.0 121.0 154.0 ; 4.0 4.0 4.0 107.0 126.0 ; 3.0 5.0 2.0 121.0 163.0 ; 3.0 1.0 3.0 163.0 170.0 ; 8.0 2.0 3.0 113.0 129.0 ; 8.0 3.0 4.0 154.0 167.0 ; 6.0 5.0 3.0 163.0 176.0 ; 10.0 1.0 3.0 170.0 202.0 ; 2.0 2.0 3.0 129.0 154.0 ; 3.0 3.0 4.0 170.0 191.0 ; 9.0 5.0 3.0 176.0 183.0 ; 5.0 1.0 4.0 202.0 240.0 ; 5.0 2.0 5.0 240.0 262.0 ; 9.0 4.0 4.0 183.0 206.0 ; 2.0 5.0 4.0 183.0 194.0 ; 9.0 6.0 5.0 206.0 221.0 ; 6.0 1.0 4.0 240.0 280.0 ; 4.0 2.0 5.0 262.0 301.0 ; 10.0 5.0 4.0 202.0 226.0 ; 2.0 6.0 5.0 221.0 257.0 ; 1.0 1.0 4.0 280.0 303.0 ; 2.0 3.0 6.0 257.0 271.0 ; 10.0 4.0 5.0 226.0 236.0 ; 8.0 5.0 5.0 226.0 234.0 ; 3.0 6.0 5.0 257.0 284.0 ; 7.0 1.0 4.0 303.0 315.0 ; 4.0 3.0 6.0 301.0 329.0 ; 7.0 4.0 5.0 315.0 344.0 ; 6.0 6.0 5.0 284.0 309.0 ; 9.0 1.0 6.0 315.0 351.0 ; 6.0 2.0 6.0 309.0 327.0 ; 10.0 3.0 6.0 329.0 334.0 ; 1.0 4.0 5.0 344.0 382.0 ; 1.0 6.0 6.0 382.0 415.0 ; 8.0 1.0 6.0 351.0 372.0 ; 3.0 4.0 6.0 382.0 401.0 ; 7.0 6.0 6.0 415.0 453.0 ; 5.0 6.0 6.0 453.0 464.0 ; |
该详细调度的甘特图如下:
例2:以例1的工艺数据为基础,采用JSP类中的方法对其进行优化求解,以获得最小完工时间的调度方案。
程序设计如下:
import easyopt.common.EasyArray; import easyopt.shopSch.SchOptResult; import easyopt.shopSch.Schedule; import easyopt.shopSch.jsp.JSP; public class Example_JSPopt
{ public void main(String[] args) { double[][] procData =
{{2,13,5,19,3,33,1,23,4,38,6,33},{4,37,1,21,2,25,5,11,6,36,3,14},{2,23,5,42,1,7,3,21,6,27,4,19},{6,34,5,26,1,18,4,19,2,39,3,28},{3,34,5,12,4,31,1,38,2,22,6,11},{3,16,4,26,5,13,1,40,6,25,2,18},{5,27,3,15,2,11,1,12,4,29,6,38},{4,9,6,30,2,16,3,13,5,8,1,21},{2,39,3,13,5,7,4,23,6,15,1,36},{2,27,6,22,1,32,5,24,4,10,3,5}}; double[] saParas =
{0.992,40,400,70}; double[] gaParas =
{400,40,0.7,0.6,70}; double[] acoParas =
{0.2,40,400,70}; double[] psoParas =
{0.9,2,2,40,400,70}; double[] tlboParas = {40,400,70}; JSP jsp =new
JSP(); SchOptResult
saResult = jsp.optCmaxBySA(procData, saParas); SchOptResult
gaResult = jsp.optCmaxByGA(procData, gaParas); SchOptResult
acoResult = jsp.optCmaxByACO(procData, acoParas); SchOptResult
psoResult = jsp.optCmaxByPSO(procData, psoParas) ; SchOptResult
tlboResult = jsp.optCmaxByTLBO(procData, tlboParas) ; System.out.println("----模拟退火算法获得的最优排序调度方案如下-----"); EasyArray.printArray(saResult.schedule); System.out.println("----模拟退火算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(saResult.schedule)); System.out.println("----遗传算法获得的最优排序调度方案如下-----"); EasyArray.printArray(gaResult.schedule); System.out.println("----遗传算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(gaResult.schedule)); System.out.println("----粒子群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(psoResult.schedule); System.out.println("----粒子群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(psoResult.schedule)); System.out.println("----蚁群算法获得的最优排序调度方案如下-----"); EasyArray.printArray(acoResult.schedule); System.out.println("----蚁群算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(acoResult.schedule)); System.out.println("----教学算法获得的最优排序调度方案如下-----"); EasyArray.printArray(tlboResult.schedule); System.out.println("----教学算法获得的最大完工时间为-----"); System.out.println(Schedule.getMaxFinishTime(tlboResult.schedule)); } } |
执行结果如下所示:
----模拟退火算法获得的最优排序调度方案如下----- 7.0 5.0 1.0 0.0 27.0 ; 4.0 5.0 2.0 34.0 60.0 ; 6.0 5.0 3.0 60.0 73.0 ; 9.0 5.0 3.0 75.0 82.0 ; 3.0 5.0 2.0 82.0 124.0 ; 1.0 5.0 2.0 124.0 143.0 ; 10.0 5.0 4.0 144.0 168.0 ; 2.0 5.0 4.0 168.0 179.0 ; 5.0 5.0 2.0 179.0 191.0 ; 8.0 5.0 5.0 191.0 199.0 ; 6.0 3.0 1.0 0.0 16.0 ; 7.0 3.0 2.0 27.0 42.0 ; 9.0 3.0 2.0 62.0 75.0 ; 5.0 3.0 1.0 75.0 109.0 ; 8.0 3.0 4.0 129.0 142.0 ; 1.0 3.0 3.0 143.0 176.0 ; 3.0 3.0 4.0 214.0 235.0 ; 2.0 3.0 6.0 235.0 249.0 ; 4.0 3.0 6.0 249.0 277.0 ; 10.0 3.0 6.0 178.0 183.0 ; 8.0 4.0 1.0 0.0 9.0 ; 6.0 4.0 2.0 16.0 42.0 ; 2.0 4.0 1.0 42.0 79.0 ; 9.0 4.0 4.0 82.0 105.0 ; 7.0 4.0 5.0 112.0 141.0 ; 4.0 4.0 4.0 141.0 160.0 ; 10.0 4.0 5.0 168.0 178.0 ; 5.0 4.0 3.0 191.0 222.0 ; 1.0 4.0 5.0 222.0 260.0 ; 3.0 4.0 6.0 267.0 286.0 ; 3.0 2.0 1.0 0.0 23.0 ; 9.0 2.0 1.0 23.0 62.0 ; 10.0 2.0 1.0 62.0 89.0 ; 7.0 2.0 3.0 89.0 100.0 ; 1.0 2.0 1.0 100.0 113.0 ; 8.0 2.0 3.0 113.0 129.0 ; 2.0 2.0 3.0 129.0 154.0 ; 4.0 2.0 5.0 160.0 199.0 ; 6.0 2.0 6.0 240.0 258.0 ; 5.0 2.0 5.0 260.0 282.0 ; 4.0 6.0 1.0 0.0 34.0 ; 8.0 6.0 2.0 34.0 64.0 ; 10.0 6.0 2.0 89.0 111.0 ; 9.0 6.0 5.0 111.0 126.0 ; 7.0 6.0 6.0 141.0 179.0 ; 2.0 6.0 5.0 179.0 215.0 ; 6.0 6.0 5.0 215.0 240.0 ; 3.0 6.0 5.0 240.0 267.0 ; 1.0 6.0 6.0 267.0 300.0 ; 5.0 6.0 6.0 300.0 311.0 ; 4.0 1.0 3.0 60.0 78.0 ; 2.0 1.0 2.0 79.0 100.0 ; 7.0 1.0 4.0 100.0 112.0 ; 10.0 1.0 3.0 112.0 144.0 ; 6.0 1.0 4.0 144.0 184.0 ; 1.0 1.0 4.0 184.0 207.0 ; 3.0 1.0 3.0 207.0 214.0 ; 5.0 1.0 4.0 222.0 260.0 ; 9.0 1.0 6.0 260.0 296.0 ; 8.0 1.0 6.0 296.0 317.0 ; ----模拟退火算法获得的最大完工时间为----- 317.0 ----遗传算法获得的最优排序调度方案如下----- 7.0 5.0 1.0 0.0 27.0 ; 1.0 5.0 2.0 40.0 59.0 ; 6.0 5.0 3.0 63.0 76.0 ; 4.0 5.0 2.0 76.0 102.0 ; 9.0 5.0 3.0 105.0 112.0 ; 3.0 5.0 2.0 115.0 157.0 ; 5.0 5.0 2.0 157.0 169.0 ; 2.0 5.0 4.0 169.0 180.0 ; 10.0 5.0 4.0 200.0 224.0 ; 8.0 5.0 5.0 224.0 232.0 ; 2.0 4.0 1.0 0.0 37.0 ; 6.0 4.0 2.0 37.0 63.0 ; 8.0 4.0 1.0 63.0 72.0 ; 7.0 4.0 5.0 72.0 101.0 ; 9.0 4.0 4.0 112.0 135.0 ; 4.0 4.0 4.0 135.0 154.0 ; 5.0 4.0 3.0 169.0 200.0 ; 1.0 4.0 5.0 200.0 238.0 ; 3.0 4.0 6.0 238.0 257.0 ; 10.0 4.0 5.0 257.0 267.0 ; 10.0 2.0 1.0 0.0 27.0 ; 1.0 2.0 1.0 27.0 40.0 ; 7.0 2.0 3.0 42.0 53.0 ; 9.0 2.0 1.0 53.0 92.0 ; 3.0 2.0 1.0 92.0 115.0 ; 2.0 2.0 3.0 115.0 140.0 ; 8.0 2.0 3.0 140.0 156.0 ; 6.0 2.0 6.0 165.0 183.0 ; 4.0 2.0 5.0 183.0 222.0 ; 5.0 2.0 5.0 238.0 260.0 ; 2.0 1.0 2.0 37.0 58.0 ; 7.0 1.0 4.0 58.0 70.0 ; 6.0 1.0 4.0 76.0 116.0 ; 4.0 1.0 3.0 116.0 134.0 ; 1.0 1.0 4.0 138.0 161.0 ; 3.0 1.0 3.0 161.0 168.0 ; 10.0 1.0 3.0 168.0 200.0 ; 5.0 1.0 4.0 200.0 238.0 ; 9.0 1.0 6.0 238.0 274.0 ; 8.0 1.0 6.0 274.0 295.0 ; 4.0 6.0 1.0 0.0 34.0 ; 10.0 6.0 2.0 34.0 56.0 ; 8.0 6.0 2.0 72.0 102.0 ; 7.0 6.0 6.0 102.0 140.0 ; 6.0 6.0 5.0 140.0 165.0 ; 9.0 6.0 5.0 165.0 180.0 ; 3.0 6.0 5.0 189.0 216.0 ; 2.0 6.0 5.0 216.0 252.0 ; 1.0 6.0 6.0 252.0 285.0 ; 5.0 6.0 6.0 285.0 296.0 ; 6.0 3.0 1.0 0.0 16.0 ; 7.0 3.0 2.0 27.0 42.0 ; 5.0 3.0 1.0 42.0 76.0 ; 9.0 3.0 2.0 92.0 105.0 ; 1.0 3.0 3.0 105.0 138.0 ; 3.0 3.0 4.0 168.0 189.0 ; 8.0 3.0 4.0 189.0 202.0 ; 4.0 3.0 6.0 222.0 250.0 ; 2.0 3.0 6.0 252.0 266.0 ; 10.0 3.0 6.0 267.0 272.0 ; ----遗传算法获得的最大完工时间为----- 296.0 ----粒子群算法获得的最优排序调度方案如下----- 7.0 5.0 1.0 0.0 27.0 ; 4.0 5.0 2.0 34.0 60.0 ; 1.0 5.0 2.0 60.0 79.0 ; 5.0 5.0 2.0 79.0 91.0 ; 9.0 5.0 3.0 92.0 99.0 ; 2.0 5.0 4.0 104.0 115.0 ; 6.0 5.0 3.0 115.0 128.0 ; 3.0 5.0 2.0 138.0 180.0 ; 10.0 5.0 4.0 180.0 204.0 ; 8.0 5.0 5.0 218.0 226.0 ; 10.0 2.0 1.0 0.0 27.0 ; 1.0 2.0 1.0 27.0 40.0 ; 9.0 2.0 1.0 40.0 79.0 ; 2.0 2.0 3.0 79.0 104.0 ; 7.0 2.0 3.0 104.0 115.0 ; 3.0 2.0 1.0 115.0 138.0 ; 4.0 2.0 5.0 138.0 177.0 ; 8.0 2.0 3.0 177.0 193.0 ; 5.0 2.0 5.0 248.0 270.0 ; 6.0 2.0 6.0 193.0 211.0 ; 2.0 1.0 2.0 37.0 58.0 ; 4.0 1.0 3.0 60.0 78.0 ; 10.0 1.0 3.0 78.0 110.0 ; 7.0 1.0 4.0 115.0 127.0 ; 6.0 1.0 4.0 128.0 168.0 ; 3.0 1.0 3.0 180.0 187.0 ; 1.0 1.0 4.0 187.0 210.0 ; 5.0 1.0 4.0 210.0 248.0 ; 9.0 1.0 6.0 248.0 284.0 ; 8.0 1.0 6.0 284.0 305.0 ; 4.0 6.0 1.0 0.0 34.0 ; 10.0 6.0 2.0 34.0 56.0 ; 8.0 6.0 2.0 56.0 86.0 ; 2.0 6.0 5.0 115.0 151.0 ; 9.0 6.0 5.0 151.0 166.0 ; 6.0 6.0 5.0 168.0 193.0 ; 7.0 6.0 6.0 193.0 231.0 ; 3.0 6.0 5.0 239.0 266.0 ; 5.0 6.0 6.0 270.0 281.0 ; 1.0 6.0 6.0 281.0 314.0 ; 6.0 3.0 1.0 0.0 16.0 ; 5.0 3.0 1.0 16.0 50.0 ; 7.0 3.0 2.0 50.0 65.0 ; 9.0 3.0 2.0 79.0 92.0 ; 1.0 3.0 3.0 92.0 125.0 ; 2.0 3.0 6.0 151.0 165.0 ; 4.0 3.0 6.0 177.0 205.0 ; 8.0 3.0 4.0 205.0 218.0 ; 3.0 3.0 4.0 218.0 239.0 ; 10.0 3.0 6.0 239.0 244.0 ; 2.0 4.0 1.0 0.0 37.0 ; 8.0 4.0 1.0 37.0 46.0 ; 6.0 4.0 2.0 46.0 72.0 ; 4.0 4.0 4.0 78.0 97.0 ; 9.0 4.0 4.0 99.0 122.0 ; 7.0 4.0 5.0 127.0 156.0 ; 5.0 4.0 3.0 156.0 187.0 ; 10.0 4.0 5.0 204.0 214.0 ; 1.0 4.0 5.0 214.0 252.0 ; 3.0 4.0 6.0 266.0 285.0 ; ----粒子群算法获得的最大完工时间为----- 314.0 ----蚁群算法获得的最优排序调度方案如下----- 1.0 2.0 1.0 0.0 13.0 ; 10.0 2.0 1.0 13.0 40.0 ; 9.0 2.0 1.0 40.0 79.0 ; 2.0 2.0 3.0 79.0 104.0 ; 3.0 2.0 1.0 104.0 127.0 ; 7.0 2.0 3.0 127.0 138.0 ; 8.0 2.0 3.0 138.0 154.0 ; 5.0 2.0 5.0 159.0 181.0 ; 4.0 2.0 5.0 225.0 264.0 ; 6.0 2.0 6.0 271.0 289.0 ; 2.0 4.0 1.0 0.0 37.0 ; 8.0 4.0 1.0 37.0 46.0 ; 5.0 4.0 3.0 46.0 77.0 ; 6.0 4.0 2.0 77.0 103.0 ; 1.0 4.0 5.0 121.0 159.0 ; 9.0 4.0 4.0 159.0 182.0 ; 4.0 4.0 4.0 206.0 225.0 ; 7.0 4.0 5.0 225.0 254.0 ; 3.0 4.0 6.0 254.0 273.0 ; 10.0 4.0 5.0 273.0 283.0 ; 7.0 5.0 1.0 0.0 27.0 ; 5.0 5.0 2.0 34.0 46.0 ; 1.0 5.0 2.0 46.0 65.0 ; 4.0 5.0 2.0 65.0 91.0 ; 2.0 5.0 4.0 104.0 115.0 ; 9.0 5.0 3.0 115.0 122.0 ; 3.0 5.0 2.0 127.0 169.0 ; 6.0 5.0 3.0 169.0 182.0 ; 10.0 5.0 4.0 182.0 206.0 ; 8.0 5.0 5.0 206.0 214.0 ; 2.0 1.0 2.0 37.0 58.0 ; 10.0 1.0 3.0 62.0 94.0 ; 1.0 1.0 4.0 98.0 121.0 ; 5.0 1.0 4.0 121.0 159.0 ; 3.0 1.0 3.0 169.0 176.0 ; 7.0 1.0 4.0 176.0 188.0 ; 4.0 1.0 3.0 188.0 206.0 ; 6.0 1.0 4.0 206.0 246.0 ; 9.0 1.0 6.0 246.0 282.0 ; 8.0 1.0 6.0 282.0 303.0 ; 4.0 6.0 1.0 0.0 34.0 ; 10.0 6.0 2.0 40.0 62.0 ; 8.0 6.0 2.0 62.0 92.0 ; 2.0 6.0 5.0 115.0 151.0 ; 1.0 6.0 6.0 159.0 192.0 ; 5.0 6.0 6.0 192.0 203.0 ; 3.0 6.0 5.0 203.0 230.0 ; 9.0 6.0 5.0 230.0 245.0 ; 6.0 6.0 5.0 246.0 271.0 ; 7.0 6.0 6.0 271.0 309.0 ; 5.0 3.0 1.0 0.0 34.0 ; 7.0 3.0 2.0 34.0 49.0 ; 6.0 3.0 1.0 49.0 65.0 ; 1.0 3.0 3.0 65.0 98.0 ; 9.0 3.0 2.0 98.0 111.0 ; 8.0 3.0 4.0 154.0 167.0 ; 3.0 3.0 4.0 176.0 197.0 ; 4.0 3.0 6.0 264.0 292.0 ; 10.0 3.0 6.0 292.0 297.0 ; 2.0 3.0 6.0 197.0 211.0 ; ----蚁群算法获得的最大完工时间为----- 309.0 ----教学算法获得的最优排序调度方案如下----- 10.0 2.0 1.0 0.0 27.0 ; 1.0 2.0 1.0 27.0 40.0 ; 7.0 2.0 3.0 42.0 53.0 ; 9.0 2.0 1.0 53.0 92.0 ; 2.0 2.0 3.0 92.0 117.0 ; 3.0 2.0 1.0 117.0 140.0 ; 6.0 2.0 6.0 166.0 184.0 ; 5.0 2.0 5.0 184.0 206.0 ; 4.0 2.0 5.0 206.0 245.0 ; 8.0 2.0 3.0 140.0 156.0 ; 7.0 5.0 1.0 0.0 27.0 ; 4.0 5.0 2.0 34.0 60.0 ; 5.0 5.0 2.0 76.0 88.0 ; 6.0 5.0 3.0 88.0 101.0 ; 9.0 5.0 3.0 105.0 112.0 ; 1.0 5.0 2.0 112.0 131.0 ; 2.0 5.0 4.0 131.0 142.0 ; 3.0 5.0 2.0 142.0 184.0 ; 10.0 5.0 4.0 241.0 265.0 ; 8.0 5.0 5.0 184.0 192.0 ; 2.0 4.0 1.0 0.0 37.0 ; 8.0 4.0 1.0 37.0 46.0 ; 6.0 4.0 2.0 46.0 72.0 ; 7.0 4.0 5.0 72.0 101.0 ; 5.0 4.0 3.0 101.0 132.0 ; 9.0 4.0 4.0 132.0 155.0 ; 4.0 4.0 4.0 155.0 174.0 ; 1.0 4.0 5.0 202.0 240.0 ; 3.0 4.0 6.0 257.0 276.0 ; 10.0 4.0 5.0 276.0 286.0 ; 2.0 1.0 2.0 37.0 58.0 ; 7.0 1.0 4.0 58.0 70.0 ; 4.0 1.0 3.0 70.0 88.0 ; 6.0 1.0 4.0 101.0 141.0 ; 5.0 1.0 4.0 141.0 179.0 ; 1.0 1.0 4.0 179.0 202.0 ; 3.0 1.0 3.0 202.0 209.0 ; 10.0 1.0 3.0 209.0 241.0 ; 9.0 1.0 6.0 241.0 277.0 ; 8.0 1.0 6.0 277.0 298.0 ; 4.0 6.0 1.0 0.0 34.0 ; 10.0 6.0 2.0 34.0 56.0 ; 8.0 6.0 2.0 56.0 86.0 ; 7.0 6.0 6.0 101.0 139.0 ; 6.0 6.0 5.0 141.0 166.0 ; 2.0 6.0 5.0 166.0 202.0 ; 9.0 6.0 5.0 202.0 217.0 ; 5.0 6.0 6.0 217.0 228.0 ; 3.0 6.0 5.0 230.0 257.0 ; 1.0 6.0 6.0 257.0 290.0 ; 6.0 3.0 1.0 0.0 16.0 ; 7.0 3.0 2.0 27.0 42.0 ; 5.0 3.0 1.0 42.0 76.0 ; 9.0 3.0 2.0 92.0 105.0 ; 1.0 3.0 3.0 131.0 164.0 ; 8.0 3.0 4.0 164.0 177.0 ; 3.0 3.0 4.0 209.0 230.0 ; 2.0 3.0 6.0 230.0 244.0 ; 4.0 3.0 6.0 245.0 273.0 ; 10.0 3.0 6.0 286.0 291.0 ; ----教学算法获得的最大完工时间为----- 303.0 |
五种优化算法获得的完工时间分别为:317、296、314、309、298,以教学算法298的结果绘制甘特图如下。
前述示例对使用JSP类中的方法进行Cmax目标优化求解过程进行描述,该类中进行Lmax目标优化的方法求解过程如此类似,只是使用过程中要选择不同的方法和设置的参数有所不同而已,不再赘述。