本文主要讲述使用MindOpt工具优化FlowShop流水线作业排班的数学规划问题。
一、案例场景
FlowShop流水线作业排班也有称为生产下料问题,它涉及到多台机器、多个工序以及多个作业调度安排。在这个问题中,我们需要对多个作业在一组流水线上的处理顺序进行安排,以使得完成所有作业的总时间最短。
应用场景包括但不限于以下几点:制造业是FlowShop排班最传统的应用场景,如汽车、电子产品、服装、食品加工等。通常需要经历一系列的加工步骤,每步由不同机器完成,合理排班可最大化生产效率,缩短交货时间。
第二,在化学品和药品的生产中,原料需要按照一定的顺序,通过反应器、混合器和分离器的设备,排班优化有助于减少制造周期时间,提高设备使用率和这个质量。
第三,半导体制造,半导体生产涉及到严格的加工设计和清洁室环境,有效的作业排班能够降低在机台上的等待时间,提高产量。
第四,机械加工,零件需要通过生产、钻厂、等多个工序,合理排班可以减少机械加工时间和代制品的储存。
第五,在印刷业场景,印刷作业需经过预处理、印刷后处理等流程,正常的排班能够保证交货期限,并降低成本。
第六,物流和供应链,在分拣中心或仓库商品的装箱运输带排序等也需要考虑作业排班优化,提高物流的效率。
二、数学规划
这个问题可用数学规划方法解决。数学规划是一种数学优化方法,主要是寻找变量的取值,在特定的约束情况下,使决策目标得到最大或者最小的决策。数学规划的方法有线性规划、混合整数线性规划以及非线性规划。需要确定问题目标,约束变量取值范围,将其建立成一个数学模型,将数学模型转化为代码进行求解,得出的结果就是最优决策。求解过程中,需要使用优化求解器,可以帮我们求解大规模数据的数学规划问题。
三、问题描述
公司生产几套产品。这些产品的规格都不一样,生产各个环节的耗时会不一致,工厂的机器资源有限,如何安排产品生产,让总生产耗时最短?
我们考虑以下四点因素:一是产品的多样性,提到生产几套不同的产品,表明每个产品有不同的加工流程和时间。
二是工序耗时不一致,每个产品在每个工序上的耗时不同,意味着需要为每个产品的工序定义不同的处理时间。
三是机器资源有限,机器数量受限,这意味着不可能为每个工序同时分配一台机器,需要进行排班来高效利用机器资源。
四是让总生产耗时最短,通常意味着需要最小化目标,就是能完成所有产品的最终操作所需要的总时间。
四、代码解析
使用工具:
- MindOpt Studio 云建模平台,在线开发调试,免下载
- MindOpt APL(MAPL)建模语言编程,代数建模语言,语法与数学公式相近
4.1 参数、集合定义
首先定义了CSV文件的路径是在data路径下,然后定义了两个集合,一是产品任务的集合,二是工序机械表的集合。读取data目录下的production name csv文件。后面的1n是读取数据的方式。目前支持读取数值和字符串两种类型。1n是按照数值读取文件的第一列。skip 1表示跳过表格的第一行内容。第二个集合machines也读取第一列的数值。
下面声明的参数是读取了production time文件,表示1n、2n以及3n是读取个产品在每个工序的耗时, 比如产品1在这个工序机器1上所需加工的耗时是54,我们这两个参数定义了分别代表集合jobs产品任务列表和工序列表的基数。在数学规划或优化问题中,通过计算集合的基数可以得到关键的数值信息。
4.2 变量解析
第一个变量是x{i,k}, 这是一个二进制决策变量,表示产品i是否在序列中的位置K上进行加工,如果说I在位置K上加工,那么x{i,k}=1,如果不是,x{i,k}=0。这个变量建立了产品与加工顺序之间的关系。<I,k> in jobs定义了索引对i、k的范围。其中每个I和每个K都取自同一个集合jobs,这意味着对于每个工作任务都有一个与其他所有可能序列位置的关联。
第二个s{m,k}表示在机器m上处理序列中位置K作业时的开始时间,<m,k> in machines定义了索引对MK的范围。其中m取自机器集合machines,而K取自工作任务集合jobs,这就确保了为每个机器和每个工作任务都分配了开始。
第三个变量是e{m,k},表示在机器M上处理序列中的位置K作业时间的结束时间。定义与上面s{m,k}是相同的索引堆范围,确保了为每个机器和每个工作任务都分配了结束时间。
声明的目标是最小化最后一个工序机器上最后一个排序序号任务的加工结束时间。决策变量e是一个特定的元素,表示在最后一台机器last machines上处理最后一个作业Last jobs时的结束时间,这实际上是整个生产流程的完成时间,目标函数的选择反映了一个假设,所有作业必须在最后一个机器上完成。因此,总时间是由在最后一台机器上完成的最后一个作业的结束时间来决定的。通过最小化时间,可以确保整个作业流程尽可能高效。
其次,在排程问题中,总的完成时间经常被用作性能指标,因为其能直接影响到生产成本和交货时间。在实际的应用中,这个指标可能会与其他方面考虑,比如作业的平均完成时间、延迟时间,或者机器空闲时间等结合起来共同构成更为复杂的目标函数。
4.3 约束解析
第一个约束意味着对于每一个产品I以及在整个加工顺序jobs上的分配之和,通过二进制变量x{i,k}表示。当x{i,k}=1时,表示产品i位于加工顺序的第K个位置,分配之和应等于1。也就是任何产品都不能同时出现在多个不同的加工位置上,每个产品只能被安排在一个特定的加工顺序位置。
第二个约束意味着对于每一个加工顺序位置K所有可能的产品i的二进制变量x{i,k},对于每个加工顺序的位置K及所有可能的产品I的二进制变量x{i,k}之和应等于1。也就是在任何一个特定的加工顺序位置上,只有一个产品的xIK会取值为1。表示该产品被安排在加工顺序的位置上,其他产品就不能在这个位置上。这个约束确保了每一种加工顺序只可能有一个产品对应。
第三个约束表示所有可能的产品及其组合,集合machines中每个机器m与集合jobs的每个产品k,产品k在机器m上的完成时间e{m,k}必须大于等于该机器M上的开始时间,即s{m,k}与所有产品i乘以被安排的耗时的概率之和,概率通过变量体现。换句话说,在确定了加工顺序后,这个顺序由x{i,k}决定,模型确保了产品k在机器m上的结束时间至少要考虑到从开始加工到完成整个生产过程所需要的时间,包括实际生产耗时。
第四个约束表示在对于每台机器m和除了最后一个产品之外所有产品位置k下一个位序的产品,在这个产品位置k上开始实现,也就是s{m,k+1}必须大于等于当前产品K在这台机器上的结束时间,用e{m,k}表示,除了最后一个产品之外的所有产品位置k用集合jobs中剔除最后一个元素后的所有元素。这个约束保证了在流水作业中,一台机器上的加工顺序是连续且交叉的,每个产品在完成之前下一产品不能开始。
第五个约束表示去除最后一台机器之外的所有机器m和集合jobs中的K以及jobs中的所有产品位置k,产品位置k在下一机器m+1上的开始时间至少要等于该产品在当前机器m的结束时间。也就是在流水线作业的连续过程中,每个产品在完成一台机器上的加工后,才能开始在下一台机器上加工,确保了加工顺序在不同机器间是连续且无交叉的。
最后一条约束规定了当产品按照顺序开始加工时,第一个产品在第一台机器上的开始时间s{1,1}必须为0,也就是从零开始生产第一个产品。这意味着整个生产流程的计时起点是从第一台机器上对第一个产品的加工开始的,假设没有任何预处理或者等待时间,从该时刻开始计算每个产品的不同级以上的加工时间和完成时间。
4.4 对模型进行求解
display是我们打印决策变量的取值。本案例的变量值过多,因此我们可以输出一个CSV文件,以数据表格的形式展示内容,提高决策变量的可读性。
首先我们代码是打印了一行表头,描述了CSV文件的一些列信息,这行代码将标题打印到一个名为排班计划.csv的文件中,这些列标题包含产品、序号、各个工序的开始时间。第一个工序S到第五工序以及作业在最后一台机器上的最后结束时间,我们使用close命令关闭文件。
然后需要将数据写入排班计划表格。用forall对于集合调度的所有可能组合ik进行一个遍历,条件是x{i,k}大于等于1,也就是作业I被分配到了这个位置K的时候,对应每个作业的每个位置。我们使用print语句,将作业编号I、作业在这个调度中的位置K、每台机器上作业的开始时间s{1,k}到s{5,k}以及在最后一台机器上的结束时间e【 lastmachine ,k】格式化后追加到排班计划文件中。其中,(:.0f)表示将数字格式化为没有小数部分的整数,再使用close关闭文件。
4.5 结果解析(部分)
最小耗时1278,即我们求解得到的最小决策目标。下方为决策变量的取值,也就是我们产品1安排在了第9个位置进行加工。第一个工序S的开始时间是343,第二个开始时间是397,依次往下推。最后第一个产品的最后的结束时间是703。
五、源码获取
大家可以扫描二维码,获取源代码。