在给仓库、生产线和配送中心搭建仿真模型的时候,订单是按什么规律到达的,会直接拖拽排队长度、设备利用率和人员是闲着还是忙不过来这几项指标。如果订单是一整天里零零散散进来的,跟每天固定在几个时间点集中释放一大批订单,两种情形跑出来的结果差异非常大。FlexSim里处理订单到达的办法不止一种,既可以在三维模型里用Source对象定义到达规则,也能通过Process Flow里的Schedule Source配合Global Table来模拟更加复杂的波次订单,Source对象自身也支持间隔到达、计划到达和顺序到达等多种方式。
一、订单到达规则该怎样定义
定义订单到达规则的时候,要先根据真实业务数据来选,不能只图省事随便套一个随机分布就完了。如果实际的订单明明集中在某几个时间段,但模型却把它平均分摊到了一整天里,那后面再去判断拣选效率的时候,得出的结论就会偏离实际情况不少。
1、零散订单适合用间隔到达
如果订单是持续地、没有明显规律地零散进入,那就可以先在场景里选中Source对象,然后在属性面板里把Arrival Style这一项改成【Inter-Arrival Time】,再填进去一个到达间隔的数值,或者在统计分布里挑一种更贴切的分布函数。这种设置比较适合用来描述客户随机下单、车间任务随机进入,或者前端请求不均匀到达这一类场景。
2、有历史表格的固定订单改用计划到达
如果手头已经有一张整理好的历史订单表,就可以把Arrival Style改成【Arrival Schedule】,再在下面弹出来的表格里,一行一行地填写订单到达的时间、每次到达的数量,还有需要附带上去的标签信息。按照官方文档的说明,Arrival Schedule这个功能会根据表格里填好的定义去创建Flow Item,每一行都可以指定到达时间、数量以及附加标签,这样就能把历史数据比较准确地还原进模型里。
3、别忘了给订单打上业务标签
光生成一批规格完全相同的物料,对后面再深入做仓储分析是远远不够的。比较建议的做法,是给订单加上OrderID、SKU、Qty、Priority、Destination和WaveID这类标签,这样一来,后面模型里分拣、拣选、缓存和配送这些环节,都可以直接去读这些标签里的值去做判断,而不用给每一种不同的订单都单独拉一套对象出来,这样整个模型维护起来也会轻松不少。
二、波次订单应该怎么模拟
遇到那种分批次集中释放的波次订单,用Process Flow来处理会更加顺手,逻辑也更清晰。在这种流程里,可以把每一个订单表示成一个Token,然后通过Schedule Source来控制它们被释放的时间点,这样就能把订单生成、波次释放、任务分派还有设备资源这几块拆开来单独管理,整个结构不会搅在一起。
1、先建一张订单数据表
在Toolbox里找到Global Table并把它加到项目里,然后按行把订单数据填写进去,常用的几个字段一般包括OrderID、ReleaseTime、WaveID、SKU、Qty和Destination。如果原本就已经有一份整理好放在Excel或数据库里的历史数据,那直接把它粘贴到表格里就行,省得一条一条手工敲进去。FlexSim官方的教程里使用的也是这种方法,先用Global Table把OrderID和ReleaseTime保存起来,再让它按照指定的时刻去重新生成对应的订单事件。
2、把Schedule Source拖进流程里
顺着【Toolbox】→【Process Flow】→【General】的路径,先新建一条流程,然后把一个【Schedule Source】组件拖进去。接着在它下面的Arrivals表格里,把每一波释放的时间点和这一波该出多少个订单给填上。Schedule Source这个组件,会一波一波地按照你在表格里约定好的时刻去创建Token,正好适合拿来模拟那些在固定时刻集中到达的订单批。
3、把订单信息写进Token里去
在Schedule Source后面再接上【Assign Labels】或者【Create Object】这类活动,让每一个刚被创建出来的Token到Global Table里面去,把属于自己那行的OrderID、SKU、Qty和WaveID都读出来并挂在自己身上。如果后面还需要在三维场景里模拟真实的箱件,那就再顺下去创建Flow Item,顺便把Token上挂着的标签也传给它。官方教程里演示过类似的做法,通过Global Table Lookup这种活动去读取数量、SKU和目标队列,再去生成对应的对象,形成一套完整的订单流转链条。
4、按波次把释放节奏控制好
比如每天上午九点释放Wave01,十点半释放Wave02,下午两点再释放Wave03,直接在数据表格里写上不同的ReleaseTime就能做到。如果想让每一天都重复同样的节奏,那可以再复制一份时间表,或者加上周期循环的逻辑。操作的时候有一点要特别留意,不光是要写准订单的数量,还要把波次与波次之间那些没有订单的空档也保留下来,不然模型跑起来很容易把前后两批订单压成一批,那就不是原来波次的样子了。
三、模拟跑完之后该怎样检查
模型能正常跑起来,并不代表订单规则就已经设置正确了。跑完了仿真以后,还要回头去看看订单实际到达的时间、队列起伏变化的规律,还有各项资源利用率是不是跟业务预期一致,这几步不能省。
1、核对一下订单的数量和到达时间
把模型跑完以后,可以先从结果里抽几个Token或Flow Item出来,检查它们的OrderID、WaveID以及进入系统的具体时间是不是对的。在固定波次的场景下面,订单应该在事先设定好的那个时刻集中地出现,既不应该提前跑出来,也不应该被重复创建,出现任何这类情况都说明规则设置有偏差。
2、观察一下队列的峰值变化
可以给Queue这类缓存对象加上一个Content vs Time的图表,用来观察每一个波次进入系统以后,在制品数量是跟着时间怎么变的。FlexSim里的Content vs Time模板是用阶梯图的形式来展示对象里内容量随时间变化的情况的,很适合拿来判断订单是不是在某个波次之后就被堆住了,一直没有被消化掉。
3、修改数据后要先重置再运行
每次改动了Global Table里的数据、调整了随机分布的参数,或者增删了标签以后,都要记得先执行一次Reset,再重新启动运行。因为Global Table和对象上的标签属于持续存在的数据,要是没有恢复初始值,就接着上次跑了一半的状态继续跑,重复运行出来的结果很可能就对不上号了。
总结
关于FlexSim里订单到达规则该怎么定义,以及波次订单要怎么模拟,处理上的顺序大致可以概括成这样:碰上零散进入的订单,用Source的间隔到达就能解决问题;已经有固定时间表的订单,可以直接套用Arrival Schedule;再复杂一些的波次释放情况,就进到Process Flow里,靠Schedule Source配合Global Table去实现。在生成订单的时候,记得把OrderID、SKU、Qty和WaveID这些关键标签补全,等仿真跑完之后,再去核对一遍订单的释放时间、队列的峰值高度,还有重复运行时得出的结果是不是稳定。只有当这些到达规则都写清楚、验明白了,后续再去分析需要配多少人手、设备能力到底够不够,拿出来的数据才真正有参考价值。
