VariableListener损坏 [英] VariableListener corruption

查看:103
本文介绍了VariableListener损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在玩自定义阴影变量和自定义变量侦听器.我发现,考试时间表"示例使用自定义阴影变量来更改考试前"时的后续考试". 因此,我确实断言在此问题中提出的要求是真的自定义VariableListener更新了多个阴影变量我在以下Exam类中添加了第二个阴影变量,该变量引用变量"period",然后在LeadingExam计划实体(PeriodUpdatingVariableListener)的变量侦听器中更新了两个变量

I was playing around with the custom shadow variables and custom variable listeners. I found that the "Exam timetabling" example uses custom shadow variables to update "Following exams" when the "Leading Exam" changes. So what i did to assert asking in this question was true Custom VariableListener updating more than one shadow variables i added a second shadow variable in the Following Exam class which references the variable "period" , and then in the variable listener of the LeadingExam planning entity(PeriodUpdatingVariableListener) i update both the variables.

这是"FollowingExam"类的代码

Here is the code for the "FollowingExam" class

@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"中,我有下一个代码

And in the "PeriodUpdatingVariableListener" i have the next code

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来说,注册另一个影子变量似乎也没有问题,因为我在运行应用程序时收到此消息

It also seem like that there is no problem for OptaPlanner registering that this is another shadow variable because i get this message when i run the application

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时,它将运行而没有任何错误.

The error that i get is the next error , this error only appears when i change the environment mode to FULL_ASSERT ,but when it is left to the default REPRODUCIBLE it runs without any errors.

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)

推荐答案

在变量侦听器中的这段代码很糟糕:

This code in a variable listener is bad:

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

如果多次调用,则var也会更改,即使真正的var并未更改.如果在评分规则中使用了该变量,则对于同一解决方案,解决方案的评分并不总是相同的.

If its called multiple times, the var changes, even if the genuine var hasn't changed. If that var is used in score rules, the solution's score isn't always the same for the same solution.

影子变量是基于至少1个真实变量(直接或间接)的公式结果的缓存.例如,阴影C =真正的A +问题属性B.因此,如果B为10,范围A从1到5,则如果A为1,则C为11;如果A为2,则C为11,等等.

A shadow variable is the caching of the result of a formula based on at least 1 genuine variable (directly or indirectly). For example shadow C = genuine A + problem property B. So if B is 10 and ranges A from 1 to 5, then C will be 11 if A is 1, 12 if A is 2, etc.

这篇关于VariableListener损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆