我在使用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:"
}
}
以下是我认为的描述:
现在,问题在于真正变量上的自定义侦听器,这是顺序:
我可以做些什么来使上面的顺序使自定义侦听器最后执行?