2016-04-11 136 views
1

我在玩弄自定義影子變量和自定義變量偵聽器。我發現「考試時間表」示例使用自定義影子變量在「Leading Exam」更改時更新「以下考試」。 因此,我所做斷言在問這個問題是真的Custom VariableListener updating more than one shadow variables我加入以下考試類引用變量「期間」第二個影子變量,然後在LeadingExam規劃實體(PeriodUpdatingVariableListener)的可變監聽我同時更新變量。VariableListener損壞

下面是「FollowingExam」類的代碼

@PlanningEntity 
@XStreamAlias("FollowingExam") 
public class FollowingExam extends Exam { 

protected LeadingExam leadingExam; 

// Shadow variables 
protected Period period; 
protected Integer var; 

@CustomShadowVariable(variableListenerClass = PeriodUpdatingVariableListener.class, sources = { 
     @CustomShadowVariable.Source(entityClass = LeadingExam.class, variableName = "period") }) 
public Period getPeriod() { 
    return period; 
} 

public void setPeriod(Period period) { 
    this.period = period; 
} 

@CustomShadowVariable(variableListenerRef = @PlanningVariableReference(variableName = "period")) 
public Integer getVar() { 
    return var; 
} 

public void setVar(Integer var) { 
    this.var = var; 
} 

public LeadingExam getLeadingExam() { 
    return leadingExam; 
} 

public void setLeadingExam(LeadingExam leadingExam) { 
    this.leadingExam = leadingExam; 
} 

} 

並在「PeriodUpdatingVariableListener」我有一個代碼

public class PeriodUpdatingVariableListener implements VariableListener<LeadingExam> { 

public void beforeEntityAdded(ScoreDirector scoreDirector, LeadingExam leadingExam) { 
    // Do nothing 
} 

public void afterEntityAdded(ScoreDirector scoreDirector, LeadingExam leadingExam) { 
    updatePeriod(scoreDirector, leadingExam); 
} 

public void beforeVariableChanged(ScoreDirector scoreDirector, LeadingExam leadingExam) { 
    // Do nothing 
} 

public void afterVariableChanged(ScoreDirector scoreDirector, LeadingExam leadingExam) { 
    updatePeriod(scoreDirector, leadingExam); 
} 

public void beforeEntityRemoved(ScoreDirector scoreDirector, LeadingExam leadingExam) { 
    // Do nothing 
} 

public void afterEntityRemoved(ScoreDirector scoreDirector, LeadingExam leadingExam) { 
    // Do nothing 
} 

protected void updatePeriod(ScoreDirector scoreDirector, LeadingExam leadingExam) { 
    Period period = leadingExam.getPeriod(); 
    for (FollowingExam followingExam : leadingExam.getFollowingExamList()) { 
     scoreDirector.beforeVariableChanged(followingExam, "period"); 
     followingExam.setPeriod(period); 
     scoreDirector.afterVariableChanged(followingExam, "period"); 

     //additional lines of code to update the "var" variable 
     Integer var = followingExam.getVar(); 
     if(var == null){ 
      var = new Integer(1); 
     } 
     else var++; 
     scoreDirector.beforeVariableChanged(followingExam, "var"); 
     followingExam.setVar(var); 
     scoreDirector.afterVariableChanged(followingExam, "var"); 

    } 
} 

} 

它也似乎沒有用於OptaPlanner沒問題註冊,這是另一個影子可變的,因爲當我運行應用程序

2016-04-11 15:26:15,309 [AWT-EventQueue-0] TRACE  Model annotations parsed for Solution Examination: 
2016-04-11 15:26:15,309 [AWT-EventQueue-0] TRACE   Entity Exam: 
2016-04-11 15:26:15,309 [AWT-EventQueue-0] TRACE    Variable room (genuine) 
2016-04-11 15:26:15,309 [AWT-EventQueue-0] TRACE   Entity LeadingExam: 
2016-04-11 15:26:15,309 [AWT-EventQueue-0] TRACE    Variable period (genuine) 
2016-04-11 15:26:15,309 [AWT-EventQueue-0] TRACE   Entity FollowingExam: 
2016-04-11 15:26:15,309 [AWT-EventQueue-0] TRACE    Variable period (shadow) 
2016-04-11 15:26:15,309 [AWT-EventQueue-0] TRACE    Variable var (shadow) 
我得到這個消息

我得到的錯誤是下一個錯誤,只有當我將環境模式更改爲FULL_ASSERT時纔會出現此錯誤,但是當它保留爲默認的REPRODUCIBLE時,它將運行而不會出現任何錯誤。

Caused by: java.lang.IllegalStateException: VariableListener corruption: the entity (426)'s shadow variable (FollowingExam.var)'s corrupted value (null) changed to uncorrupted value (1) after all VariableListeners were triggered without changes to the genuine variables. 
Probably the VariableListener class for that shadow variable (FollowingExam.var) forgot to update it when one of its sources changed after completedAction (Initial score calculated). 
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.assertShadowVariablesAreNotStale(AbstractScoreDirector.java:349) 
at org.optaplanner.core.impl.solver.recaller.BestSolutionRecaller.solvingStarted(BestSolutionRecaller.java:84) 
at org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:196) 
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:175) 
at org.optaplanner.examples.common.business.SolutionBusiness.solve(SolutionBusiness.java:307) 
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$SolveWorker.doInBackground(SolverAndPersistenceFrame.java:287) 
at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$SolveWorker.doInBackground(SolverAndPersistenceFrame.java:1) 
at javax.swing.SwingWorker$1.call(Unknown Source) 
at java.util.concurrent.FutureTask.run(Unknown Source) 
at javax.swing.SwingWorker.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

回答

2

這段代碼在一個變量監聽器是壞:

Integer var = followingExam.getVar(); 
    ... 
    var++; 
    ... 
    followingExam.setVar(var); 
    ... 

如果多次調用,該變種的變化,即使真正的變種並沒有改變。如果該分數用於分數規則,則解決方案的分數對於相同的解決方案並不總是相同的。

陰影變量是一個公式的結果的高速緩存基於至少1真正變量(直接或間接)。例如影子C =真A +問題屬性B.因此,如果B爲10和範圍A爲1〜5,則C將是11,如果A是1,12,如果A是2,等等。

+0

感謝您的幫助現在一切都變得更有意義。 –