自定义 VariableListener 更新多个影子变量

Custom VariableListener updating more than one shadow variables

我正在阅读有关影子变量和自定义变量侦听器的文档,我想知道我是否在正确的轨道上理解它们的工作原理。

从 4.3.6.4 节的 OptaPlanner 文档中复制。 "Custom VariableListener"

If one VariableListener changes two shadow variables (because having two separate VariableListeners would be inefficient), then annotate only the first shadow variable with the variableListenerClass and let the other shadow variable(s) reference the first shadow variable:

@PlanningVariable(...)
public Standstill getPreviousStandstill() {
    return previousStandstill;
}

@CustomShadowVariable(variableListenerClass = TransportTimeAndCapacityUpdatingVariableListener.class,
        sources = {@CustomShadowVariable.Source(variableName = "previousStandstill")})
public Integer getTransportTime() {
    return transportTime;
}

@CustomShadowVariable(variableListenerRef = @PlanningVariableReference(variableName = "transportTime"))
public Integer getCapacity() {
    return capacity;
}

据我所知,当真正的规划变量发生变化时,我们有更多的影子变量需要相应地在另一个规划实体中更新,我们可以在真正的规划实体的同一个变量侦听器中执行此操作。

如果是这样,那么这样的事情是否有效?

这里是影子规划实体中影子变量的注释方法。

//shadow variables
protected Integer variable;
protected Integer shadowVariable2;

@CustomShadowVariable(variableListenerClass = CustomVariableListener.class,
    sources = {@CustomShadowVariable.Source(variableName = "variable")})
public Integer getVariable() {
return variable;
}

@CustomShadowVariable(variableListenerRef =     @PlanningVariableReference(variableName = "variable"))
public Integer getShadowVariable2() {
return shadowVariable2;
}

以及正版规划实体的VariableListener的代码

public class CustomVariableListener implements VariableListener<GenuinePlanningEntity> {

@Override
public void afterEntityAdded(ScoreDirector scoreDirector, GenuinePlanningEntity genuinePlanningEntity) {

}

@Override
public void afterEntityRemoved(ScoreDirector scoreDirector, GenuinePlanningEntity genuinePlanningEntity) {

}

@Override
public void afterVariableChanged(ScoreDirector scoreDirector, GenuinePlanningEntity genuinePlanningEntity) {
    List<ShadowPlanningEntity> shadowPlanningEntities = genuinePlanningEntity.getShadowPlanningEntities();
    Integer variable = genuinePlanningEntity.getVariable();
    for(ShadowPlanningEntity shadowPlanningEntity : shadowPlanningEntities){
        scoreDirector.beforeVariableChanged(shadowPlanningEntity,"variable");
        shadowPlanningEntity.setVariable(variable);
        scoreDirector.afterVariableChanged(shadowPlanningEntity,"variable");

        scoreDirector.beforeVariableChanged(shadowPlanningEntity,"shadowVariable2");
        shadowPlanningEntity.setshadowVariable2(shadowPlanningEntity.getshadowVariable2() + 1);
        scoreDirector.afterVariableChanged(shadowPlanningEntity,"shadowVariable2");

    }

}

@Override
public void beforeEntityAdded(ScoreDirector scoreDirector, GenuinePlanningEntity genuinePlanningEntity) {

}

@Override
public void beforeEntityRemoved(ScoreDirector scoreDirector, GenuinePlanningEntity genuinePlanningEntity) {

}

@Override
public void beforeVariableChanged(ScoreDirector scoreDirector, GenuinePlanningEntity genuinePlanningEntity) {

}



}

如果不行,那么如何正确更新影子规划实体中的所有影子变量? 影子变量的beforeVariableChanged和afterVariableChanged方法应该这样调用吗?

是的,乍一看还不错。查看示例 ArrivalTimeUpdatingVariableListener,了解更改 VRP 链中的 1 个客户如何影响该客户之后链中所有其他客户的到达时间的一个很好的例子。