2016-04-11 87 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

感谢您的帮助现在一切都变得更有意义。 –