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) {}
}
我正在使用 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) {}
}