kentzhang

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

  本来这段时间一直都在加紧我家“三胎”(易排通用智能规划平台)建设,毕竟我们的通用规划平台原定6月初就能上线,但因为其中遇到的各种技术问题及其它项目的突发情况,导致也只能跟随国家的003号航母,只能推迟上线,进度紧迫。经过近两个星期的奋战,终于将我们的【易排通用智能规划平台】的主要功能上线了,并做了一些基本的使用资料,供各位小伙伴先得试用。

  因为我们的平台还处在刚上线提供试用阶段,后续还有数不清的功能、平台设计、应用小视频需要我日以继夜地奋力补充(这些资料里不仅仅有平台的介绍资料喔,也有我们做规划或供应链信息化设计过程中的一些满满干货,敬请期待),理应是安排不了时间发布新的文章,但发现OptaPlanner已官宣,将在8.x版开始弃用对Drools评分机制,并在9.x不再支持Drools作为评分,作为替换的,将使用Constraint Stream(约束流)方式作为评分。当然,之前支持的Easy Java score calculation和Incremental Java score calculation这两种方式必然不会取消的。其中,我们的【易排通用规划平台】使用的就是Incremental Java score calculation,这种方式的优点是极度高效,有能力的小伙伴可以通过官言的示例尝试一下,目前大多数案例都有多种评分方式的,可以通过修改配置来尝试不同的评分方式,当问题空间足够大时(相同的问题模型,问题空间基本上取决于数据量大小),其运算时间差异可以是一个数量级的,甚至当数量大到一定程度时,使用Drools的评分方式会出现崩溃的情况(之前我们做过一个VRP项目遇到到这种情况,节点足够多时,不是放一两个小时就能跑出来,而是跑着跑着就出现JVM级别的溢出异常了)。

  关于Drools评分方式(下称DRL评分方式,官方也使用类似的叫法)的优劣,及未来补充的ConstraintStream方式,在本文中作一些概括性介绍,更详细的资料及从DRL到ConstraintStream的转换,可以参考OptaPlanner官方发布的博文:

https://www.optaplanner.org/blog/2022/05/26/optaplanner-deprecates-score-drl.html

使用DRL评分方式的优点

逻辑表达丰富,可用较简短的脚本表达较复杂的业务逻辑

  因为Drools本身是与OptaPlanner同属一项目群(KIE)的开源规划引擎软件,它具有一套成熟的规划描述脚本及规则推理引擎。算是目前世界上最成熟的开源规则引擎了(有没有之一不清晰,也许是我见识不够广)。因此,当我们使用Drools脚本,对OptaPlanner中涉及到的各种各样业务规则(都会抽象成约束)进行评分描述时,是相当有优势的。OptaPlanner这个引擎与Drools有相当丰富的接口,可实现两个引擎之间的高度匹配,从而则让OptaPlanner具备更丰富的约束表达能力。

自主生成OptaPlanner中规划实体的约束违反统计信息

  我们做OptaPlanner程序的时候,归根到底是要以高效、合理的方式对让引擎对各个规划实体(Planning Entity)中的规划变量(Planning Variable)进行不同的取值组合,并照我们编写好的评分约束对各个组合方案进行评分,从中找到评分最高的组合方案。而在此过程中,若我们使用DRL评分方式,哪个规划实体的哪个取值违反了哪条约束被扣了多少分,通过DRL的评分方式在运算过程,会把上述做详细的记录。因此,当我们完成规划运算,得到一个方案时,通过这个方案和OptaPlanner的评分API,就可以完整、精确地描述出,究竟是哪个规划实体的哪个变量取了什么值违反了哪个约束,导致被扣了多少分了。这样看来这个功能是不是很炫?目前我见到的其它求解器,应该还没有提供这种功能吧?当然也可能是我孤陋寡闻。而这个功能在业务场景上来说,是相当有用的,就是说,当你的规划程序跑出一个生产计划方案,这个计划方案哪个任务放在哪个机台上,导致扣了多少分,你直接就可以通过它的约束违反信息,就可以直接找到违反约束的原因和具体数据。而不需要我们人工对整个计划方案中的各个数据,一个一个寻找。

  相同的功能要求,如果我们使用的评分方式是Incremental Java score calculation,是没有自动的功能来记录这些约束违反信息的,而是需要我们在实现这个约束逻辑Java代码里,编写相应的评分逻辑,来保存这些信息的。完成了些逻辑后,最终生成的计划方案,才能统计出各个任务的约束违反情况,否则你只能从方案知道它的分数概况,也就是仅能知道哪个约束扣了多少分,但是哪个任务分配到哪个机台,因为与哪个任务冲突引起的扣分,不通过人工去编写逻辑,你是看不到的。

使用DRL评分方式的优点

  老师教导我们,所有事物都要辩证地看,因为事物必然具有两面性的。那么DRL的评分方式的缺点在哪里呢?

学习成本

  这个缺点对于我们没有涉及到规划引擎的小伙伴来说,肯定是一个巨大的差评。毕竟我们去掌握一门新的开发语言都需要花费不少精力了,况且还要学习掌握一门专门编写规则的脚本,虽然它是一种描述性的脚本语言(我们在学校进而学计算课的时候,把这种语言称为第四代语言,例如:SQL脚本),但丝毫不代表它简单。在面对一些复杂的场景时,要实现一些约束的逻辑,我们写脚本虽然不长,但其实要实现它,还是要花费不少心思的。总不会有人说,SQL脚本就比C++、Java简单吧?SQL脚本简单的仅仅是表达的方法,但处理一大堆复杂关联查询时,一条SQL的难点不一定比C++低,毕竟C++还是针对具体的每个对象进行运算的,而SQL则主要设计来针对一个数据集合进行处理的。所以并不能说它就简单。

  要完成对Drools引擎在OptaPlanner上的应用,除了要了解Drools脚本以外,还需要对Drools这个规则引擎的一些基本原理与结构有一定理解,才能更好的理解每个评分约束中,每个变更的含义,例如:哪些变量代表的是一个对象,什么情况下一个变量代表的是一个对象列表。

  当然若完全掌握了Drools的评分方式,并积累了一定用DRL表达OptaPlanner约束的经验后,面对一些约束,还是很有“拿着锤子你看到的满眼都是钉子”感觉的。也就是,当你面对一个约束时,会自然而然地很快通过Drools脚本来构思出它的大概逻辑结构。

运算效率

  运算效率指的是使用DRL评分时,引擎的计算速度。若你深入了解了OptaPlanner引擎的主要工作就知道,它所谓的运算,绝大多数时间都是在进行分数计算,还有小部分是使用各种启发式算法对搜寻过程的搜寻方向进行控制。因此,在这过程中,若使用DRL评分方式,Drools规则引擎就是担起了一个非常大运算责任。但Drools其实还是需要把这些约束转换成Java字节码进行运算的,而且是大量的集合运算,因此,很多情况下,性能上相对直接用Java编写的逻辑会更慢的。大家回忆一下各自的系统的性能卡顿点,是不是很多时候都是一些超长超复杂的SQL存储过程造成的?而其实它卡的原因还不一定是它的逻辑复杂,而是一些逻辑涉到数据集的运算,当我们处理不好这些数据集的关联查询时,就会引起很大规模的集合与集合之间的关联运算(就是各种表、视图进行的各种Join),从而成为绝对的性能瓶。

  Drools在进行约束评分运算时,实际上它就是一个规则推导过程,也有可能涉及很多对象集合的操作与判断。因此,当数据量大,评分约束相当复杂,或关联到众多对象列表时,也有可能引起如SQL查询一样的效果,从而大大影响了运算性能。

DRL评分的替代 - ConstraintStream.

  这种评分方式大概是从7.8x版本开始提出,8.x版本后开始慢慢完善。它充分使用了Java8以后的版本中出现的Stream特性,对大量的场景使用了函数式编程,从而大大地简化了集合数据处理的难度。也就是说,如果我们在使用Java的Stream功能,能很灵活地编写其中的Lambda表达式,ConstraintStream应用起来也是得心应手的。只是因为ConstraintStream是专门针对约束编程的,因此,它提供了一些特定的API供我们使用,我们要理解这引起API的前提,还是要理解评分过程的一些原理与原则。这也是我们学习ConstraintStream最大难点。

  我目前主要投入的精力都在我们的“三胎” - 【易排通用规划平台】上,这个平台因为基于灵活性与运算性能的考虑,我并没有使用DRL或ConstraintStream方式,而是直接使用Incremental Java score calculation的方式。这种方式与前两种对比,最贴切就理解就是单反相机与傻瓜相机的差别吧。正是因为我能在没有时间压力的前提下,把我目前掌握到的各种排产约束通过Incremental Java score calculation方式精心实现,从而让这个平台在运算大数据量订单时,性能远比使用Drools或ConstraintStream高。期待大家可能尝试该平台,这个平台我们将会使用租用方式,以SaaS方式提供一些有规划要求的场景,例如MES、MOM的计划模块。令专门提供这类系统、方案的小伙伴可以开箱即用地拥有一个规划引擎。当然,当你们遇到一些客户的个性化需求、约束或优化目标,而在我们平台上还没有提供的,也欢大家向我们提出,我们可以通过项目合作的方式定制这些功能。

  最后,我做了一个关于这个平台的操作说明。因为这个平台主要是针对我们业内小伙伴,他们都有相应的软件技术能力,且目前时间与精力都比较紧张;因此暂时未提供操作界面供大家使用,而是使用WebAPI方式供各位小伙伴集成到自己的系统中。当然要调用这些接口,其中一个很重要的步骤是把你们自己的系统中的业务数据,构建成这个接口的数据规范,才能把它传进来调用这些接口。关于这个接口说明视频,我已经发布在我的公众号上,当然知呼视频我也会上传。后续我会把构建这些数据的各个要点以短视频方式给大家提供讲解,从这些短视频中,并仅仅可以掌握这个平台接口的一些约束,还可以学到一些不错的干货,因为这两个月来,为了构建这个接口数据,里面表达业务的各种原理、规则、方案,设计一个推翻一个,经过无数次的迭代,最终才形成现在相对科学合理的结构。

接口说明:

https://mp.weixin.qq.com/s/DFLFNgRbJBP-iSONdeTPEQ

 

平台讲解说明视频:

https://mp.weixin.qq.com/s/x46p0en7AQVxRIsioSAmhg

 

  本系列文章在公众号不定时连载,请关注公众号(搜“让APS成为可能”)

  如需了解更多关于OptaPlanner的应用,请发电邮致:12977379@
若有需要可添加本人微信(13631823503)或QQ(12977379)实时沟通,但因本人日常工作繁忙,通过微信,QQ等工具可能无法深入沟通,较复杂的问题,建议以邮件或讨论组方式提出。(讨论组属于google邮件列表,国内网络可能较难访问,需自行解决)

 

posted on 2022-07-20 15:23  kentzhang  阅读(183)  评论(0编辑  收藏  举报