Skip to content

Commit 21dc302

Browse files
committed
feat: prepare for multithread implementation
1 parent 1f3302d commit 21dc302

33 files changed

Lines changed: 1000 additions & 925 deletions

core/src/main/java/ai/timefold/solver/core/config/evolutionaryalgorithm/EvolutionaryWorkerConfig.java renamed to core/src/main/java/ai/timefold/solver/core/config/evolutionaryalgorithm/EvolutionaryAgentConfig.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"localSearchConfig",
1616
})
1717
@NullMarked
18-
public class EvolutionaryWorkerConfig extends PhaseConfig<EvolutionaryWorkerConfig> {
18+
public class EvolutionaryAgentConfig extends PhaseConfig<EvolutionaryAgentConfig> {
1919

2020
@Nullable
2121
private EvolutionaryIndividualGeneratorConfig individualGeneratorConfig = null;
@@ -47,19 +47,19 @@ public void setLocalSearchConfig(@Nullable EvolutionaryLocalSearchConfig localSe
4747
// With methods
4848
// ************************************************************************
4949

50-
public EvolutionaryWorkerConfig
50+
public EvolutionaryAgentConfig
5151
withIndividualGeneratorConfig(EvolutionaryIndividualGeneratorConfig individualGeneratorConfig) {
5252
setIndividualGeneratorConfig(individualGeneratorConfig);
5353
return this;
5454
}
5555

56-
public EvolutionaryWorkerConfig withLocalSearchConfig(EvolutionaryLocalSearchConfig localSearchConfig) {
56+
public EvolutionaryAgentConfig withLocalSearchConfig(EvolutionaryLocalSearchConfig localSearchConfig) {
5757
setLocalSearchConfig(localSearchConfig);
5858
return this;
5959
}
6060

6161
@Override
62-
public EvolutionaryWorkerConfig inherit(EvolutionaryWorkerConfig inheritedConfig) {
62+
public EvolutionaryAgentConfig inherit(EvolutionaryAgentConfig inheritedConfig) {
6363
super.inherit(inheritedConfig);
6464
individualGeneratorConfig =
6565
ConfigUtils.inheritConfig(individualGeneratorConfig, inheritedConfig.getIndividualGeneratorConfig());
@@ -68,8 +68,8 @@ public EvolutionaryWorkerConfig inherit(EvolutionaryWorkerConfig inheritedConfig
6868
}
6969

7070
@Override
71-
public EvolutionaryWorkerConfig copyConfig() {
72-
return new EvolutionaryWorkerConfig().inherit(this);
71+
public EvolutionaryAgentConfig copyConfig() {
72+
return new EvolutionaryAgentConfig().inherit(this);
7373
}
7474

7575
@Override

core/src/main/java/ai/timefold/solver/core/config/evolutionaryalgorithm/EvolutionaryAlgorithmPhaseConfig.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212

1313
@XmlType(propOrder = {
1414
"complexProblem",
15+
"agentCount",
1516
"populationConfig",
16-
"workerConfig",
17+
"evolutionaryAgentConfig",
1718
})
1819
@NullMarked
1920
public class EvolutionaryAlgorithmPhaseConfig extends PhaseConfig<EvolutionaryAlgorithmPhaseConfig> {
@@ -23,11 +24,14 @@ public class EvolutionaryAlgorithmPhaseConfig extends PhaseConfig<EvolutionaryAl
2324
@Nullable
2425
private Boolean complexProblem;
2526

27+
@Nullable
28+
private Integer agentCount;
29+
2630
@Nullable
2731
private EvolutionaryPopulationConfig populationConfig = null;
2832

2933
@Nullable
30-
private EvolutionaryWorkerConfig workerConfig = null;
34+
private EvolutionaryAgentConfig evolutionaryAgentConfig = null;
3135

3236
// ************************************************************************
3337
// Constructors and simple getters/setters
@@ -41,6 +45,14 @@ public void setComplexProblem(@Nullable Boolean complexProblem) {
4145
this.complexProblem = complexProblem;
4246
}
4347

48+
public @Nullable Integer getAgentCount() {
49+
return agentCount;
50+
}
51+
52+
public void setAgentCount(@Nullable Integer agentCount) {
53+
this.agentCount = agentCount;
54+
}
55+
4456
public @Nullable EvolutionaryPopulationConfig getPopulationConfig() {
4557
return populationConfig;
4658
}
@@ -49,12 +61,12 @@ public void setPopulationConfig(@Nullable EvolutionaryPopulationConfig populatio
4961
this.populationConfig = populationConfig;
5062
}
5163

52-
public @Nullable EvolutionaryWorkerConfig getWorkerConfig() {
53-
return workerConfig;
64+
public @Nullable EvolutionaryAgentConfig getEvolutionaryAgentConfig() {
65+
return evolutionaryAgentConfig;
5466
}
5567

56-
public void setWorkerConfig(@Nullable EvolutionaryWorkerConfig workerConfig) {
57-
this.workerConfig = workerConfig;
68+
public void setEvolutionaryAgentConfig(@Nullable EvolutionaryAgentConfig evolutionaryAgentConfig) {
69+
this.evolutionaryAgentConfig = evolutionaryAgentConfig;
5870
}
5971

6072
// ************************************************************************
@@ -66,23 +78,29 @@ public EvolutionaryAlgorithmPhaseConfig withComplexProblem(Boolean complexProble
6678
return this;
6779
}
6880

81+
public EvolutionaryAlgorithmPhaseConfig withAgentCount(Integer agentCount) {
82+
setAgentCount(agentCount);
83+
return this;
84+
}
85+
6986
public EvolutionaryAlgorithmPhaseConfig withPopulationConfig(EvolutionaryPopulationConfig populationConfig) {
7087
setPopulationConfig(populationConfig);
7188
return this;
7289
}
7390

74-
public EvolutionaryAlgorithmPhaseConfig withWorkerConfig(EvolutionaryWorkerConfig evolutionaryWorkerConfig) {
75-
setWorkerConfig(evolutionaryWorkerConfig);
91+
public EvolutionaryAlgorithmPhaseConfig withEvolutionaryAgentConfig(EvolutionaryAgentConfig evolutionaryAgentConfig) {
92+
setEvolutionaryAgentConfig(evolutionaryAgentConfig);
7693
return this;
7794
}
7895

7996
@Override
8097
public EvolutionaryAlgorithmPhaseConfig inherit(EvolutionaryAlgorithmPhaseConfig inheritedConfig) {
8198
super.inherit(inheritedConfig);
8299
complexProblem = ConfigUtils.inheritOverwritableProperty(complexProblem, inheritedConfig.getComplexProblem());
100+
agentCount = ConfigUtils.inheritOverwritableProperty(agentCount, inheritedConfig.getAgentCount());
83101
populationConfig = ConfigUtils.inheritConfig(populationConfig, inheritedConfig.getPopulationConfig());
84-
workerConfig =
85-
ConfigUtils.inheritConfig(workerConfig, inheritedConfig.getWorkerConfig());
102+
evolutionaryAgentConfig =
103+
ConfigUtils.inheritConfig(evolutionaryAgentConfig, inheritedConfig.getEvolutionaryAgentConfig());
86104
return this;
87105
}
88106

@@ -96,8 +114,8 @@ public void visitReferencedClasses(Consumer<@Nullable Class<?>> classVisitor) {
96114
if (populationConfig != null) {
97115
populationConfig.visitReferencedClasses(classVisitor);
98116
}
99-
if (workerConfig != null) {
100-
workerConfig.visitReferencedClasses(classVisitor);
117+
if (evolutionaryAgentConfig != null) {
118+
evolutionaryAgentConfig.visitReferencedClasses(classVisitor);
101119
}
102120
}
103121
}

core/src/main/java/ai/timefold/solver/core/enterprise/TimefoldSolverEnterpriseService.java

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,8 @@
3131
import ai.timefold.solver.core.impl.domain.entity.descriptor.EntityDescriptor;
3232
import ai.timefold.solver.core.impl.domain.variable.declarative.TopologicalOrderGraph;
3333
import ai.timefold.solver.core.impl.evolutionaryalgorithm.common.state.SolutionState;
34-
import ai.timefold.solver.core.impl.evolutionaryalgorithm.common.state.SolutionStateManager;
35-
import ai.timefold.solver.core.impl.evolutionaryalgorithm.crossover.CrossoverStrategy;
3634
import ai.timefold.solver.core.impl.evolutionaryalgorithm.decider.EvolutionaryDecider;
37-
import ai.timefold.solver.core.impl.evolutionaryalgorithm.population.individual.IndividualBuilder;
38-
import ai.timefold.solver.core.impl.evolutionaryalgorithm.population.individual.generator.ConstructionIndividualStrategy;
35+
import ai.timefold.solver.core.impl.evolutionaryalgorithm.decider.HybridGeneticSearchWorkerContext;
3936
import ai.timefold.solver.core.impl.heuristic.HeuristicConfigPolicy;
4037
import ai.timefold.solver.core.impl.heuristic.selector.entity.EntitySelector;
4138
import ai.timefold.solver.core.impl.heuristic.selector.list.DestinationSelector;
@@ -48,7 +45,6 @@
4845
import ai.timefold.solver.core.impl.localsearch.decider.forager.LocalSearchForager;
4946
import ai.timefold.solver.core.impl.neighborhood.MoveRepository;
5047
import ai.timefold.solver.core.impl.partitionedsearch.PartitionedSearchPhase;
51-
import ai.timefold.solver.core.impl.phase.Phase;
5248
import ai.timefold.solver.core.impl.score.constraint.ConstraintMatchTotal;
5349
import ai.timefold.solver.core.impl.score.director.InnerScore;
5450
import ai.timefold.solver.core.impl.score.director.InnerScoreDirector;
@@ -181,13 +177,9 @@ <Solution_> PartitionedSearchPhase<Solution_> buildPartitionedSearch(int phaseIn
181177
BiFunction<HeuristicConfigPolicy<Solution_>, SolverTermination<Solution_>, PhaseTermination<Solution_>> phaseTerminationFunction);
182178

183179
<Solution_, Score_ extends Score<Score_>, State_ extends SolutionState<Solution_, Score_>>
184-
EvolutionaryDecider<Solution_, Score_> buildHybridGeneticSearch(int populationSize, int generationSize,
185-
int eliteGroupSize, int populationRestartCount,
186-
ConstructionIndividualStrategy<Solution_, Score_> constructionIndividualStrategy,
187-
Phase<Solution_> localSearchPhase, Phase<Solution_> swapStarPhase,
188-
CrossoverStrategy<Solution_, Score_> crossoverStrategy,
189-
IndividualBuilder<Solution_, Score_> individualBuilder,
190-
SolutionStateManager<Solution_, Score_, State_> solutionInitializer,
180+
EvolutionaryDecider<Solution_, Score_> buildHybridGeneticSearch(HeuristicConfigPolicy<Solution_> solverConfigPolicy,
181+
int agentCount, int populationSize, int generationSize, int eliteGroupSize, int populationRestartCount,
182+
List<HybridGeneticSearchWorkerContext<Solution_, Score_, State_>> agentContextList,
191183
PhaseTermination<Solution_> phaseTermination, BestSolutionRecaller<Solution_> bestSolutionRecaller);
192184

193185
<Solution_> EntitySelector<Solution_> applyNearbySelection(EntitySelectorConfig entitySelectorConfig,
@@ -236,7 +228,9 @@ enum Feature {
236228
"remove multistageMoveSelector and/or listMultistageMoveSelector from the solver configuration"),
237229
CONSTRAINT_PROFILING("Constraint profiling", "remove constraintStreamProfilingEnabled from the solver configuration"),
238230
SCORE_ANALYSIS("Score analysis", "do not use SolutionManager's analyze() method"),
239-
RECOMMENDATIONS("Recommendations", "do not use SolutionManager's recommendAssignment() method");
231+
RECOMMENDATIONS("Recommendations", "do not use SolutionManager's recommendAssignment() method"),
232+
EVOLUTIONARY_ALGORITHM("Evolutionary Algorithm",
233+
"remove the agent count property from the evolutionary algorithm configuration");
240234

241235
private final String name;
242236
private final String workaround;

core/src/main/java/ai/timefold/solver/core/impl/evolutionaryalgorithm/DefaultEvolutionaryAlgorithmPhase.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,12 @@ public void stepStarted(EvolutionaryAlgorithmStepScope<Solution_> stepScope) {
106106
public void stepEnded(EvolutionaryAlgorithmStepScope<Solution_> stepScope) {
107107
super.stepEnded(stepScope);
108108
evolutionaryDecider.stepEnded(stepScope);
109-
var solver = stepScope.getPhaseScope().getSolverScope().getSolver();
110-
solver.getBestSolutionRecaller().processWorkingSolutionDuringStep(stepScope);
109+
}
110+
111+
@Override
112+
public void solvingError(SolverScope<Solution_> solverScope, Exception exception) {
113+
super.solvingError(solverScope, exception);
114+
evolutionaryDecider.solvingError(solverScope, exception);
111115
}
112116

113117
@NullMarked

0 commit comments

Comments
 (0)