Search code examples
javaoptaplannertimefold

Create an initial solution with right shadow variables and score


I'm trying to add a hand-made solution to OptaPlanner in Java code. I'm following the first way from this.

According the comments, I should somehow use ScoreDirector.triggerVariableListeners() to initialize shadow variables.

I've found in OptaPlanner examples code like this:

private <Result_> Result_ applyScoreDirector(Function<InnerScoreDirector<Solution_, Score_>, Result_> function) {
    try (InnerScoreDirector<Solution_, Score_> scoreDirector =
            (InnerScoreDirector<Solution_, Score_>) solverFactory.getScoreDirectorFactory().buildScoreDirector(true,
                    true)) {
        scoreDirector.setWorkingSolution(getSolution());
        Result_ result = function.apply(scoreDirector);
        scoreDirector.triggerVariableListeners();
        scoreDirector.calculateScore();
        setSolution(scoreDirector.getWorkingSolution());
        return result;
    }
}

I've tried to adapt it to my case (Table - my planning solution):

SolverConfig solverConfig = SolverConfig.createFromXmlFile(new File(url.getFile()));
solverManager = SolverManager.create(solverConfig, new SolverManagerConfig());
Table result = createInitialSolution(data);
DefaultSolverManager defaultSolverManager = (DefaultSolverManager) solverManager;
DefaultSolverFactory<Table> solverFactory = (DefaultSolverFactory<Table>) defaultSolverManager.getSolverFactory();
InnerScoreDirector<Table, HardSoftScore>  scoreDirector = (InnerScoreDirector<Table, HardSoftScore>) 
        solverFactory.getScoreDirectorFactory().buildScoreDirector(true, true);      
scoreDirector.setWorkingSolution(result);
scoreDirector.triggerVariableListeners();
scoreDirector.calculateScore();
result = scoreDirector.getWorkingSolution();
return result;

This doesn't work. All shadow variables are null. What am I doing wrong?


Solution

  • SolutionManager provides an update(...) method which serves just this purpose.

    In OptaPlanner, there is a bug in that call which makes it not work with chained and list variables. Timefold Solver fixes that bug, among others.