From 644a4740247f4390c7244fd4da52dbf1b3a18a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Petrovick=C3=BD?= Date: Mon, 26 Aug 2024 11:00:59 +0200 Subject: [PATCH] chore: code review --- .../DefaultConstructionHeuristicPhase.java | 24 +++---- ...aultConstructionHeuristicPhaseFactory.java | 43 ++++--------- ...nRecreateConstructionHeuristicDecider.java | 4 +- ...uinRecreateConstructionHeuristicPhase.java | 55 ++++------------ ...eateConstructionHeuristicPhaseBuilder.java | 63 +++++++++++++++++++ ...eateConstructionHeuristicPhaseFactory.java | 37 +++++++++++ .../move/generic/RuinRecreateMove.java | 1 - .../generic/RuinRecreateMoveIterator.java | 1 - .../generic/RuinRecreateMoveSelector.java | 1 - .../RuinRecreateMoveSelectorFactory.java | 7 +-- .../list/ruin/ListRuinRecreateMove.java | 2 +- .../ruin/ListRuinRecreateMoveIterator.java | 2 +- .../ruin/ListRuinRecreateMoveSelector.java | 2 +- .../ListRuinRecreateMoveSelectorFactory.java | 12 ++-- 14 files changed, 151 insertions(+), 103 deletions(-) create mode 100644 core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhaseBuilder.java create mode 100644 core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhaseFactory.java diff --git a/core/src/main/java/ai/timefold/solver/core/impl/constructionheuristic/DefaultConstructionHeuristicPhase.java b/core/src/main/java/ai/timefold/solver/core/impl/constructionheuristic/DefaultConstructionHeuristicPhase.java index b3fd994960..e2103045f4 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/constructionheuristic/DefaultConstructionHeuristicPhase.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/constructionheuristic/DefaultConstructionHeuristicPhase.java @@ -26,10 +26,6 @@ protected DefaultConstructionHeuristicPhase(DefaultConstructionHeuristicPhaseBui entityPlacer = builder.getEntityPlacer(); } - protected boolean isNested() { - return false; - } - public EntityPlacer getEntityPlacer() { return entityPlacer; } @@ -102,9 +98,11 @@ private void doStep(ConstructionHeuristicStepScope stepScope) { var step = stepScope.getStep(); step.doMoveOnly(stepScope.getScoreDirector()); predictWorkingStepScore(stepScope, step); - if (!isNested()) { - solver.getBestSolutionRecaller().processWorkingSolutionDuringConstructionHeuristicsStep(stepScope); - } + processWorkingSolutionDuringStep(stepScope); + } + + protected void processWorkingSolutionDuringStep(ConstructionHeuristicStepScope stepScope) { + solver.getBestSolutionRecaller().processWorkingSolutionDuringConstructionHeuristicsStep(stepScope); } @Override @@ -143,10 +141,7 @@ public void stepEnded(ConstructionHeuristicStepScope stepScope) { public void phaseEnded(ConstructionHeuristicPhaseScope phaseScope) { super.phaseEnded(phaseScope); - // Only update the best solution if it is not a ruin+recreate CH and the CH made any change. - if (!isNested() && !phaseScope.getStartingScore().equals(phaseScope.getBestScore())) { - solver.getBestSolutionRecaller().updateBestSolutionAndFire(phaseScope.getSolverScope()); - } + updateBestSolutionAndFire(phaseScope); entityPlacer.phaseEnded(phaseScope); decider.phaseEnded(phaseScope); phaseScope.endingNow(); @@ -162,6 +157,13 @@ public void phaseEnded(ConstructionHeuristicPhaseScope phaseScope) { } } + protected void updateBestSolutionAndFire(ConstructionHeuristicPhaseScope phaseScope) { + // Only update the best solution if the CH made any change. + if (!phaseScope.getStartingScore().equals(phaseScope.getBestScore())) { + solver.getBestSolutionRecaller().updateBestSolutionAndFire(phaseScope.getSolverScope()); + } + } + @Override public void solvingEnded(SolverScope solverScope) { super.solvingEnded(solverScope); diff --git a/core/src/main/java/ai/timefold/solver/core/impl/constructionheuristic/DefaultConstructionHeuristicPhaseFactory.java b/core/src/main/java/ai/timefold/solver/core/impl/constructionheuristic/DefaultConstructionHeuristicPhaseFactory.java index 74766e78b2..0ddd53a95f 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/constructionheuristic/DefaultConstructionHeuristicPhaseFactory.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/constructionheuristic/DefaultConstructionHeuristicPhaseFactory.java @@ -17,13 +17,13 @@ import ai.timefold.solver.core.config.heuristic.selector.move.composite.UnionMoveSelectorConfig; import ai.timefold.solver.core.config.heuristic.selector.move.generic.list.ListChangeMoveSelectorConfig; import ai.timefold.solver.core.config.heuristic.selector.value.ValueSelectorConfig; -import ai.timefold.solver.core.config.solver.termination.TerminationConfig; import ai.timefold.solver.core.config.util.ConfigUtils; import ai.timefold.solver.core.enterprise.TimefoldSolverEnterpriseService; import ai.timefold.solver.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.DefaultConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.constructionheuristic.decider.ConstructionHeuristicDecider; import ai.timefold.solver.core.impl.constructionheuristic.decider.forager.ConstructionHeuristicForager; import ai.timefold.solver.core.impl.constructionheuristic.decider.forager.ConstructionHeuristicForagerFactory; +import ai.timefold.solver.core.impl.constructionheuristic.placer.EntityPlacer; import ai.timefold.solver.core.impl.constructionheuristic.placer.EntityPlacerFactory; import ai.timefold.solver.core.impl.constructionheuristic.placer.PooledEntityPlacerFactory; import ai.timefold.solver.core.impl.constructionheuristic.placer.QueuedEntityPlacerFactory; @@ -31,14 +31,9 @@ import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor; import ai.timefold.solver.core.impl.domain.variable.descriptor.ListVariableDescriptor; import ai.timefold.solver.core.impl.heuristic.HeuristicConfigPolicy; -import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicDecider; -import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhase.RuinRecreateConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.phase.AbstractPhaseFactory; import ai.timefold.solver.core.impl.solver.recaller.BestSolutionRecaller; -import ai.timefold.solver.core.impl.solver.termination.BasicPlumbingTermination; -import ai.timefold.solver.core.impl.solver.termination.PhaseToSolverTerminationBridge; import ai.timefold.solver.core.impl.solver.termination.Termination; -import ai.timefold.solver.core.impl.solver.termination.TerminationFactory; public class DefaultConstructionHeuristicPhaseFactory extends AbstractPhaseFactory { @@ -47,9 +42,9 @@ public DefaultConstructionHeuristicPhaseFactory(ConstructionHeuristicPhaseConfig super(phaseConfig); } - protected DefaultConstructionHeuristicPhaseBuilder getBaseBuilder(int phaseIndex, + public final DefaultConstructionHeuristicPhaseBuilder getBuilder(int phaseIndex, boolean triggerFirstInitializedSolutionEvent, HeuristicConfigPolicy solverConfigPolicy, - Termination solverTermination, boolean isNested) { + Termination solverTermination) { var constructionHeuristicType_ = Objects.requireNonNullElse(phaseConfig.getConstructionHeuristicType(), ConstructionHeuristicType.ALLOCATE_ENTITY_FROM_QUEUE); var entitySorterManner = Objects.requireNonNullElse(phaseConfig.getEntitySorterManner(), @@ -67,15 +62,16 @@ protected DefaultConstructionHeuristicPhaseBuilder getBaseBuilder(int .orElseGet(() -> buildDefaultEntityPlacerConfig(phaseConfigPolicy, constructionHeuristicType_)); var entityPlacer = EntityPlacerFactory. create(entityPlacerConfig_) .buildEntityPlacer(phaseConfigPolicy); + return createBuilder(phaseConfigPolicy, solverTermination, phaseIndex, triggerFirstInitializedSolutionEvent, + entityPlacer); + } - if (isNested) { // Nested phases ignore terminations and always finish, as they are nested inside a move. - var phaseTermination = new PhaseToSolverTerminationBridge<>(new BasicPlumbingTermination(false)); - return new RuinRecreateConstructionHeuristicPhaseBuilder<>(phaseTermination, entityPlacer, - buildRuinRecreateDecider(phaseConfigPolicy, phaseTermination)); - } + protected DefaultConstructionHeuristicPhaseBuilder createBuilder( + HeuristicConfigPolicy phaseConfigPolicy, Termination solverTermination, int phaseIndex, + boolean triggerFirstInitializedSolutionEvent, EntityPlacer entityPlacer) { var phaseTermination = buildPhaseTermination(phaseConfigPolicy, solverTermination); var builder = new DefaultConstructionHeuristicPhaseBuilder<>(phaseIndex, triggerFirstInitializedSolutionEvent, - solverConfigPolicy.getLogIndentation(), phaseTermination, entityPlacer, + phaseConfigPolicy.getLogIndentation(), phaseTermination, entityPlacer, buildDecider(phaseConfigPolicy, phaseTermination)); var environmentMode = phaseConfigPolicy.getEnvironmentMode(); if (environmentMode.isNonIntrusiveFullAsserted()) { @@ -92,18 +88,10 @@ protected DefaultConstructionHeuristicPhaseBuilder getBaseBuilder(int public ConstructionHeuristicPhase buildPhase(int phaseIndex, boolean triggerFirstInitializedSolutionEvent, HeuristicConfigPolicy solverConfigPolicy, BestSolutionRecaller bestSolutionRecaller, Termination solverTermination) { - return getBaseBuilder(phaseIndex, triggerFirstInitializedSolutionEvent, solverConfigPolicy, solverTermination, false) + return getBuilder(phaseIndex, triggerFirstInitializedSolutionEvent, solverConfigPolicy, solverTermination) .build(); } - public RuinRecreateConstructionHeuristicPhaseBuilder - getRuinPhaseBuilder(HeuristicConfigPolicy solverConfigPolicy) { - var solverTermination = TerminationFactory. create(new TerminationConfig()) - .buildTermination(solverConfigPolicy); - return (RuinRecreateConstructionHeuristicPhaseBuilder) getBaseBuilder(0, false, solverConfigPolicy, - solverTermination, true); - } - private Optional> getValidEntityPlacerConfig() { EntityPlacerConfig entityPlacerConfig = phaseConfig.getEntityPlacerConfig(); if (entityPlacerConfig == null) { @@ -177,7 +165,7 @@ public static EntityPlacerConfig buildListVariableQueuedValuePlacerConfig(Heuris .withMoveSelectorConfig(listChangeMoveSelectorConfig); } - private ConstructionHeuristicDecider buildDecider(HeuristicConfigPolicy configPolicy, + protected ConstructionHeuristicDecider buildDecider(HeuristicConfigPolicy configPolicy, Termination termination) { var forager = buildForager(configPolicy); var moveThreadCount = configPolicy.getMoveThreadCount(); @@ -189,17 +177,12 @@ private ConstructionHeuristicDecider buildDecider(HeuristicConfigPoli return decider; } - private ConstructionHeuristicForager buildForager(HeuristicConfigPolicy configPolicy) { + protected ConstructionHeuristicForager buildForager(HeuristicConfigPolicy configPolicy) { var foragerConfig_ = Objects.requireNonNullElseGet(phaseConfig.getForagerConfig(), ConstructionHeuristicForagerConfig::new); return ConstructionHeuristicForagerFactory. create(foragerConfig_).buildForager(configPolicy); } - private ConstructionHeuristicDecider buildRuinRecreateDecider(HeuristicConfigPolicy configPolicy, - Termination termination) { - return new RuinRecreateConstructionHeuristicDecider<>(termination, buildForager(configPolicy)); - } - private EntityPlacerConfig buildUnfoldedEntityPlacerConfig(HeuristicConfigPolicy phaseConfigPolicy, ConstructionHeuristicType constructionHeuristicType) { return switch (constructionHeuristicType) { diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicDecider.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicDecider.java index 9fc29f1d86..653d03defb 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicDecider.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicDecider.java @@ -5,10 +5,10 @@ import ai.timefold.solver.core.impl.constructionheuristic.decider.forager.ConstructionHeuristicForager; import ai.timefold.solver.core.impl.solver.termination.Termination; -public final class RuinRecreateConstructionHeuristicDecider +final class RuinRecreateConstructionHeuristicDecider extends ConstructionHeuristicDecider { - public RuinRecreateConstructionHeuristicDecider(Termination termination, + RuinRecreateConstructionHeuristicDecider(Termination termination, ConstructionHeuristicForager forager) { super("", termination, forager); } diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhase.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhase.java index 84b4ba5978..9d95deea75 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhase.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhase.java @@ -1,60 +1,31 @@ package ai.timefold.solver.core.impl.heuristic.selector.move.generic; -import java.util.List; - import ai.timefold.solver.core.impl.constructionheuristic.ConstructionHeuristicPhase; import ai.timefold.solver.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase; -import ai.timefold.solver.core.impl.constructionheuristic.decider.ConstructionHeuristicDecider; -import ai.timefold.solver.core.impl.constructionheuristic.placer.EntityPlacer; -import ai.timefold.solver.core.impl.solver.termination.Termination; +import ai.timefold.solver.core.impl.constructionheuristic.scope.ConstructionHeuristicPhaseScope; +import ai.timefold.solver.core.impl.constructionheuristic.scope.ConstructionHeuristicStepScope; -public final class RuinRecreateConstructionHeuristicPhase +final class RuinRecreateConstructionHeuristicPhase extends DefaultConstructionHeuristicPhase implements ConstructionHeuristicPhase { - public RuinRecreateConstructionHeuristicPhase(RuinRecreateConstructionHeuristicPhaseBuilder builder) { + RuinRecreateConstructionHeuristicPhase(RuinRecreateConstructionHeuristicPhaseBuilder builder) { super(builder); } @Override - protected boolean isNested() { - return true; + protected void processWorkingSolutionDuringStep(ConstructionHeuristicStepScope stepScope) { + // Ruin and Recreate CH doesn't process the working solution, it is a nested phase. } - public static final class RuinRecreateConstructionHeuristicPhaseBuilder - extends DefaultConstructionHeuristicPhaseBuilder { - - private List elementsToRecreate; - - public RuinRecreateConstructionHeuristicPhaseBuilder(Termination phaseTermination, - EntityPlacer entityPlacer, ConstructionHeuristicDecider decider) { - super(0, false, "", phaseTermination, entityPlacer, decider); - } - - public RuinRecreateConstructionHeuristicPhaseBuilder withElementsToRecreate(List elements) { - this.elementsToRecreate = elements; - return this; - } - - @Override - public EntityPlacer getEntityPlacer() { - if (elementsToRecreate == null || elementsToRecreate.isEmpty()) { - return super.getEntityPlacer(); - } - return super.getEntityPlacer().rebuildWithFilter((scoreDirector, selection) -> { - for (var element : elementsToRecreate) { - if (selection == element) { - return true; - } - } - return false; - }); - } + @Override + protected void updateBestSolutionAndFire(ConstructionHeuristicPhaseScope phaseScope) { + // Ruin and Recreate CH doesn't update the best solution, it is a nested phase. + } - @Override - public RuinRecreateConstructionHeuristicPhase build() { - return new RuinRecreateConstructionHeuristicPhase<>(this); - } + @Override + public String getPhaseTypeString() { + return "Ruin & Recreate Construction Heuristics"; } } diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhaseBuilder.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhaseBuilder.java new file mode 100644 index 0000000000..ccb5bbd0f1 --- /dev/null +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhaseBuilder.java @@ -0,0 +1,63 @@ +package ai.timefold.solver.core.impl.heuristic.selector.move.generic; + +import java.util.List; + +import ai.timefold.solver.core.config.constructionheuristic.ConstructionHeuristicPhaseConfig; +import ai.timefold.solver.core.config.solver.termination.TerminationConfig; +import ai.timefold.solver.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase; +import ai.timefold.solver.core.impl.constructionheuristic.decider.ConstructionHeuristicDecider; +import ai.timefold.solver.core.impl.constructionheuristic.placer.EntityPlacer; +import ai.timefold.solver.core.impl.heuristic.HeuristicConfigPolicy; +import ai.timefold.solver.core.impl.solver.termination.Termination; +import ai.timefold.solver.core.impl.solver.termination.TerminationFactory; + +public final class RuinRecreateConstructionHeuristicPhaseBuilder + extends DefaultConstructionHeuristicPhase.DefaultConstructionHeuristicPhaseBuilder { + + public static RuinRecreateConstructionHeuristicPhaseBuilder + create(HeuristicConfigPolicy solverConfigPolicy) { + var constructionHeuristicConfig = new ConstructionHeuristicPhaseConfig(); + return create(solverConfigPolicy, constructionHeuristicConfig); + } + + public static RuinRecreateConstructionHeuristicPhaseBuilder create( + HeuristicConfigPolicy solverConfigPolicy, ConstructionHeuristicPhaseConfig constructionHeuristicConfig) { + var constructionHeuristicPhaseFactory = + new RuinRecreateConstructionHeuristicPhaseFactory(constructionHeuristicConfig); + return (RuinRecreateConstructionHeuristicPhaseBuilder) constructionHeuristicPhaseFactory.getBuilder(0, false, + solverConfigPolicy, TerminationFactory. create(new TerminationConfig()) + .buildTermination(solverConfigPolicy)); + } + + private List elementsToRecreate; + + RuinRecreateConstructionHeuristicPhaseBuilder(Termination phaseTermination, + EntityPlacer entityPlacer, ConstructionHeuristicDecider decider) { + super(0, false, "", phaseTermination, entityPlacer, decider); + } + + public RuinRecreateConstructionHeuristicPhaseBuilder withElementsToRecreate(List elements) { + this.elementsToRecreate = elements; + return this; + } + + @Override + public EntityPlacer getEntityPlacer() { + if (elementsToRecreate == null || elementsToRecreate.isEmpty()) { + return super.getEntityPlacer(); + } + return super.getEntityPlacer().rebuildWithFilter((scoreDirector, selection) -> { + for (var element : elementsToRecreate) { + if (selection == element) { + return true; + } + } + return false; + }); + } + + @Override + public DefaultConstructionHeuristicPhase build() { + return new RuinRecreateConstructionHeuristicPhase<>(this); + } +} diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhaseFactory.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhaseFactory.java new file mode 100644 index 0000000000..f09f7d19fe --- /dev/null +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateConstructionHeuristicPhaseFactory.java @@ -0,0 +1,37 @@ +package ai.timefold.solver.core.impl.heuristic.selector.move.generic; + +import ai.timefold.solver.core.config.constructionheuristic.ConstructionHeuristicPhaseConfig; +import ai.timefold.solver.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.DefaultConstructionHeuristicPhaseBuilder; +import ai.timefold.solver.core.impl.constructionheuristic.DefaultConstructionHeuristicPhaseFactory; +import ai.timefold.solver.core.impl.constructionheuristic.decider.ConstructionHeuristicDecider; +import ai.timefold.solver.core.impl.constructionheuristic.placer.EntityPlacer; +import ai.timefold.solver.core.impl.heuristic.HeuristicConfigPolicy; +import ai.timefold.solver.core.impl.solver.termination.BasicPlumbingTermination; +import ai.timefold.solver.core.impl.solver.termination.PhaseToSolverTerminationBridge; +import ai.timefold.solver.core.impl.solver.termination.Termination; + +final class RuinRecreateConstructionHeuristicPhaseFactory + extends DefaultConstructionHeuristicPhaseFactory { + + RuinRecreateConstructionHeuristicPhaseFactory(ConstructionHeuristicPhaseConfig phaseConfig) { + super(phaseConfig); + } + + @Override + protected DefaultConstructionHeuristicPhaseBuilder createBuilder( + HeuristicConfigPolicy phaseConfigPolicy, + Termination solverTermination, int phaseIndex, boolean triggerFirstInitializedSolutionEvent, + EntityPlacer entityPlacer) { + var phaseTermination = new PhaseToSolverTerminationBridge<>(new BasicPlumbingTermination(false)); + return new RuinRecreateConstructionHeuristicPhaseBuilder<>(phaseTermination, entityPlacer, + buildDecider(phaseConfigPolicy, phaseTermination)); + + } + + @Override + protected ConstructionHeuristicDecider buildDecider(HeuristicConfigPolicy configPolicy, + Termination termination) { + return new RuinRecreateConstructionHeuristicDecider<>(termination, buildForager(configPolicy)); + } + +} diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMove.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMove.java index 82c283fa53..a4e064ad1e 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMove.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMove.java @@ -9,7 +9,6 @@ import ai.timefold.solver.core.impl.domain.variable.descriptor.GenuineVariableDescriptor; import ai.timefold.solver.core.impl.heuristic.move.AbstractMove; import ai.timefold.solver.core.impl.heuristic.move.Move; -import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhase.RuinRecreateConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.score.director.VariableDescriptorAwareScoreDirector; import ai.timefold.solver.core.impl.solver.scope.SolverScope; diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveIterator.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveIterator.java index eed8d08dbc..e7c0a917f0 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveIterator.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveIterator.java @@ -9,7 +9,6 @@ import ai.timefold.solver.core.impl.heuristic.move.NoChangeMove; import ai.timefold.solver.core.impl.heuristic.selector.common.iterator.UpcomingSelectionIterator; import ai.timefold.solver.core.impl.heuristic.selector.entity.EntitySelector; -import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhase.RuinRecreateConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.solver.scope.SolverScope; import ai.timefold.solver.core.impl.util.CollectionUtils; diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelector.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelector.java index 08838572f9..0e4340b9c4 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelector.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelector.java @@ -5,7 +5,6 @@ import ai.timefold.solver.core.impl.domain.variable.descriptor.GenuineVariableDescriptor; import ai.timefold.solver.core.impl.heuristic.move.Move; import ai.timefold.solver.core.impl.heuristic.selector.entity.EntitySelector; -import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhase.RuinRecreateConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.solver.scope.SolverScope; import org.apache.commons.math3.util.CombinatoricsUtils; diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelectorFactory.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelectorFactory.java index 0b2535aae4..11903bd6e9 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelectorFactory.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelectorFactory.java @@ -1,11 +1,9 @@ package ai.timefold.solver.core.impl.heuristic.selector.move.generic; -import ai.timefold.solver.core.config.constructionheuristic.ConstructionHeuristicPhaseConfig; import ai.timefold.solver.core.config.heuristic.selector.common.SelectionCacheType; import ai.timefold.solver.core.config.heuristic.selector.common.SelectionOrder; import ai.timefold.solver.core.config.heuristic.selector.entity.EntitySelectorConfig; import ai.timefold.solver.core.config.heuristic.selector.move.generic.RuinRecreateMoveSelectorConfig; -import ai.timefold.solver.core.impl.constructionheuristic.DefaultConstructionHeuristicPhaseFactory; import ai.timefold.solver.core.impl.heuristic.HeuristicConfigPolicy; import ai.timefold.solver.core.impl.heuristic.selector.entity.EntitySelectorFactory; import ai.timefold.solver.core.impl.heuristic.selector.move.AbstractMoveSelectorFactory; @@ -37,10 +35,7 @@ protected MoveSelector buildBaseMoveSelector(HeuristicConfigPolicy(constructionHeuristicConfig); - var constructionHeuristicPhaseBuilder = constructionHeuristicPhaseFactory.getRuinPhaseBuilder(configPolicy); + var constructionHeuristicPhaseBuilder = RuinRecreateConstructionHeuristicPhaseBuilder.create(configPolicy); return new RuinRecreateMoveSelector<>(entitySelector, variableDescriptor, constructionHeuristicPhaseBuilder, minimumSelectedSupplier, maximumSelectedSupplier); } diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMove.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMove.java index 93e17409dc..136306cbef 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMove.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMove.java @@ -12,7 +12,7 @@ import ai.timefold.solver.core.impl.heuristic.move.AbstractMove; import ai.timefold.solver.core.impl.heuristic.move.Move; import ai.timefold.solver.core.impl.heuristic.selector.list.LocationInList; -import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhase.RuinRecreateConstructionHeuristicPhaseBuilder; +import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.score.director.VariableDescriptorAwareScoreDirector; import ai.timefold.solver.core.impl.solver.scope.SolverScope; import ai.timefold.solver.core.impl.util.CollectionUtils; diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveIterator.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveIterator.java index 8749b2a4d7..73c18a505b 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveIterator.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveIterator.java @@ -8,7 +8,7 @@ import ai.timefold.solver.core.impl.heuristic.move.Move; import ai.timefold.solver.core.impl.heuristic.move.NoChangeMove; import ai.timefold.solver.core.impl.heuristic.selector.common.iterator.UpcomingSelectionIterator; -import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhase.RuinRecreateConstructionHeuristicPhaseBuilder; +import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.heuristic.selector.value.EntityIndependentValueSelector; import ai.timefold.solver.core.impl.solver.scope.SolverScope; import ai.timefold.solver.core.impl.util.CollectionUtils; diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelector.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelector.java index b28558efe6..3130b55523 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelector.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelector.java @@ -7,7 +7,7 @@ import ai.timefold.solver.core.impl.heuristic.move.Move; import ai.timefold.solver.core.impl.heuristic.selector.move.generic.CountSupplier; import ai.timefold.solver.core.impl.heuristic.selector.move.generic.GenericMoveSelector; -import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhase.RuinRecreateConstructionHeuristicPhaseBuilder; +import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.heuristic.selector.value.EntityIndependentValueSelector; import ai.timefold.solver.core.impl.heuristic.selector.value.decorator.FilteringValueSelector; import ai.timefold.solver.core.impl.solver.scope.SolverScope; diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelectorFactory.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelectorFactory.java index ccb52cd3fa..fb18620140 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelectorFactory.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelectorFactory.java @@ -10,6 +10,7 @@ import ai.timefold.solver.core.impl.heuristic.selector.move.AbstractMoveSelectorFactory; import ai.timefold.solver.core.impl.heuristic.selector.move.MoveSelector; import ai.timefold.solver.core.impl.heuristic.selector.move.generic.CountSupplier; +import ai.timefold.solver.core.impl.heuristic.selector.move.generic.RuinRecreateConstructionHeuristicPhaseBuilder; import ai.timefold.solver.core.impl.heuristic.selector.value.EntityIndependentValueSelector; import ai.timefold.solver.core.impl.heuristic.selector.value.ValueSelectorFactory; @@ -40,12 +41,11 @@ protected MoveSelector buildBaseMoveSelector(HeuristicConfigPolicy(constructionHeuristicConfig); - return new ListRuinRecreateMoveSelector<>(valueSelector, listVariableDescriptor, - constructionHeuristicPhaseFactory.getRuinPhaseBuilder(configPolicy), + var constructionHeuristicPhaseConfig = new ConstructionHeuristicPhaseConfig() + .withEntityPlacerConfig(entityPlacerConfig); + var constructionHeuristicPhaseBuilder = + RuinRecreateConstructionHeuristicPhaseBuilder.create(configPolicy, constructionHeuristicPhaseConfig); + return new ListRuinRecreateMoveSelector<>(valueSelector, listVariableDescriptor, constructionHeuristicPhaseBuilder, minimumSelectedSupplier, maximumSelectedSupplier); } }