因为工作和其它原因,很长一段时间没有出新的、关于OptaPlanner的文章了,但工余时间并没有停止对该引擎的学习。与此同时Geoffrey大神带领的KIE项目团队并没有闲下来,尽管在工业可用性、易用性和使用门槛方面,OptaPlanner相对传统的求解器已经做得相当出色;特别是在规划过程交互、和各种操作接口方面,更是目前最为容易使用的规划求解器。

以第7版一系列子版本中,OptaPlanner很多子版只作了细微的更新,如优化规划性能,改善Business Center集成水平等。而在作为OptaPlanner直接使用者的我们而言,第7版的所有子版本中,目前本人认为最大最有意义的更新有2个。一个是7.9.0版本提供内了置的多线程规划,从而实现了规划过程中的多CPU同时对同一问题进行运算,大大地发挥了多CPU(核)服务器的并行运算能力。而今天本文需要详解的新增接口SolverManager则是在系统集成方面的另一次重大创新。SolverManager接口在7.32.0版本中发布。

规划服务的常见场景与异步服务

OptaPlanner的核心是一个运筹优化求解器,可以对各领域的规划问题(NPC, NP-Hard问题)进行规划求解,寻找出问题的近似最优解。OptaPlanner规划组件提供了相当完善的求解运算功能。但在实际的规划系统设计中,除了设计相应的规划模型,还需要考虑规划程序部署问题,便于与现有系统集成。这类部署问题并非OptaPlanner求解器自身的功能焦点。因此,对于我们软件开发、工程人员而言,还需要设计好相应的架构系统,才能实现规划程序与现有信息系统之间良好数据交互。

通常情况下规划运算需要使用大量的运算资源,也即CPU运算能力。我们会把基于OptaPlanner的规划程序部署成独立的规划服务,以接口方式与外界系统进行数据通讯。部署成独立的服务除了有利于降低系统模块间低耦合外,另一个重要原因是有利于运算资源的扩展。当问题规划增大时,程序所需的CPU运算能力也会大副提升;独立存在的规划服务更有利于硬件资源的更新。当然,需要在Client端进行即时规划的场景(例如手机导航软件)除外。

因为规划服务大多数情况下,需要一定的运算周期才能得到可行、且相对最优方案。若根据上述的场景需求,在常见的项目中,可以把规划程序做成一个轻量级的Jar包,再过Web和应用服务器,以Web服务的方式对外提供服务。例如使用Spring Boot进行封装,对外提供Web API服务。通过使Spring Boot的Controller与规划程序包在进程上相互独立,从而实现规划服务的异步性。当然也可以通过在Spring Boot程序中通过多线程方式实现异常调用的特性。不同的实现方法视实际需要而定。

SolverManager特性解决异步问题

对于上述场景,OptaPlanner是否可提供Out-Of-The-Box的解决方案呢?在7.32.0.Final版本之前,求解器规划问题时的接口方法是Solver.solve(),这个方法是同步的,需要规划完成后才能返回。若需要实现异步功能,就需要自己想办法实现了,例如上面提到的将服务进程与规划进程相互独立,或使用不同的线程来响应服务和启动规划,实现起来对软件架构设计需要有一定的经验才能做得相对完善。很幸运,在7.32.0.Final版本中,终于从OptaPlanner内置功能上实现了此特性,这个就是SolverManager。SolverManager是7.32.0.Final版本提供的新接口,通过此接口我们可以在调用规划核心程序进行问题求解时,调用线程即时返回,从而实现调用线程与规划线程异步执行。具体访求是:通过SolverManager.solve()方法可以启动一个异步规划方法,调用方可以即时返回,通过轮询的方式调用SolverManager的其它方法来查询规划状态(SolverManger.getSolverStatus)并获取结果(SoverJob.getFinalBestSolution)。SolverManager的基本用法如下:

CloudBalance problem1 = ...;
UUID problemId = UUID.randomUUID();
// Returns immediately
SolverJob<CloudBalance, UUID> solverJob = solverManager.solve(problemId, problem1);
...
CloudBalance solution1;
try {
// Returns only after solving terminates
solution1 = solverJob.getFinalBestSolution();
} catch (InterruptedException | ExecutionException e) {
throw ...;
}

可以看出,使用SolverManager 对一个问题进行求解时,与Solver对象的solve方法有以下区别:

  1. 异步执行,当solve方法被调用后,方法会马上返回,而不待引擎运行结果。调用者需要通过轮询或回调方法(bestSolutionChanged事件)获取运行结果。
  2. 每个问题对应一个ID,因为SolverManager会启动线程池同一时间对多个问题进行求解,因此每个问题需要有一个唯一的标识做识别,在下一篇文章中的SolverManger批量求解中将会详解。

因此,在7.32.0.Final版本中,SolverManager的出现,将会在进行求解服务的设计过程中,大大简化引擎与服务的设计复杂度。希望在未来的应用过让OptaPlanner在工业场景的可能性上更胜一筹。

关于SolverManager接口的详细介绍见以下使用说明:

https://docs.optaplanner.org/7.33.0.Final/optaplanner-docs/html_single/index.html#solverManager​docs.optaplanner.org

原创不易,如果觉得文章对你有帮助,欢迎点赞、评论。文章有疏漏之处,欢迎批评指正。

本系列文章在公众号不定时连载,请关注公众号(让APS成为可能)及时接收,二维码:

 http://weixin.qq.com/r/WjtFXSvE2HanrW8_925I (二维码自动识别)

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

OptaPlanner 7.32.0.Final版本彩蛋 - SolverManager之异步求解的更多相关文章

  1. OptaPlanner 7.32.0.Final版本彩蛋 - SolverManager之批量求解

    上一篇介绍了OptaPlanner 7.32.0.Final版本中的SolverManager接口可以实现异步求解功能.本篇将继续介绍SolverManager的另一大特性 - 批量求解. 适用场景 ...

  2. JBoss Wildfly (1) —— 7.2.0.Final编译

    JBoss Wildfly (1) -- 7.2.0.Final编译 wildfly版本: 7.2.0.Final-testsuite-fix jdk版本: jdk1.7.0_79 maven版本: ...

  3. Drools7.0.0.Final Unsupported major.minor version 52.0异常

    异常信息 在使用Drools7.0.0.Final版本进行开发过程中,出现以下异常: java.lang.UnsupportedClassVersionError: org/kie/api/KieSe ...

  4. Netty4.0.24.Final 版本中 IdleStateHandler 使用时的局限性

    使用Netty在客户端和服务端建立通讯通道,一般来说,一个连接可能很久没有访问,由于各种各样的网络问题导致连接已经失效,客户端再次发送请求时会产生连接异常. 基于这个原因,需要在客户端和服务端之间建立 ...

  5. PL/SQL Developer从11.0.6版本开始32/64为之区分

    PL/SQL Developer从11.0.6版本开始32/64为之区分 在PL/SQL Developer11.0.6版本之前,64位Windows操作系统在使用PL/SQL Developer都未 ...

  6. 40个超有趣的Linux命令行彩蛋和游戏

    40个有趣的Linux命令行彩蛋和游戏,让你假装成日理万机的黑客高手.附一键安装脚本,在树莓派和ubuntu云主机上亲测成功,有些还可以在Windows的DOS命令行中运行. 本文配套B站视频:40个 ...

  7. 淘宝首页源码藏美女彩蛋(上)(UED新作2013egg)

    今日,偶尔翻看淘宝源码,发现竟有美女形状源码.如下图: 此段代码在console中运行,结果更为惊叹. 亲手尝试的读者已经看到了代码运行的结果.taobao.com的console打印出了UED的招聘 ...

  8. druid 源码分析与学习(含详细监控设计思路的彩蛋)(转)

    原文路径:http://herman-liu76.iteye.com/blog/2308563  Druid是阿里巴巴公司的数据库连接池工具,昨天突然想学习一下阿里的druid源码,于是下载下来分析了 ...

  9. Android彩蛋效果,微信彩蛋效果

    根据Android源码修改,具有微信彩蛋效果 主要代码 public static class Board extends FrameLayout { public static final bool ...

随机推荐

  1. Android教程2020 - RecyclerView显示多种item

    Android教程2020 - 系列总览 本文链接 前面我们已经用RecyclerView显示一些数据.也知道如何获取滑动的距离. 前面我们的列表中显示的都是同类数据.如果要在一个列表中显示不同类别的 ...

  2. 单点登陆(SSO)

    一.背景 在企业发展初期,企业使用的系统很少,通常一个或者两个,每个系统都有自己的登录模块,运营人员每天用自己的账号登录,很方便.但随着企业的发展,用到的系统随之增多,运营人员在操作不同的系统时,需要 ...

  3. 1755: N相关孪生素数

    #include<stdio.h>int f(int n,int L,int R){ int ch[10000],i,j,count=0; j=1; for(i=L;i<=R;i++ ...

  4. 娱乐往事,年初捡到1G PAR,平淡的日子泛起波澜

    常听说这样的故事 垃圾佬捡到蓝牙键盘,于是配了一台上万的电脑 垃圾佬捡到机箱,于是配了一台带遥控的HTPC 垃圾佬捡到假NAS,于是组了20+T的RAID 而我,不是垃圾佬,更没有捡到过U盘,对突如其 ...

  5. django登录页面优化

    环境准备 1.python3.6 2.django2.0+ 3.bootstrap3 后台代码 #创建login_check视图函数,用来处理登录 def login_action(request): ...

  6. HDU_3183_RMQ

    http://acm.hdu.edu.cn/submit.php?pid=3183 初探rmq,这道题看了题解还是写了好久.原因是rmq处理字符串时没有自己写min函数,导致把返回的字符当成下标处理了 ...

  7. POJ_1166_暴搜

    题目描述: 有3*3的9个时钟,每个始终有0,1,2,3四种可以循环的状态码,每组数据给我们9个时钟的一种状态码.另外还有9种操作,分别使指定位置的时钟状态码加一,求使得9个时钟状态码全部置于0的最少 ...

  8. 12306 抢票系列之只要搞定RAIL_DEVICEID的来源,从此抢票不再掉线(上)

    郑重声明: 本文仅供学习使用,禁止用于非法用途,否则后果自负,如有侵权,烦请告知删除,谢谢合作! 开篇明义 本文针对自主开发的抢票脚本在抢票过程中常常遇到的请求无效等问题,简单分析了 12306 网站 ...

  9. Springboot笔记(二)整合

    1.整合Freemarker 一种模板引擎,前端渲染模板的,类似于EL,jsp,不过比前两个好用 导入很简单   pom.xml <dependency> <groupId>o ...

  10. python库之matplotlib学习---关于坐标轴

    首先定·定义x, y创建一个figure import numpy as np import matplotlib.pyplot as plt x = np.linspace(-1, 1, 10) y ...