复杂作业车间调度-单机调度问题研究

在这里插入图片描述

获取更多资讯,赶快关注上面的公众号吧!

第一章 单机调度问题研究

1.1 单机案例描述

  单机总加权拖期问题可以描述为:一共有n个作业,每个作业(1,…,n)需要在同一台机床上加工,加工过程不能中断,且机床在同一时间只能加工一项作业。作业j(j=1,…,n)在0时刻准备就绪,加工时间为p(j),权重为w(j),交货期为d(j)。给定这些作业的加工顺序,可以很容易地得到作业j(j=1,…,n)的最早完成时间C(j)和拖期T(j)=max{C(j)-d(j),0}。问题的目标是确定一个加工顺序使得所有作业的总加权拖期SUM{j=1,…,n}w(j)T{j}最小。

  OR-Library中提供了三种问题规模(n=40,50,100)的数据文件,每种规模都有125(对于RDD和TF每个取值各生成5个案例,5x5x5=125)个测试案例。这些案例可以在链接:https://pan.baidu.com/s/1SXl8TZCKs1D2uNca80RjmA 提取码:ux3k 下载。

  案例按照如下方式随机生成:

属性 数据类型 分布 分布参数
加工时间p(j) 整型 均匀分布 [1,100]
权重w(j) 整型 均匀分布 [1,10]
交货期范围RDD 浮点型 离散取值 [0.2,0.4,0.6,0.8,1.0]
平均拖期因子TF 浮点型 离散取值 [0.2,0.4,0.6,0.8,1.0]
交货期d(j) 整型 均匀分布 [P(1-TF-RDD/2),P(1-TF+RDD/2)],P=SUM{j=1,…,n}p(j)

  文件wt40,wt50和wt100分别包含了规模为40,50和100的案例,每个文件包含了125个实例的数据,这些数据是针对每个案例依次给出的,首先是n个加工时间,接着是n个权重,最后是n个交货期。例如,在wt40中前40个整数是第一个案例的40个作业的加工时间,接下来的40个整数为第一个案例的权重,再接下来的40个整数为第一个案例的交货期,再后面的40个整数为第二个案例的加工时间,以此类推。

  规模大小为40和50的案例中,分别有124和115个案例时已知最优值的,规模40中未被解决的问题是19,50中未被解决的是11,12,14,19,36,44,66,87,88和111。

  wtopt40和wtopt50文件中给出了目前已知的最优值。Crauwels, Potts & Van Wassenhove (1996)。这些值一直到现在也没有得到改进,所以很可能就是最优的。

  在文件wtbest100a中给出了规模为100问题的最优值(Crauwels, Potts & Van Wassenhove (1998)),这些值在Crauwels, Potts和Van Wassenhove (1998) and Congram, Potts & van de Velde (1998)中也被当做是已知最优值。因此使用这些已知的最优解值Crauwels, Potts & Van Wassenhove(1998)允许未来启发式算法的结果直接与这些论文中的表格数据进行比较。

  针对规模为100的问题,局部搜索启发式动态搜索(Congram, Potts & van de Velde 1998)已经在某些情况下找到了比Crauwels, Potts & van Wassenhove(1998)更好的解决方案。wtbest100b文件给出了到目前为止已知的最优值。

1.2 启发式规则设计

  一共设置了34种启发式规则,详细见下表。

表1 启发式规则列表
规则序号 规则名称 描述
1 FOPNR 剩余工序数越少越优先
2 MOPNR 剩余工序数越多越优先
3 SPT 工时越短越优先
4 LPT 工时越长越优先
5 SRPT 剩余工时越少越优先
6 LRPT 剩余工时越多越优先
7 MINSEQ 准备时间越少越优先
8 EDD 工件交货期越早越优先
9 SPT/TWK 选择工序加工时间与总加工时间比值最小的工件
10 LPT/TWK 选择工序加工时间与总加工时间比值最大的工件
11 SPT/TWKR 选择工序加工时间与剩余加工时间比值最小的工件
12 LPT/TWKR 选择工序加工时间与剩余加工时间比值最大的工件
13 SPTxTWK 选择工序加工时间与总加工时间乘积最小的工件
14 LPTxTWK 选择工序加工时间与总加工时间乘积最大的工件
15 SPTxTWKR 选择工序加工时间与剩余加工时间乘积最小的工件
16 LPTxTWKR 选择工序加工时间与剩余加工时间乘积最大的工件
17 SRM 选择除当前考虑工序外剩余加工时间最短的工件
18 LRM 选择除当前考虑工序外剩余加工时间最长的工件
19 SSO 选择后继工序加工时间最短的工件
20 LSO 选择后继工序加工时间最长的工件
21 SPT+SSO 选择当前工序加工时间与后继工序加工时间最短的工件
22 LPT+LSO 选择当前工序加工时间与后继工序加工时间最长的工件
23 S-1 工件剩余交货时间越少越优先(ALL)
24 S-2 工件松弛率越小越优先(CR)
25 S-3 工件待加工部分松弛率越小越优先(SL)
26 S-4 工序松弛时间越小越优先(OSL)
27 S-5 工序松弛率越小越优先(OCR)
28 S-6 每一剩余工序可用时间越小越优先(ALL/OPN)
29 S-7 每一剩余工序松弛时间越小越优先(SL/OPN)
30 S-8 每单位剩余工作量松弛时间越小越优先(SL/WKR)
31 GW 工件权重越大越优先
32 LW 工件权重越小越优先
33 WSPT 加权最短加工时间(权重/工时越大)优先
34 WLPT 加权最长加工时间(权重/工时越小)优先

1.3 调度案例求解过程

1.3.1 案例格式化

  对于不同调度类型(单机、并行机、流水、作业车间、柔性作业车间),以及不同机构和论文中给出的benchmark往往具有不同的数据定义格式,为了能够灵活地处理这些数据,在调度平台中加入了一个Instance类,所有的benchmark数据最终转换成Instance类型并保存成JSON格式至本地,所以用户在使用时就不用再关心和调度无直接关系的事情了。同时用户也还可以自行运行程序,根据给定的参数(工件数、机床数、工序数等)生成自己想要的案例,同样也以JSON形式保存到本地。

  案例格式化的目的在于三方面。第一,就是将不同的调度定义进行转换,使得调度平台的输入只有一种格式,从而简化维护过程;第二,JSON格式具有很强的可读性,“属性:值”这样的表达远远要比一堆纯数字要清晰得多;第三,Instance采用面向对象的思想,可以让其具有更通用的表达能力
在这里插入图片描述

图1 调度案例JSON格式 vs 原格式

1.3.2 案例初始化与重置

  通过FileHandle类中的相关方法就可以将本地JSON读取到内存中,但是此时调度案例中各个对象间的关系是独立的,比如某一工序的前置和后置工序为空,工序对应的工件为空,因此在执行调度前一般需要对案例进行初始化,具体的初始化内容加表表2。初始化过程仅仅在算法整个生命周期中执行一次。

表2 案例初始化具体内容
初始化项 初始化值
调度目标objective 默认为ObjectiveCmax,即制造期
工序任务map 遍历各个工件的各道工序,以工序名称为key,以工序为value存入map
工序剩余工时 当前工序工时+其后所有工序总工时
工序剩余工序数 最后一道工序为1,倒数第二道工序为2,以此类推
工序对应工件 设置为当前正在处理的工件
工序的前置工序 工件的工序列表中前一道工序
工序的后置工序 工件的工序列表中后一道工序
工件总工时 工件的工序任务列表工时总和
机床已分派任务队列 新建一个TreeSet,设置一个按照工序开始时间升序排列的比较器

  调度案例重置的目的是在使用迭代优化算法时,每一次迭代开始前先清除上一代的调度结果,具体的重置内容见表表3。重置过程需要在每次迭代时执行。

表3 案例重置具体内容
重置项 重置值
调度目标objective 0
已调度总工时 0
就绪任务集合 设置为默认的任务比较器,添加所有工件的首工序至该集合
工件当前工序 工件的首工序
工序调度开始和结束 0
工序已分派机床 ID为-1, 名称为空,表示未分派
工序状态 Operation.Unassigned_state表示待分派
工序固定分配机床 -1
机床已分派任务队列 清空
机床已分派任务工时 0
机床负荷率和利用率 0
工件调度开始和结束 0

1.3.3 案例工序分派

  任务调度是基于析取图模型(后面再单独讲)的,如图2所示,大致就是确定需要相同机床上加工的工件顺序,然后再通过拓扑排序得到调度结果,整个调度流程如图3所示。
在这里插入图片描述

图2 析取图模型

在这里插入图片描述

图3 基于析取图的调度流程

  调度分派过程中采用了插空法,这样就能得到活跃调度,因为已经证明最优解存在于活跃调度中。

1.3.4 案例调度后处理

  后处理主要是计算调度结果并进行输出。

1.4 单机调度案例启发式求解

1.4.1 案例格式化

  在InstanceGenManagerTest中给出了单机调度案例格式化的测试,方法genSingleMachineInstance需要三个参数,分别为:标准案例文件路径,案例个数和工件数量。

InstanceGenManager instanceGenManager = new InstanceGenManager();
instanceGenManager.genSingleMachineInstance("D:\\Personal\\Desktop\\单机调度案例\\wt40.txt", 125, 40);
instanceGenManager.genSingleMachineInstance("D:\\Personal\\Desktop\\单机调度案例\\wt50.txt", 125, 50);
instanceGenManager.genSingleMachineInstance("D:\\Personal\\Desktop\\单机调度案例\\wt100.txt", 125, 100);

  格式化后的案例默认存放于系统盘用户目录(我的是C:\Users\Administrator\instance)下,如图4所示。其中“0”表示单机调度类型,40/50/100表示工件数量,1表示机床数量。在该三个文件夹下各有125个调度案例,以“.ins”为后缀名,可以用NotePad打开,同时需要在插件管理中安装JSON Viewer,这样看起来就舒服多了,但这并不是必要的。所有这些文件都已经准备好,无需运行以上代码。
在这里插入图片描述

图4 格式化后所在目录

在这里插入图片描述

图5 JSON插件安装

1.4.2 读取格式化后的案例

  读取案例也很方便,只要调用相应的方法即可,如读取单机案例则执行FileHandle的readSingleMachineInstance方法即可,输入参数为案例所在文件夹名称,如图4中的“0_40x1sample”。

1.4.3 创建启发式管理器

  调度管理器采用接口(ScheduleManagerIface)的形式对调度使用的主要过程进行了定义,然后在实现类ScheduleManager中实现了一般的调度过程,其实大部分调度过程离不开这个范围,如果有特殊的调度过程,可以继承ScheduleManager,对相应的方法进行重写(override)即可。这里的启发式调度管理器HeuristicScheduleManager直接继承了ScheduleManager而没有重写。

package mm_scheduler.instanceScheduler.algorithm.heuristic;
import mm_scheduler.instanceScheduler.instance.manager.ScheduleManager;
/**
 * @author: hba
 * @description:启发式调度器,完全继承了ScheduleManager
 * @date: 2019年12月18日
 *
 */
public class HeuristicScheduleManager extends ScheduleManager {
	/**
	 * @author hba
	 *
	 *         下午5:25:38
	 */
}

1.4.4 创建启发式调度器

  调度器是用户进行调度的交互入口,在新建启发式调度器时需要指定所使用的启发式规则,可以有两种指定方式:启发式规则对象和启发式规则编号。

  目前在rules路径下指定了34中启发式规则,这些规则均继承于OperationRule类,自定义的规则也需要继承该类,然后根据规则属性重写compare方法。创建调度器时只需要传入规则对象即可。

HeuristicScheduler heuristicScheduler = new HeuristicScheduler(new OperationEDD());

  当需要一次运行多个规则时,平台里还提供了一种通过编号确定规则的方式,创建调度器时只需要传入规则对应的编号,同时该编号对应的规则一定要在InstanceUtil的setInstanceOperationComparator方法中进行注册。

HeuristicScheduler heuristicScheduler = new HeuristicScheduler(ruleID);

1.4.5 执行调度

  创建完调度器后,直接调用其schedule方法即可。

heuristicScheduler.schedule(instance, 0);

1.4.6 调度结果

  这里以40x1的第一个单机案例为研究对象(其加权拖期最优解为913),使用34种规则进行调度,得到的结果如表4。通过以下结果可以发现,很多规则得到的调度结果是相同的,这是因为在按某一属性进行排序时得到的调度结果是相同的,同时不同规则间调度性能差别也很大,所以不同的规则组合搭配成复合规则往往取长补短,更加有效。

表4 40x1第一个调度案例结果
规则名称 加权拖期 执行时间(秒)
FOPNR 7755 0.048
MOPNR 27509 0.002
SPT 7755 0.001
LPT 27509 0.001
SRPT 7755 0.001
LRPT 27509 0.001
MINSEQ 7755 0.001
EDD 1588 0.001
SPT/TWK 7755 0.0
LPT/TWK 27509 0.001
SPT/TWKR 7755 0.0
LPT/TWKR 27509 0.0
SPTxTWK 7755 0.001
LPTxTWK 27509 0.0
SPTxTWKR 7755 0.0
LPTxTWKR 27509 0.001
SRM 7755 0.0
LRM 27509 0.001
SSO 7755 0.0
LSO 27509 0.0
SPT+SSO 7755 0.0
LPT+LSO 27509 0.0
S-1 1588 0.001
S-2 27493 0.001
S-3 1588 0.0
S-4 1588 0.001
S-5 27493 0.001
S-6 1588 0.0
S-7 1588 0.001
S-8 27493 0.001
GW 3354 0.0
LW 23831 0.0
WSPT 3066 0.001
WLPT 30647 0.001

参考文献

H.A.J. Crauwels, C.N. Potts and L.N. Van Wassenhove (1998). Local search heuristics for the single machine total weighted tardiness scheduling problem, Informs Journal on Computing 10, 341-350.

R.K. Congram, C.N. Potts and S.L. van de Velde (1998). An iterated dynasearch algorithm for the single-machine total weighted tardiness scheduling problem. In preparation.

发布了42 篇原创文章 · 获赞 56 · 访问量 5716

猜你喜欢

转载自blog.csdn.net/hba646333407/article/details/103722161