2020import ai .timefold .solver .core .impl .localsearch .decider .LocalSearchDecider ;
2121import ai .timefold .solver .core .impl .localsearch .scope .LocalSearchPhaseScope ;
2222import ai .timefold .solver .core .impl .localsearch .scope .LocalSearchStepScope ;
23+ import ai .timefold .solver .core .impl .move .director .MoveDirector ;
2324import ai .timefold .solver .core .impl .score .director .InnerScoreDirector ;
2425import ai .timefold .solver .core .impl .score .director .InnerScoreDirectorFactory ;
2526import ai .timefold .solver .core .impl .solver .DefaultSolver ;
@@ -35,6 +36,7 @@ abstract class AbstractProblem<Solution_> implements Problem {
3536 private final InnerScoreDirectorFactory <Solution_ , ?> scoreDirectorFactory ;
3637 private final Solution_ originalSolution ;
3738
39+ private MoveDirector <Solution_ > moveDirector ;
3840 private InnerScoreDirector <Solution_ , ?> scoreDirector ;
3941 private MoveSelector <Solution_ > moveSelector ;
4042 private Iterator <Move <Solution_ >> moveIterator ;
@@ -104,6 +106,7 @@ public final void setupIteration() {
104106 scoreDirector .setWorkingSolution (scoreDirector .cloneSolution (originalSolution )); // Use fresh solution again.
105107 scoreDirector .triggerVariableListeners ();
106108 scoreDirector .calculateScore ();
109+ moveDirector = new MoveDirector <>(scoreDirector );
107110 // Prepare the lifecycle.
108111 var solverScope = new SolverScope <Solution_ >();
109112 solverScope .setScoreDirector (scoreDirector );
@@ -146,10 +149,14 @@ public final void setupInvocation() {
146149 */
147150 @ Override
148151 public final Object runInvocation () {
152+ var scoreDirector = (InnerScoreDirector <Solution_ , ?>) moveDirector .getScoreDirector ();
149153 if (willUndo ) {
150- move = move .doMove (scoreDirector ); // Do the move and prepare undo.
154+ try (var ephemeralMoveDirector = moveDirector .ephemeral ()) {
155+ move .doMoveOnly (ephemeralMoveDirector .getScoreDirector ());
156+ }
157+ } else {
158+ move .doMoveOnly (scoreDirector ); // Do the move without any undo.
151159 }
152- move .doMoveOnly (scoreDirector ); // Run either the original move, or the undo.
153160 return scoreDirector .calculateScore ();
154161 }
155162
0 commit comments