Skip to content

Commit b39b4d3

Browse files
chore: remove RandomFactory and RandomType
1 parent 0f74239 commit b39b4d3

14 files changed

Lines changed: 88 additions & 243 deletions

File tree

core/src/main/java/ai/timefold/solver/core/config/solver/SolverConfig.java

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,13 @@
4141
import ai.timefold.solver.core.config.score.director.ScoreDirectorFactoryConfig;
4242
import ai.timefold.solver.core.config.solver.monitoring.MonitoringConfig;
4343
import ai.timefold.solver.core.config.solver.monitoring.SolverMetric;
44-
import ai.timefold.solver.core.config.solver.random.RandomType;
4544
import ai.timefold.solver.core.config.solver.termination.TerminationConfig;
4645
import ai.timefold.solver.core.config.util.ConfigUtils;
4746
import ai.timefold.solver.core.impl.domain.common.accessor.MemberAccessor;
4847
import ai.timefold.solver.core.impl.heuristic.selector.common.nearby.NearbyDistanceMeter;
4948
import ai.timefold.solver.core.impl.io.jaxb.SolverConfigIO;
5049
import ai.timefold.solver.core.impl.io.jaxb.TimefoldXmlSerializationException;
5150
import ai.timefold.solver.core.impl.phase.PhaseFactory;
52-
import ai.timefold.solver.core.impl.solver.random.RandomFactory;
5351

5452
import org.jspecify.annotations.NonNull;
5553
import org.jspecify.annotations.Nullable;
@@ -63,9 +61,7 @@
6361
"enablePreviewFeatureSet",
6462
"environmentMode",
6563
"daemon",
66-
"randomType",
6764
"randomSeed",
68-
"randomFactoryClass",
6965
"moveThreadCount",
7066
"moveThreadBufferSize",
7167
"threadFactoryClass",
@@ -215,9 +211,7 @@ public final class SolverConfig extends AbstractConfig<SolverConfig> {
215211
private Set<PreviewFeature> enablePreviewFeatureSet = null;
216212
private EnvironmentMode environmentMode = null;
217213
private Boolean daemon = null;
218-
private RandomType randomType = null;
219214
private Long randomSeed = null;
220-
private Class<? extends RandomFactory> randomFactoryClass = null;
221215
private String moveThreadCount = null;
222216
private Integer moveThreadBufferSize = null;
223217
private Class<? extends ThreadFactory> threadFactoryClass = null;
@@ -332,14 +326,6 @@ public void setDaemon(@Nullable Boolean daemon) {
332326
this.daemon = daemon;
333327
}
334328

335-
public @Nullable RandomType getRandomType() {
336-
return randomType;
337-
}
338-
339-
public void setRandomType(@Nullable RandomType randomType) {
340-
this.randomType = randomType;
341-
}
342-
343329
public @Nullable Long getRandomSeed() {
344330
return randomSeed;
345331
}
@@ -348,14 +334,6 @@ public void setRandomSeed(@Nullable Long randomSeed) {
348334
this.randomSeed = randomSeed;
349335
}
350336

351-
public @Nullable Class<? extends RandomFactory> getRandomFactoryClass() {
352-
return randomFactoryClass;
353-
}
354-
355-
public void setRandomFactoryClass(@Nullable Class<? extends RandomFactory> randomFactoryClass) {
356-
this.randomFactoryClass = randomFactoryClass;
357-
}
358-
359337
public @Nullable String getMoveThreadCount() {
360338
return moveThreadCount;
361339
}
@@ -471,21 +449,11 @@ public void setMonitoringConfig(@Nullable MonitoringConfig monitoringConfig) {
471449
return this;
472450
}
473451

474-
public @NonNull SolverConfig withRandomType(@NonNull RandomType randomType) {
475-
this.randomType = randomType;
476-
return this;
477-
}
478-
479452
public @NonNull SolverConfig withRandomSeed(@NonNull Long randomSeed) {
480453
this.randomSeed = randomSeed;
481454
return this;
482455
}
483456

484-
public @NonNull SolverConfig withRandomFactoryClass(@NonNull Class<? extends RandomFactory> randomFactoryClass) {
485-
this.randomFactoryClass = randomFactoryClass;
486-
return this;
487-
}
488-
489457
public @NonNull SolverConfig withMoveThreadCount(@NonNull String moveThreadCount) {
490458
this.moveThreadCount = moveThreadCount;
491459
return this;
@@ -648,7 +616,7 @@ public boolean canTerminate() {
648616
// ************************************************************************
649617

650618
public void offerRandomSeedFromSubSingleIndex(long subSingleIndex) {
651-
if ((environmentMode == null || environmentMode.isReproducible()) && randomFactoryClass == null && randomSeed == null) {
619+
if ((environmentMode == null || environmentMode.isReproducible()) && randomSeed == null) {
652620
randomSeed = subSingleIndex;
653621
}
654622
}
@@ -665,10 +633,7 @@ public void offerRandomSeedFromSubSingleIndex(long subSingleIndex) {
665633
inheritedConfig.getEnablePreviewFeatureSet());
666634
environmentMode = ConfigUtils.inheritOverwritableProperty(environmentMode, inheritedConfig.getEnvironmentMode());
667635
daemon = ConfigUtils.inheritOverwritableProperty(daemon, inheritedConfig.getDaemon());
668-
randomType = ConfigUtils.inheritOverwritableProperty(randomType, inheritedConfig.getRandomType());
669636
randomSeed = ConfigUtils.inheritOverwritableProperty(randomSeed, inheritedConfig.getRandomSeed());
670-
randomFactoryClass = ConfigUtils.inheritOverwritableProperty(randomFactoryClass,
671-
inheritedConfig.getRandomFactoryClass());
672637
moveThreadCount = ConfigUtils.inheritOverwritableProperty(moveThreadCount,
673638
inheritedConfig.getMoveThreadCount());
674639
moveThreadBufferSize = ConfigUtils.inheritOverwritableProperty(moveThreadBufferSize,
@@ -700,7 +665,6 @@ public void offerRandomSeedFromSubSingleIndex(long subSingleIndex) {
700665

701666
@Override
702667
public void visitReferencedClasses(@NonNull Consumer<Class<?>> classVisitor) {
703-
classVisitor.accept(randomFactoryClass);
704668
classVisitor.accept(threadFactoryClass);
705669
classVisitor.accept(solutionClass);
706670
if (entityClassList != null) {

core/src/main/java/ai/timefold/solver/core/impl/solver/DefaultSolver.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import java.util.Map;
66
import java.util.Objects;
77
import java.util.concurrent.atomic.AtomicBoolean;
8+
import java.util.function.Supplier;
9+
import java.util.random.RandomGenerator;
810

911
import ai.timefold.solver.core.api.domain.common.PlanningId;
1012
import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
@@ -16,7 +18,6 @@
1618
import ai.timefold.solver.core.impl.phase.Phase;
1719
import ai.timefold.solver.core.impl.score.director.InnerScoreDirector;
1820
import ai.timefold.solver.core.impl.score.director.ScoreDirectorFactory;
19-
import ai.timefold.solver.core.impl.solver.random.RandomFactory;
2021
import ai.timefold.solver.core.impl.solver.recaller.BestSolutionRecaller;
2122
import ai.timefold.solver.core.impl.solver.scope.SolverScope;
2223
import ai.timefold.solver.core.impl.solver.termination.BasicPlumbingTermination;
@@ -38,7 +39,7 @@
3839
public class DefaultSolver<Solution_> extends AbstractSolver<Solution_> {
3940

4041
protected final EnvironmentMode environmentMode;
41-
protected final RandomFactory randomFactory;
42+
protected final Supplier<RandomGenerator> randomFactory;
4243
protected final BasicPlumbingTermination<Solution_> basicPlumbingTermination;
4344
protected final AtomicBoolean solving = new AtomicBoolean(false);
4445
protected final SolverScope<Solution_> solverScope;
@@ -48,7 +49,7 @@ public class DefaultSolver<Solution_> extends AbstractSolver<Solution_> {
4849
// Constructors and simple getters/setters
4950
// ************************************************************************
5051

51-
public DefaultSolver(EnvironmentMode environmentMode, RandomFactory randomFactory,
52+
public DefaultSolver(EnvironmentMode environmentMode, Supplier<RandomGenerator> randomFactory,
5253
BestSolutionRecaller<Solution_> bestSolutionRecaller, BasicPlumbingTermination<Solution_> basicPlumbingTermination,
5354
UniversalTermination<Solution_> termination, List<Phase<Solution_>> phaseList,
5455
SolverScope<Solution_> solverScope, String moveThreadCountDescription) {
@@ -65,7 +66,7 @@ public EnvironmentMode getEnvironmentMode() {
6566
return environmentMode;
6667
}
6768

68-
public RandomFactory getRandomFactory() {
69+
public Supplier<RandomGenerator> getRandomSupplier() {
6970
return randomFactory;
7071
}
7172

@@ -187,7 +188,7 @@ public void outerSolvingStarted(SolverScope<Solution_> solverScope) {
187188
solving.set(true);
188189
basicPlumbingTermination.resetTerminateEarly();
189190
solverScope.setStartingSolverCount(0);
190-
solverScope.setWorkingRandom(randomFactory.createRandom());
191+
solverScope.setWorkingRandom(randomFactory.get());
191192
}
192193

193194
@Override

core/src/main/java/ai/timefold/solver/core/impl/solver/DefaultSolverFactory.java

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.util.List;
88
import java.util.Objects;
99
import java.util.OptionalInt;
10+
import java.util.function.Supplier;
11+
import java.util.random.RandomGenerator;
1012

1113
import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
1214
import ai.timefold.solver.core.api.score.Score;
@@ -21,7 +23,6 @@
2123
import ai.timefold.solver.core.config.solver.PreviewFeature;
2224
import ai.timefold.solver.core.config.solver.SolverConfig;
2325
import ai.timefold.solver.core.config.solver.monitoring.SolverMetric;
24-
import ai.timefold.solver.core.config.solver.random.RandomType;
2526
import ai.timefold.solver.core.config.solver.termination.TerminationConfig;
2627
import ai.timefold.solver.core.config.util.ConfigUtils;
2728
import ai.timefold.solver.core.impl.AbstractFromConfigFactory;
@@ -36,8 +37,7 @@
3637
import ai.timefold.solver.core.impl.score.director.ScoreDirectorFactory;
3738
import ai.timefold.solver.core.impl.score.director.ScoreDirectorFactoryFactory;
3839
import ai.timefold.solver.core.impl.solver.change.DefaultProblemChangeDirector;
39-
import ai.timefold.solver.core.impl.solver.random.DefaultRandomFactory;
40-
import ai.timefold.solver.core.impl.solver.random.RandomFactory;
40+
import ai.timefold.solver.core.impl.solver.random.DelegatingSplittableRandomGenerator;
4141
import ai.timefold.solver.core.impl.solver.recaller.BestSolutionRecaller;
4242
import ai.timefold.solver.core.impl.solver.recaller.BestSolutionRecallerFactory;
4343
import ai.timefold.solver.core.impl.solver.scope.SolverScope;
@@ -133,7 +133,7 @@ public Solver<Solution_> buildSolver(SolverConfigOverride configOverride) {
133133

134134
var moveThreadCount = resolveMoveThreadCount(true);
135135
var bestSolutionRecaller = BestSolutionRecallerFactory.create().<Solution_> buildBestSolutionRecaller(environmentMode);
136-
var randomFactory = buildRandomFactory(environmentMode);
136+
var randomFactory = buildRandomSupplier(environmentMode);
137137
var previewFeaturesEnabled = solverConfig.getEnablePreviewFeatureSet();
138138

139139
var scoreDirectorFactoryConfig = solverConfig.getScoreDirectorFactoryConfig();
@@ -153,7 +153,7 @@ public Solver<Solution_> buildSolver(SolverConfigOverride configOverride) {
153153
.withMoveThreadBufferSize(solverConfig.getMoveThreadBufferSize())
154154
.withThreadFactoryClass(solverConfig.getThreadFactoryClass())
155155
.withNearbyDistanceMeterClass(solverConfig.getNearbyDistanceMeterClass())
156-
.withRandom(randomFactory.createRandom())
156+
.withRandom(randomFactory.get())
157157
.withInitializingScoreTrend(scoreDirectorFactory.getInitializingScoreTrend())
158158
.withSolutionDescriptor(solutionDescriptor)
159159
.withClassInstanceCache(ClassInstanceCache.create())
@@ -212,25 +212,15 @@ private <Score_ extends Score<Score_>> ScoreDirectorFactory<Solution_, Score_> b
212212
return scoreDirectorFactoryFactory.buildScoreDirectorFactory(environmentMode, solutionDescriptor);
213213
}
214214

215-
public RandomFactory buildRandomFactory(EnvironmentMode environmentMode_) {
216-
var randomFactoryClass = solverConfig.getRandomFactoryClass();
217-
if (randomFactoryClass != null) {
218-
var randomType = solverConfig.getRandomType();
219-
var randomSeed = solverConfig.getRandomSeed();
220-
if (randomType != null || randomSeed != null) {
221-
throw new IllegalArgumentException(
222-
"The solverConfig with randomFactoryClass (%s) has a non-null randomType (%s) or a non-null randomSeed (%s)."
223-
.formatted(randomFactoryClass, randomType, randomSeed));
224-
}
225-
return ConfigUtils.newInstance(solverConfig, "randomFactoryClass", randomFactoryClass);
215+
public Supplier<RandomGenerator> buildRandomSupplier(EnvironmentMode environmentMode_) {
216+
var randomSeed_ = solverConfig.getRandomSeed();
217+
if (randomSeed_ == null && environmentMode_ != EnvironmentMode.NON_REPRODUCIBLE) {
218+
randomSeed_ = DEFAULT_RANDOM_SEED;
226219
} else {
227-
var randomType_ = Objects.requireNonNullElse(solverConfig.getRandomType(), RandomType.JDK);
228-
var randomSeed_ = solverConfig.getRandomSeed();
229-
if (solverConfig.getRandomSeed() == null && environmentMode_ != EnvironmentMode.NON_REPRODUCIBLE) {
230-
randomSeed_ = DEFAULT_RANDOM_SEED;
231-
}
232-
return new DefaultRandomFactory(randomType_, randomSeed_);
220+
randomSeed_ = RandomGenerator.getDefault().nextLong();
233221
}
222+
Long finalRandomSeed_ = randomSeed_;
223+
return () -> new DelegatingSplittableRandomGenerator(finalRandomSeed_);
234224
}
235225

236226
public List<Phase<Solution_>> buildPhaseList(HeuristicConfigPolicy<Solution_> configPolicy,

core/src/main/java/ai/timefold/solver/core/impl/solver/random/DefaultRandomFactory.java

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)