-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: Allow phase commands to read termination status (#1422)
- Loading branch information
Showing
24 changed files
with
375 additions
and
187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
core/src/main/java/ai/timefold/solver/core/api/solver/phase/PhaseCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package ai.timefold.solver.core.api.solver.phase; | ||
|
||
import java.util.function.BooleanSupplier; | ||
|
||
import ai.timefold.solver.core.api.domain.solution.PlanningSolution; | ||
import ai.timefold.solver.core.api.score.Score; | ||
import ai.timefold.solver.core.api.score.director.ScoreDirector; | ||
import ai.timefold.solver.core.api.solver.Solver; | ||
import ai.timefold.solver.core.api.solver.change.ProblemChange; | ||
import ai.timefold.solver.core.impl.phase.Phase; | ||
import ai.timefold.solver.core.impl.score.director.InnerScoreDirector; | ||
|
||
import org.jspecify.annotations.NullMarked; | ||
|
||
/** | ||
* Runs a custom algorithm as a {@link Phase} of the {@link Solver} that changes the planning variables. | ||
* To change problem facts, use {@link Solver#addProblemChange(ProblemChange)} instead. | ||
* <p> | ||
* To add custom properties, configure custom properties and add public setters for them. | ||
* | ||
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation | ||
*/ | ||
@NullMarked | ||
public interface PhaseCommand<Solution_> { | ||
|
||
/** | ||
* Changes {@link PlanningSolution working solution} of {@link ScoreDirector#getWorkingSolution()}. | ||
* When the {@link PlanningSolution working solution} is modified, | ||
* the {@link ScoreDirector} must be correctly notified | ||
* (through {@link ScoreDirector#beforeVariableChanged(Object, String)} and | ||
* {@link ScoreDirector#afterVariableChanged(Object, String)}), | ||
* otherwise calculated {@link Score}s will be corrupted. | ||
* <p> | ||
* Don't forget to call {@link ScoreDirector#triggerVariableListeners()} after each set of changes | ||
* (especially before every {@link InnerScoreDirector#calculateScore()} call) | ||
* to ensure all shadow variables are updated. | ||
* | ||
* @param scoreDirector the {@link ScoreDirector} that needs to get notified of the changes. | ||
* @param isPhaseTerminated long-running command implementations should check this periodically | ||
* and terminate early if it returns true. | ||
* Otherwise the terminations configured by the user will have no effect, | ||
* as the solver can only terminate itself when a command has ended. | ||
*/ | ||
void changeWorkingSolution(ScoreDirector<Solution_> scoreDirector, BooleanSupplier isPhaseTerminated); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 2 additions & 1 deletion
3
core/src/main/java/ai/timefold/solver/core/impl/phase/custom/CustomPhase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 14 additions & 27 deletions
41
core/src/main/java/ai/timefold/solver/core/impl/phase/custom/CustomPhaseCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,25 @@ | ||
package ai.timefold.solver.core.impl.phase.custom; | ||
|
||
import ai.timefold.solver.core.api.domain.solution.PlanningSolution; | ||
import ai.timefold.solver.core.api.score.Score; | ||
import java.util.function.BooleanSupplier; | ||
|
||
import ai.timefold.solver.core.api.score.director.ScoreDirector; | ||
import ai.timefold.solver.core.api.solver.ProblemFactChange; | ||
import ai.timefold.solver.core.api.solver.Solver; | ||
import ai.timefold.solver.core.impl.phase.Phase; | ||
import ai.timefold.solver.core.impl.score.director.InnerScoreDirector; | ||
import ai.timefold.solver.core.api.solver.phase.PhaseCommand; | ||
|
||
import org.jspecify.annotations.NullMarked; | ||
|
||
/** | ||
* Runs a custom algorithm as a {@link Phase} of the {@link Solver} that changes the planning variables. | ||
* Do not abuse to change the problems facts, | ||
* instead use {@link Solver#addProblemFactChange(ProblemFactChange)} for that. | ||
* <p> | ||
* To add custom properties, configure custom properties and add public setters for them. | ||
* | ||
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation | ||
* @deprecated Use {@link PhaseCommand} instead. | ||
*/ | ||
@FunctionalInterface | ||
public interface CustomPhaseCommand<Solution_> { | ||
@NullMarked | ||
@Deprecated(forRemoval = true, since = "1.20.0") | ||
public interface CustomPhaseCommand<Solution_> extends PhaseCommand<Solution_> { | ||
|
||
@Override | ||
default void changeWorkingSolution(ScoreDirector<Solution_> scoreDirector, BooleanSupplier isPhaseTerminated) { | ||
changeWorkingSolution(scoreDirector); | ||
} | ||
|
||
/** | ||
* Changes {@link PlanningSolution working solution} of {@link ScoreDirector#getWorkingSolution()}. | ||
* When the {@link PlanningSolution working solution} is modified, the {@link ScoreDirector} must be correctly notified | ||
* (through {@link ScoreDirector#beforeVariableChanged(Object, String)} and | ||
* {@link ScoreDirector#afterVariableChanged(Object, String)}), | ||
* otherwise calculated {@link Score}s will be corrupted. | ||
* <p> | ||
* Don't forget to call {@link ScoreDirector#triggerVariableListeners()} after each set of changes | ||
* (especially before every {@link InnerScoreDirector#calculateScore()} call) | ||
* to ensure all shadow variables are updated. | ||
* | ||
* @param scoreDirector never null, the {@link ScoreDirector} that needs to get notified of the changes. | ||
*/ | ||
void changeWorkingSolution(ScoreDirector<Solution_> scoreDirector); | ||
|
||
} |
Oops, something went wrong.