Optaplanner:如何在 Quarkus 中获取求解器实例

Optaplanner: How to get solver instance in Quarkus

我正在使用 Quarkus optaplanner,所以我没有使用 SolverFactory 来构建求解器,而是使用 Quarkus 的方式注入 solverManager 然后让它解决问题:

val solverJob: SolverJob<SolarDesign, UUID> = solverManager.solve(problemId, problem) 

但我仍然希望能够像这样添加 EventListener:

solver.addEventListener(SolverEventListener<SolarDesign>() {
            fun bestSolutionChanged(event: BestSolutionChangedEvent<MyProblem>) {
                val solution = event.getNewBestSolution()
                if (solution.score.isFeasible()) {
                    println("found new best solution")
                    println(solution)
                }
            }
        })

问题是如何在 Quarkus optaplanner 中获取求解器实例,以便将其用于 addEventListener?它似乎无法从 solverManager 中实现。

谢谢

是的,SolverManager 是可能的,您不需要获得 Solver 实例。

使用SolverManager.solverAndListen(problemId, problemFinder, bestSolutionConsumer)。第三个参数是消费者,您可以在其中使用找到的每个最佳解决方案做任何您想做的事情。在你的情况下它可能看起来像这样:

fun solve() {
    val solverJob: SolverJob<SolarDesign, UUID> = solverManager
        .solveAndListen(problemId, { problemId -> problem }, this::printSolution)
}

fun printSolution(solution: SolarDesign) {
    if (solution.score.isFeasible()) {
        println("found new best solution")
        println(solution)
    }
}

在此 section 中查找有关 SolverManager 的更多详细信息。

下面的例子展示了如何在Quarkus中获取一个Solver实例。 SolverManager API 不包含此选项,因此替代方法是注入 SolverFactory,使用它来构建 Solver 实例并自行管理其生命周期。

该示例还展示了如何访问 Phase 生命周期。它可以用于开发过程中的实验。但是,这只能通过将求解器实例转换为 DefaultSolver,这是一个内部 API。内部 类 没有向后兼容性保证。如果您在代码中使用它们,它们可能会在未来的次要版本中发生重大变化并导致编译错误。 不要在生产中使用它。

class MySolverResource(private val solverFactory: SolverFactory<SolarDesign>) {

  fun solve(problemId : UUID) {
    // WARNING: DefaultSolver is OptaPlanner's internal class.
    // Backward compatibility is not guaranteed.
    // Its usage is totally not recommended.
    val solver: DefaultSolver<SolarDesign> = solverFactory.buildSolver() as DefaultSolver<SolarDesign>
    solver.addPhaseLifecycleListener(object : PhaseLifecycleListenerAdapter<SolarDesign>() {
      override fun stepEnded(stepScope: AbstractStepScope<SolarDesign>) {
        printSolution(stepScope.createOrGetClonedSolution())
      }
    })
    solver.solve(loadProblem(problemId))
  }

  fun printSolution(solution: SolarDesign) {}
}