【问题标题】:OptaPlanner Solution's score not matches the score given by `ScoreManager::explainScore`OptaPlanner 解决方案的分数与 `ScoreManager::explainScore` 给出的分数不匹配
【发布时间】:2021-03-18 17:54:00
【问题描述】:

说实话,我有一个复杂的模型,而且我的 OptaPlanner 模型中可能存在错误。

我不确定以下是否可能和正常,或者我的映射中某处存在错误,我应该根据我的实体创建一个 MCVE。

TLDR:

我的项目中某处有以下 Kotlin 代码:

        val solverJob = solverManager.solveAndListen(problem.id, problemMap::get) {
            val hardScore = it.score!!.hardScore
            if (scoreManager.explainScore(it).score.hardScore != hardScore) {
                throw IllegalStateException()
            }
            onBetterSolutionFoundCallback(mapSolutionToFrontendObject(it))
        }

这很简单,它会给 OptaPlanner 带来问题,并在找到更好的解决方案时调用回调。这里的诀窍是它会仔细检查解决方案是否可行。

Aaaaand,有时会抛出 IllegalStateExceptionscoreManager.explainScore(it).score 报告存在一个硬约束违规,而solution.score 表示没有硬约束违规。

棘手的部分是solution.score 在调用scoreManager.explainScore 方法后更新。

我查看了解决方案,ScoreManager 是正确的:解决方案中有一个硬约束违规。但一切都报告说,在我调用 scoreManager.explainScore 方法之前,这是一个可行的解决方案。

在我的案例中,OptaPlanner 在引发此异常之前找到了 2 个正确的解决方案,因此存在可行的解决方案,但 OptaPlanner 将它们替换为不可行的解决方案。

这是正确的行为吗?

或者我的领域模型有什么错误?

或者是 OptaPlanner 中的一个 bug,我应该基于此创建一个 bugreport?

我正在使用 Quarkus 1.11.1.Final 和 OptaPlanner 8.1.0.Final。

谢谢,

【问题讨论】:

    标签: optaplanner constraint-programming


    【解决方案1】:

    暂时将其添加到您的 application.properties 中以更快地失败,并提供更清晰的错误消息指出原因:

    # To detect common bugs in your code
    quarkus.optaplanner.solver.environment-mode=FULL_ASSERT
    

    给它更多时间,因为 FULL_ASSERT 会严重减慢速度。请参阅 optaplanner 文档“环境模式”部分以了解它的作用。

    【讨论】:

    • 嗨@Geoffrey,我在XML中有以下solverConfig:pastebin.com/8qQ7Jdm2,据我所知,它将envMode设置为FULL_ASSERT,但在这种情况下也会发生分数不匹配。我正在尝试使用以下 2 个插件修改 VRP:车辆需要有 1 个或 2 个驱动程序;一段时间后车辆需要返回车库。
    • 检查您的信息日志 - 它将说明 FULL_ASSERT 是否处于活动状态。那么如果你让它在 FULL_ASSERT 开启的情况下解决很长时间就会引发异常?
    • 好的,谢谢,FULL_ASSERT 不是从 XML 配置中读取的,我还需要将它添加到 application.propertes 文件中。谢谢,我让它运行一段时间,我会回来的。
    • 感谢@Geoffrey,抛出此异常:pastebin.com/v3hpanjV。因此,据我了解,我的约束条件不好,我会检查它们。不过有一个问题:我有一个 CHAINED PlanningVariable(名为 previousTask)。检查此previousTask 变量上的多个步骤back 是否正确?因此,如果我想在 Task 和约束中的 previousTask.previousTask.previousTask 之间进行惩罚?
    猜你喜欢
    • 2022-07-22
    • 2014-12-20
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多