搜索

第 9 章 OptaPlanner SolverManager

download PDF

Solver Manager 是一个或多个 Solver 实例的常见问题,旨在简化 REST 和其他企业服务中的规划问题。

Solver.solve (…​) 方法不同,S olverManager 具有以下特征:

  • SolverManager.solve(…​) 立即返回:它会调度一个问题,以便在不阻止调用线程的情况下进行异步解决。这可避免 HTTP 和其他技术的超时问题。
  • SolverManager.solve(…​) 可并行解决同一域的多个规划问题。

在内部,SolverManager 管理了一个临时解决方案程序线程的线程池,它调用 Solver.solve(…​),以及处理最佳解决方案更改事件的线程池。

在 Quarkus 和 Spring Boot 中,SolverManager 实例会在您的代码中自动注入。如果您使用 Quarkus 或 Spring Boot 以外的平台,请使用 create(…​) 方法构建 SolverManager 实例:

SolverConfig solverConfig = SolverConfig.createFromXmlResource(".../cloudBalancingSolverConfig.xml");
SolverManager<CloudBalance, UUID> solverManager = SolverManager.create(solverConfig, new SolverManagerConfig());

提交至 Solv erManager.solve(…​)方法的 每个问题都必须有唯一的问题 ID。之后调用 getSolverStatus(problemId) 或终止Early(problemId) 使用问题 ID 来区分规划问题。问题 ID 必须是一个不可变的类,如 LongStringjava.util.UUID

SolverManagerConfig 类有一个 parallelSolverCount 属性,用于控制并行运行了多少 solvers。例如,如果 parallelSolverCount 属性被设置为 4,您提交了五个问题,则四个问题开始立即解决,在第一个问题之一结束时启动第五个问题。如果这些问题每五分钟解决,则第五个问题需要 10 分钟完成。默认情况下,parallelSolverCount 设置为 AUTO,它解析为 CPU 内核的一半,无论解决者的 moveThreadCount 是什么。

要获得最佳解决方案,在解决终止后通常会使用 SolverJob.getFinalBestSolution()

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 实施在一个计算机节点上运行,但未来的工作旨在跨云分发解决方法。

9.1. 批量解决问题

批量解决问题正在并行解决多个数据集。批量解决问题尤其有用:

  • 夜之间通常没有问题变化,或者没有问题变化。例如,某些组织强制执行截止时间,在 午夜前提交所有关闭请求
  • 解决者会运行时间更长的时间,因为 nobody 正在等待结果,而 CPU 资源通常更便宜。
  • 当员工到达下一工作日时,可以使用解决方案。

流程

为批量解决并行解决的问题,通过 parallelSolverCount 限制,每个数据集的 address (…​) 被调用:

public class TimeTableService {

    private SolverManager<TimeTable, Long> solverManager;

    // Returns immediately, call it for every data set
    public void solveBatch(Long timeTableId) {
        solverManager.solve(timeTableId,
                // Called once, when solving starts
                this::findById,
                // Called once, when solving ends
                this::save);
    }

    public TimeTable findById(Long timeTableId) {...}

    public void save(TimeTable timeTable) {...}

}
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.