OptaPlanner将弃用DRL(Drools)评分方式!!!

本来这段时间一直都在加紧我家”三胎”(易排通用智能规划平台)建设,毕竟我们的通用规划平台原定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官方发布的博文:

使用DRL评分方式的优点

因为Drools本身是与OptaPlanner同属一项目群(KIE)的开源规划引擎软件,它具有一套成熟的规划描述脚本及规则推理引擎。算是目前世界上最成熟的开源规则引擎了(有没有之一不清晰,也许是我见识不够广)。因此,当我们使用Drools脚本,对OptaPlanner中涉及到的各种各样业务规则(都会抽象成约束)进行评分描述时,是相当有优势的。OptaPlanner这个引擎与Drools有相当丰富的接口,可实现两个引擎之间的高度匹配,从而则让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方式供各位小伙伴集成到自己的系统中。当然要调用这些接口,其中一个很重要的步骤是把你们自己的系统中的业务数据,构建成这个接口的数据规范,才能把它传进来调用这些接口。关于这个接口说明视频,我已经发布在我的公众号上,当然知呼视频我也会上传。后续我会把构建这些数据的各个要点以短视频方式给大家提供讲解,从这些短视频中,并仅仅可以掌握这个平台接口的一些约束,还可以学到一些不错的干货,因为这两个月来,为了构建这个接口数据,里面表达业务的各种原理、规则、方案,设计一个推翻一个,经过无数次的迭代,最终才形成现在相对科学合理的结构。

接口说明:

平台讲解说明视频:

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

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

Original: https://www.cnblogs.com/kentzhang/p/16498174.html
Author: kentzhang
Title: OptaPlanner将弃用DRL(Drools)评分方式!!!

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621184/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • knife4j通过js动态刷新全局参数

    背景 之前在为框架集成knife4j接口调试查看工具,使用了一段时间,使用体验上比较繁琐,因为接口都需要token,所以每次都要去f12查看token复制再创建全局参数,可能我只需…

    Java 2023年6月15日
    076
  • Python工具箱系列(七)

    上期描述了如何在ubuntu18.04下安装python3.8,本期将描述: · BIOS开启CPU的虚拟化支持 · 如何在windows10/11下安装wsl/wslg · 如何…

    Java 2023年6月16日
    073
  • 微服务SpringCloud之Spring Cloud Config配置中心SVN

    在回来的路上看到一个个的都抱着花,吃了一路的狗粮,原本想着去旁边的工业园里跑跑步呢,想想还是算了,人家过七夕,俺们过巴西。上一博客学习了Spring Cloud Config使用g…

    Java 2023年5月30日
    065
  • fastposter v2.9.0 程序员必备海报生成器

    fastposter v2.9.0 程序员必备海报生成器 🔥🔥🔥 fastposter海报生成器是一款快速开发海报的工具。只需上传一张背景图,在对应的位置放上组件( &#x…

    Java 2023年6月5日
    086
  • Java多线程

    一、线程简介 任务:要完成的一件事情 进程:操作系统中运行的程序就是进程( 一个进程里面有多个线程) 线程:(单线程)一条道路执行 多线程:多条道路并行执行 Process(进程)…

    Java 2023年6月5日
    079
  • 日常踩坑_下载文件时文件名是乱码

    背景提要 一个下载文件的controller,下载下来内容虽然正常,但是文件名一直是乱码。 解决 需要清晰的一点就是,下载的文件名仅与请求头有关所以实际只要设置一下 respons…

    Java 2023年6月7日
    059
  • MyBatis的基本介绍及优势

    MyBatis 的历史由来 Mybatis 原本是 Apache 软件基金会的一个开源项目叫做 iBatis ,2010 年这个项目由 Apache 迁移到了 google cod…

    Java 2023年6月5日
    083
  • Java并发之ReentrantLock基础(一)

    ReentrantLock是Java中java.util.concurrent.locks.Lock的一个实现类,顾名思义它是Java中锁的一种实现,具体一点来说它是Java中一种…

    Java 2023年6月16日
    057
  • SpringBoot自定义环境变量——EnvironmentPostProcessor

    现有需求是将数据库配置文件中账号密码相关信息分离且加密,用到了SpringBoot中 EnvironmentPostProcessor接口。可以将外部配置文件读取注入系统中。 实现…

    Java 2023年6月9日
    075
  • Eureka详解系列(二)–如何使用Eureka(原生API,无Spring)

    简介 通过上一篇博客 Eureka详解系列(一)–先谈谈负载均衡器 ,我们知道了 Eureka 是什么以及为什么要使用它,今天,我们开始研究如何使用 Eureka。 在…

    Java 2023年6月13日
    064
  • POI往word模板中写入数据

    word导出excel表格自适应宽度 https://www.cnblogs.com/libin6505/p/10339045.html Word 模板引擎,基于Apache po…

    Java 2023年5月29日
    090
  • 双色球系统开发

    Java对彩票双色球系统开发的简单实现 双色球系统 案例: 中奖条件及奖金表 代码及解释 main方法代码: public static void main(String[] ar…

    Java 2023年6月6日
    078
  • mongodb 配置均衡器的运行窗口

    mongodb 均衡器 考虑到数据迁移会降低系统性能,可以配置均衡器在只在特定时间段运行,比如夜里系统负载比较小的时候。详细的配置步骤如下; 连接到任意的mongos服务器,并通过…

    Java 2023年6月6日
    080
  • markdown mermaid甘特图

    甘特图 甘特图(Gantt chart)又称为横道图、条状图(Bar chart)。其通过条状图来显示项目、进度和其他时间相关的系统进展的内在关系随着时间进展的情况。以提出者亨利·…

    Java 2023年6月5日
    056
  • 【Java】Cron表达式

    一. 域说明 二. 特殊字符说明 三. 常用例子 四. 注意事项 1. 有些表达式能包含范围或列表 2. “/”字符用来指定数值的增量 3. “…

    Java 2023年5月29日
    043
  • 作为一个程序员,有什么想对新人说的吗?

    1.工作是我们的生存之本。通过完成工作,公司才能支付我们工资。2.工作是我们技能的最佳## 标题实践,做好工作能同时提高我们的技能。3.通过更好完成工作,同时积累我们对业务的分析、…

    Java 2023年6月13日
    082
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球