【问题标题】:OptaPlanner - Explain score of non-optimal solutionsOptaPlanner - 解释非最优解决方案的分数
【发布时间】:2022-07-22 21:02:28
【问题描述】:

我们有一个用例,我们希望向用户展示一些人类可读的消息,说明为什么根据约束的分数拒绝“分配”。

例如在 3 台计算机 (Computer-1,2,3) 和 1 个进程 (Process-1) 的 CloudBalancing 问题中,我们最终得到以下结果:

Computer-1 打破了硬约束(requiredCpu)

Computer-2 由于软约束(最小成本)而丢失

Computer-3 分配给 Process-1 -->(最优解)

我们已经实现了 BestSolutionChanged 监听器,我们使用 solution.explainScore() 来获取一些信息并启用调试日志记录,它为我们提供了 OptaPlanner 内部日志以用于中间移动及其分数。但要求是提供一些自定义的人类可读信息,说明为什么所有非最优解决方案(Computer-1、Computer-2)即使不可行也被拒绝(基本上解释了这两种解决方案的得分)。

所以想知道我们如何实现上述目标?

  • 我们不想依赖收听 BestSolutionChanged 事件作为 如果 LS/CH 可能不会触发其他解决方案 阶段从已经是“最佳解决方案”的解决方案开始 (计算机 3)。这是一个有效的假设吗?
  • DEBUG 日志确实为我们提供了 信息,但似乎没有从此日志构建自定义消息 就像一个好主意,所以想知道是否还有另一个 可用于实现此目的的侦听器/OptaPlanner 概念。

【问题讨论】:

    标签: optaplanner


    【解决方案1】:

    您所说的“所有非最佳解决方案”是指特定的非最佳解决方案吗?搜索空间会很快变得非常大,OptaPlanner 本身可能不会评估大多数解决方案(仅仅是因为搜索空间太大)。

    如果提供给 Solver 的问题/解决方案已经是最佳解决方案(因为根据定义,没有比它更好的解决方案),BestSolutionChanged 事件将不会再次触发,这是正确的。

    特别感兴趣的是ScoreManager,它允许您计算和解释任何问题/解决方案的分数:

    (示例取自https://www.optaplanner.org/docs/optaplanner/latest/score-calculation/score-calculation.html#usingScoreCalculationOutsideTheSolver

    要创建它并获取ScoreExplanation,请执行以下操作:

    ScoreManager<CloudBalance, HardSoftScore> scoreManager = ScoreManager.create(solverFactory);
    ScoreExplanation<CloudBalance, HardSoftScore> scoreExplanation = scoreManager.explainScore(cloudBalance);
    

    cloudBalance 是您要解释的问题/解决方案。随着 分数说明你可以:

    获取分数

    HardSoftScore score = scoreExplanation.getScore();
    

    按约束分解分数

    Collection<ConstraintMatchTotal<HardSoftScore>> constraintMatchTotals = scoreExplanation.getConstraintMatchTotalMap().values();
    for (ConstraintMatchTotal<HardSoftScore> constraintMatchTotal : constraintMatchTotals) {
        String constraintName = constraintMatchTotal.getConstraintName();
        // The score impact of that constraint
        HardSoftScore totalScore = constraintMatchTotal.getScore();
    
        for (ConstraintMatch<HardSoftScore> constraintMatch : constraintMatchTotal.getConstraintMatchSet()) {
            List<Object> justificationList = constraintMatch.getJustificationList();
            HardSoftScore score = constraintMatch.getScore();
            ...
        }
    }
    

    并获得单个实体和问题事实的影响:

    Map<Object, Indictment<HardSoftScore>> indictmentMap = scoreExplanation.getIndictmentMap();
    for (CloudProcess process : cloudBalance.getProcessList()) {
        Indictment<HardSoftScore> indictment = indictmentMap.get(process);
        if (indictment == null) {
            continue;
        }
        // The score impact of that planning entity
        HardSoftScore totalScore = indictment.getScore();
    
        for (ConstraintMatch<HardSoftScore> constraintMatch : indictment.getConstraintMatchSet()) {
            String constraintName = constraintMatch.getConstraintName();
            HardSoftScore score = constraintMatch.getScore();
            ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2011-03-31
      • 2021-11-02
      相关资源
      最近更新 更多