Optaplanner影子变量腐败检查机制

时间:2018-06-13 07:57:33

标签: optaplanner

我在使用FULL_ASSERT构建启发式阶段时会出现分数损坏异常:

  

java.lang.IllegalStateException:VariableListener损坏:   实体(任务{6661-30})的影子变量(Task.plannedDateTime)' s   损坏的值(null)更改为未损坏的值(2018-06-04T07:00)   在没有更改的情况下触发所有VariableListener之后   真正的变数。也许是VariableListener类   (VrpTaskStartTimeListener)用于该影子变量   (Task.plannedDateTime)忘记在其中一个来源时更新它   在完成动作后更改(任务{6661-30} {Shift {Tech1:2018-06-04}    - >移{Tech1:2018年6月4日。}})

     

在   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:执行步骤移动(它还执行shadow var listeners)
  • 第2步:获取当前实体的影子变量值。(这里是影子变量 没有有效价值)
  • 第3步:执行ShadowsVariable listehttp://example.comners(现在 阴影将具有正确的值)
  • 第4步:获取新值并进行比较 与Step2。

现在,问题在于真正变量上的自定义侦听器,这是顺序:

  1. 反向关系阴影变量监听器
  2. 自定义侦听器
  3. 锚影变量
  4. 我可以做些什么来使上面的顺序使自定义侦听器最后执行?

1 个答案:

答案 0 :(得分:0)

正确配置@CustomShadowVariable的{​​{1}}属性。

有这样的保证: enter image description here