近段时间忙于各种项目和对【易排平台】的优化,没顾得上分享APS相关的小技巧,回头看看小公众号的关注人数早已达1500+,在此争取时间写一下这段时间在项目上及平台优化过程中遇到的一些小技巧,以感谢诸位的关注。过去数月的解决的问题中,涉及最多的是规划模型中,实现各种时间维度的功能,目前在平台上也稍有成果。因此本次分享就选取其中几个较具代表性的情况,分享给大家,欢迎大家一起探讨。
多种工序接续关系导致的时间推导逻辑
在项目计划中,任务与任务之间存在多种接续关系,使用PJS模型作为APS的规划模型时,我们可以把一个工单看作一个项目, 工单中的各个工序看作项目中的各个任务,一个工单的加工计划,就相当于一个项目执行计划。因此,在该模型背景下,任务的规划可以划分为空间规划与时间规划,其中前者体现为各任务的资源分配过程,后者可以归纳为任务的开始时间,任务与任务之间的关系等。
在开始讨论规划过程中的时间计算之前,需要先对其中一些概念作一些定义,以简化下文的语言描述。
概念定义
在项目计划有多种接续关系,目前易排系统中实现了FS(Finish to Start)与SS(Start to Start)两种关系,其它关系将视具体的项目情况,若有需要再具体实现。
前置工序、后置工序
在一个工序路线上相邻的两个工序,需要先加工的(即前面的)工序,我们定义为前置工序,后加工的称为后置工序。
前导任务、后续任务
分布在同一资源(例如机台、产线)上、且相邻的两个任务,在时间轴左则(先加工)的我们称之为前导任务,右则(后加工)的我们称为后续任务.
静置时间
工序路线上两个前/后置任务之间,若前置任务完成后,需要等待一段时间,后置任务才能开始,该等待时间,我们称为静置时间。
接续关系
同一工序路线上,前后两个任务的制约关系,我们称为接续关系。因为我们使用PJS作为原型衍生出来的模型作为规划模型,因此,【易排平台】借用了项目管理中项目计划的任务间依赖关系,正常的项目依赖包括FS(完成-开始),FF(完成-完成),SS(开始-开始)和SF(开始-完成)。而【易排平台】为仅提供其中较为常见的两种关系:FS和SS。这两种关系在系统中的实现逻辑如下。
任务计划开始时间
在PJS模型中,关于时间维度的推导,其中一个关系变量是各任务的开始时间,各个任务几乎所有时间长度和时间点(我们称为时刻)都与任务的计划开始时间有直接或间接关系。因此,本文着重讲解各种情况下,任务开始时间的推导逻辑。
FS接续关系
FS接续关系是表示前置工序全部完成后,后续工序才开始生产。这种关系通常出现在后置工序对前置工序具有整体依赖关系的情况。例如一些大型装备生产加工过程中,一个工序的加工对象就是一件大型零部件,因为场景、设备等限制,需要一个工序完全完成后,才能整体交付出去,后置工序才能拉着生产。
这种接续关系在排程过程中的时候推导最为简单,当前任务的开始时间,为前置任务的完成时间,加上前置任务的静置(详见【静置时间】一节)时间。
SS接续关系
SS接续关系即Start to Start接续关系,它表示前置工序完成了一定量,后置工序即可开始。通常我们用SS 50%, 表示前置工序完成了50%的工作量,后置工序即可开始。例如一个工单的某个工序,需要产生1000件半成品,这些半成品将成为后置工序的原料。为了提高资源利用率,后置工序通常不需等到1000个半成品全部生产完成后才启动生产。而是待前置工序完成了50%(即500件),后置工序即会开始接力加工,从而实现前后两个工序一定程度的并行加工,进而缩短整个工单的生产周期。
这种情况下,一个任务的开始时间,将不再以前置任务的完成时间为基准进行计算,而是以前置任务完成50%的时间作为基准。即开始时间为:前置任务开始时刻 + 前置任务整体时长 * 50% + 静置时间
同一资源上相邻任务的接续关系
上述描述的是同一产品的工序路线前,两个互为前/后置工序的任务,因接续关系不同,而导致的计划开始时间计算差异。而分布在同一资源上的一系列任务,同样存在时间推上的逻辑需要理清。
在同一资源上一对互为前导/后续关系的任务(即两个相邻任务),在时间任务的计划开始时间时,也需要注意。任何一个任务的开始时间,除了考虑其前置任务的结束时间(或在使用SS关系,完成一定百分比的时间)外,还需要考虑该任务的前导任务的完成时间,否则就会出现时间重叠,即一个资源在某一时间段出现多个任务,导致资源超用。
虚拟任务
而同一资源上两个任务之间有可能存在一些额外操作,例如:同一机台加工完一个零部件后,需要加工另一个产品的零部件,有可能需要更换模具、夹具,这些额外工作,视不同任务的参数而定,有可能不需要额外工作(例如:两个所有参数均一致的零部件加工),也有可能需要同时进行多个额外工作(例如:有些任务的转换,除了需要更换模具,还需要重新调整加工参数,重新试制等)。我们把这些额外工作称为虚拟任务。虚拟任务的多少,及用时长短,对后续任务的开始时间会造成影响。
因此,在同一资源上,一个任务的开始时间为:前导任务的结束时间,加上前导任务切换到后续任务的虚拟任务时长。
现留有以下疑问大家可以思考一下:
- 前导/后续任务为什么不需要加上静置时间?
- 一个任务的开始时间,需要同时考虑前置任务的完成时间及前导任务的完成时间,那么这两个时间以哪个为准?
工序间的静置时间
如上述的定义,【静置时间】是指两个前置/后置工序之间的等待时间,对于离散结构的工序路线,静置时间可能存在多个工序之间。例如一个任务存在多个后置任务时,对于不同的后置任务,可能存在不同长度的静置时间。例如,在某些情况下,喷涂工序完成后,需要等待4小时才能进行镀膜工序,但同样是喷涂工序的后置,在工作表面上的钻孔工序,可能静置两小时即可完成。若镀膜工序与钻孔均为喷涂工序的后置工序,则它们具有不同的静置时间,因此,在设计规划模块时,必须考虑此类离散情况下的复杂场景,能实现尽可能减少等待时间,提高资源利用率。
在【易排平台】最初的设计中,我们考虑了将静置时间纳入前置工序的加工时长上,并作出标识,用于区分工序的加工结束时间与静置结束时间。此方案从时间上确实可以实现后续工序必须在静置完成之后才开始。但存在非常大的局限性与弊端。因为所谓的静置时间,对于一个任务而言是不占用任何资源的(完成喷涂的工件可以放在等待区,喷涂产线可以继续加工后续的工作),若将静置时间加到喷涂工序的时间上,就会造成静置时间也相当于占用了资源。虽然当时我们修改了资源占用的计算方法,将静置时间略过,但该方案明显会导致判断逻辑变得复杂。且上述提到的存在多个静置时间的情况,也难以实现,当然你也可以考虑将静置时间添加到后置工序的开始处,但同理,离散结果的场景不仅存在多个后置工序情况(即工序路线分叉),还存在多个前置工序的情况(即工序路线合并),因此,逻辑将非常复杂,且导致部分场景出现歧义。
最终我们使用的方法还是修改该设计方案,新的方案是将静置时间抽出来,作为任务间的独立属性存在,该属性不属于工序,而属于工序之间的关系。即在工序路线这个有向图上,静置时间不属于一个任务,而是属于两个任务之间的弧。
原本计划把所有时间相关的设计思路都介绍一下,但发现就目前介绍的思路已经需要相当篇幅。因此将剩余的其它时间相关设计留在下一篇。
事实上,上述对于各场景下,时间的推导只是最为简单的思路,需要实现这些逻辑时,还会遇到非常多需要考虑的要素,限于篇幅不可能在此完全阐明。如下图我们关于时间推导设计的其中一些设计资料,那是相当细的工作。
下一篇,我们将介绍以下几点的时间设计思路
任务加工时间适配资源日历的方案
大多数资源不可能 7 x 24工作,也不可能所有任务都能在一个班次(8或12小时)内完成,那么如果实现这些不规则的时间片段与任务长度呢?
工单的排程方式如何体现在时间上
我们现有的生产计划,有前推式排程,尽可能早开始;还有后拉式排程,尽可能晚开始(JIT);此外,还因为资源限制或半成品时效限制等因素,以关键工序为基准进行排程(尽可能保证关键工序资源使用率最高)。那么在时间上应该如何设计,才能实现这三种典型排程呢?
因时间计算逻辑,引起的OptaPlanner各种Corruption问题
在处理时间推导逻辑过程中,经常遇到本来很正常的程序,加上一些时间推导逻辑后,就会出现“Score corruption”,"UndoMove corruption"与"Variable Listener Corruption". 这些异常产生的根本原因是什么?应该如何识别?识别出来应该如何改进设计来适配OptaPlanner的评分规范要求,以消除这些异常?
写在最后
有同行问到:为什么你分享的经验都是一些细枝末节?有没有一些“更有营养”的内容可以分享一下。
我觉得吧,小弟正是软件开发出身的,偶然的机会接触到APS,更偶然机会接触到OptaPlanner才开始的APS系统设计开发工作。经历的都是各种很底层且很细节的问题,但在这些项目实践过程中,我也总结到一些经历,那就是一个很好的方案能否落地,很多细节往往都是起决定性作用。就算不谈技术方面,就是做具体的实施,客户的具体业务场景、细节和规则,都是至关重要的。
一个宏观的方案对于客户高层领导对整个项目的理解当然是重要的,但项目一旦启动,能否切实地满足需求,使用项目通过各种系统、数据、流程落地到具体的用户部门,才能最终体现整个项目的价值。所以,细枝末节多关注一些也无防。而且纵观整个市场,能提供宏大、高阶推介方案的专家顾问很多,水平极高;相反愿意潜心去处理细枝末节这种脏累差活的人却不多,因此,研究起来可以参考的案例、资料相当匮乏,能深入研究一下,应该也挺有价值的。
<完>