2016-04-11 26 views
2

我正在閱讀關於陰影變量和自定義變量偵聽器的文檔,我想知道我是否正確理解它們的工作方式。自定義VariableListener更新多個陰影變量

從OptaPlanner文檔複製到第4.3.6.4節。 「自定義VariableListener」

如果一個VariableListener改變2個陰影變量(因爲具有 兩個單獨VariableListeners將是低效的),則註釋 僅與variableListenerClass第一陰影可變和讓 其它陰影變量(一個或多個當真正的規劃變量被改變,我們需要更多的陰影變量

@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; 
} 

和真正的策劃實體

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) { 

} 



} 

如果這也不行那該怎麼正確更新從陰影規劃實體上所有的陰影變量的VariableListener的代碼? 應該像這樣調用shadow變量的beforeVariableChanged和afterVariableChanged方法嗎?

+1

使用自定義陰影變量時,如果您還沒有使用optaplanner'6.3.0.Final'或更高版本。在舊版本中,它們會混亂觸發(這對某些用例而言是一種開發難題)。在6.3和更高版本中,它們以合理,可預測的順序觸發。 –

+0

是的,我讀過關於這個問題,我正在使用最新版本的OptaPlanner。但是這隻適用於鏈接變量,還是適用於非鏈接變量? –

+1

適用於所有影子變形。 –

回答

2

是的,這似乎一見鍾情。例如,看看ArrivalTimeUpdatingVariableListener就是一個很好的例子,說明在VRP鏈中更改1個客戶如何影響該客戶之後的所有其他客戶的到達時間。