【问题标题】:Optaplanner shadow variable corruption check mechanismOptaplanner 影子变量损坏检查机制
【发布时间】:2018-06-13 18:26:56
【问题描述】:

我在使用 FULL_ASSERT 的构造启发式阶段遇到分数损坏异常:

java.lang.IllegalStateException:VariableListener 损坏: 实体 (Task{6661-30}) 的影子变量 (Task.plannedDateTime) 的 损坏的值 (null) 更改为未损坏的值 (2018-06-04T07:00) 在所有 VariableListeners 都被触发而不改变 真正的变量。也许是 VariableListener 类 (VrpTaskStartTimeListener) 为那个影子变量 (Task.plannedDateTime) 当它的一个来源忘记更新它 完成操作后更改(任务{6661-30} {Shift{Tech1:2018-06-04} -> 转移{Tech1:2018-06-04}})。

在 org.optaplanner.core.impl.score.director.AbstractScoreDirector.assertShadowVariablesAreNotStale(AbstractScoreDirector.java:462) 在 org.optaplanner.core.impl.solver.scope.DefaultSolverScope.assertShadowVariablesAreNotStale(DefaultSolverScope.java:140) 在 org.optaplanner.core.impl.phase.scope.AbstractPhaseScope.assertShadowVariablesAreNotStale(AbstractPhaseScope.java:171) 在 org.optaplanner.core.impl.phase.AbstractPhase.predictWorkingStepScore(AbstractPhase.java:169) 在 org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.doStep(DefaultConstructionHeuristicPhase.java:108) 在 org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.solve(DefaultConstructionHeuristicPhase.java:95) 在 org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:87) 在 org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:173) 在...

现在在查看 DefaultConstructionHeuristicPhase.doStep 时,它确实:

private void doStep(ConstructionHeuristicStepScope<Solution_> stepScope) {
        Move<Solution_> nextStep = stepScope.getStep();
        nextStep.doMove(stepScope.getScoreDirector()); //Step-1
        predictWorkingStepScore(stepScope, nextStep);
        ...
    }

predictWorkingStepScore() 调用 AbstractScoreDirector.assertShadowVariablesAreNotStale()assertShadowVariablesAreNotStale() 是:

    public void assertShadowVariablesAreNotStale(Score expectedWorkingScore, Object completedAction) {
                SolutionDescriptor<Solution_> solutionDescriptor = getSolutionDescriptor();
    //Step2
                Map<Object, Map<ShadowVariableDescriptor, Object>> entityToShadowVariableValuesMap = new IdentityHashMap<>();
                ...
                    entityToShadowVariableValuesMap.put(entity, shadowVariableValuesMap);
                }
//Step3
                variableListenerSupport.triggerAllVariableListeners();
                for (Iterator<Object> it = solutionDescriptor.extractAllEntitiesIterator(workingSolution); it.hasNext();) {
                    Object entity = it.next();
                    EntityDescriptor<Solution_> entityDescriptor
                            = solutionDescriptor.findEntityDescriptorOrFail(entity.getClass());
                    Collection<ShadowVariableDescriptor<Solution_>> shadowVariableDescriptors = entityDescriptor.getShadowVariableDescriptors();
                    Map<ShadowVariableDescriptor, Object> shadowVariableValuesMap = entityToShadowVariableValuesMap.get(entity);
                    for (ShadowVariableDescriptor shadowVariableDescriptor : shadowVariableDescriptors) {
                        Object newValue = shadowVariableDescriptor.getValue(entity);
                        Object originalValue = shadowVariableValuesMap.get(shadowVariableDescriptor);
    //Step4
                        if (!Objects.equals(originalValue, newValue)) {
                            throw new IllegalStateException(VariableListener.class.getSimpleName() + " corruption:"

        }
        }

这是我相信的描述:

  • 第 1 步:执行 step 的 move(它还执行 shadow var listeners)
  • 第 2 步:获取当前实体 shadow vars 值。(此处为 shadow vars 不会有有效值)
  • 第三步:执行ShadowsVariable listehttp://example.comners(now 阴影将具有正确的值)
  • 第 4 步:获取新值并进行比较 与步骤 2。

现在,问题出在真正变量上的自定义侦听器上,顺序如下:

  1. 反向关系影子变量监听器
  2. 自定义监听器
  3. 锚阴影变量

我该怎么做才能使自定义侦听器最后执行?

【问题讨论】:

    标签: optaplanner


    【解决方案1】:

    正确配置@CustomShadowVariablesources属性。

    有这样的保证:

    【讨论】:

    • @Geffrey, IRSV,custom var, ASV 都监听同一个真正的变量。
    • 那么他们之间没有订单保证。要改变这一点,让其中一个也依赖于其他之一。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多