Skip to content

Commit d0da2b4

Browse files
committed
feat: enable mixed models for more moves
1 parent a43b552 commit d0da2b4

2 files changed

Lines changed: 47 additions & 12 deletions

File tree

core/src/test/java/ai/timefold/solver/core/impl/solver/DefaultSolverTest.java

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,12 @@
4040
import ai.timefold.solver.core.config.constructionheuristic.placer.QueuedEntityPlacerConfig;
4141
import ai.timefold.solver.core.config.constructionheuristic.placer.QueuedValuePlacerConfig;
4242
import ai.timefold.solver.core.config.heuristic.selector.entity.EntitySelectorConfig;
43+
import ai.timefold.solver.core.config.heuristic.selector.entity.pillar.PillarSelectorConfig;
4344
import ai.timefold.solver.core.config.heuristic.selector.move.MoveSelectorConfig;
4445
import ai.timefold.solver.core.config.heuristic.selector.move.composite.UnionMoveSelectorConfig;
4546
import ai.timefold.solver.core.config.heuristic.selector.move.generic.ChangeMoveSelectorConfig;
47+
import ai.timefold.solver.core.config.heuristic.selector.move.generic.PillarChangeMoveSelectorConfig;
48+
import ai.timefold.solver.core.config.heuristic.selector.move.generic.PillarSwapMoveSelectorConfig;
4649
import ai.timefold.solver.core.config.heuristic.selector.move.generic.SwapMoveSelectorConfig;
4750
import ai.timefold.solver.core.config.heuristic.selector.move.generic.chained.TailChainSwapMoveSelectorConfig;
4851
import ai.timefold.solver.core.config.heuristic.selector.move.generic.list.ListChangeMoveSelectorConfig;
@@ -125,6 +128,8 @@
125128
import org.junit.jupiter.api.Test;
126129
import org.junit.jupiter.api.Timeout;
127130
import org.junit.jupiter.api.extension.ExtendWith;
131+
import org.junit.jupiter.params.ParameterizedTest;
132+
import org.junit.jupiter.params.provider.MethodSource;
128133

129134
import io.micrometer.core.instrument.Meter;
130135
import io.micrometer.core.instrument.Metrics;
@@ -1510,8 +1515,39 @@ void solvePinnedAndUnassignedWithListAndBasicVariables() {
15101515
assertThat(solution.getEntityList().get(1).getValueList()).hasSameElementsAs(List.of(problem.getValueList().get(3)));
15111516
}
15121517

1513-
@Test
1514-
void solveCustomConfigurationMultiEntityWithListAndBasicVariables() {
1518+
private static List<MoveSelectorConfig> generateMultiEntityListAndBasicMoveConfig() {
1519+
// Local Search
1520+
var allMoveSelectionConfigList = new ArrayList<MoveSelectorConfig>();
1521+
// Change - basic
1522+
allMoveSelectionConfigList.add(new ChangeMoveSelectorConfig());
1523+
// Swap - basic
1524+
allMoveSelectionConfigList.add(new SwapMoveSelectorConfig());
1525+
// Pillar change - basic
1526+
var pillarChangeMoveSelectorConfig = new PillarChangeMoveSelectorConfig();
1527+
var pillarChangeEntitySelectorConfig =
1528+
new EntitySelectorConfig().withEntityClass(TestdataListMultiEntitySecondEntity.class);
1529+
var pillarChangeValueSelectorConfig = new ValueSelectorConfig().withVariableName("basicValue");
1530+
pillarChangeMoveSelectorConfig
1531+
.withPillarSelectorConfig(new PillarSelectorConfig().withEntitySelectorConfig(pillarChangeEntitySelectorConfig))
1532+
.withValueSelectorConfig(pillarChangeValueSelectorConfig);
1533+
allMoveSelectionConfigList.add(pillarChangeMoveSelectorConfig);
1534+
// Pilar swap - basic
1535+
allMoveSelectionConfigList.add(new PillarSwapMoveSelectorConfig().withPillarSelectorConfig(
1536+
new PillarSelectorConfig().withEntitySelectorConfig(pillarChangeEntitySelectorConfig)));
1537+
// Change - list
1538+
allMoveSelectionConfigList.add(new ListChangeMoveSelectorConfig());
1539+
// Swap - list
1540+
allMoveSelectionConfigList.add(new ListSwapMoveSelectorConfig());
1541+
// KOpt - list
1542+
allMoveSelectionConfigList.add(new KOptListMoveSelectorConfig());
1543+
// Union of all moves
1544+
allMoveSelectionConfigList.add(new UnionMoveSelectorConfig(List.copyOf(allMoveSelectionConfigList)));
1545+
return allMoveSelectionConfigList;
1546+
}
1547+
1548+
@ParameterizedTest
1549+
@MethodSource("generateMultiEntityListAndBasicMoveConfig")
1550+
void solveCustomConfigurationMultiEntityWithListAndBasicVariables(MoveSelectorConfig moveSelectionConfig) {
15151551
// Construction Heuristic
15161552
var valueSelectorConfig = new ValueSelectorConfig("valueList")
15171553
.withId("valueList");
@@ -1526,18 +1562,11 @@ void solveCustomConfigurationMultiEntityWithListAndBasicVariables() {
15261562
var entityPlacerConfig = new QueuedEntityPlacerConfig();
15271563
var constructionHeuristicConfig =
15281564
new ConstructionHeuristicPhaseConfig().withEntityPlacerConfigList(valuePlacerConfig, entityPlacerConfig);
1529-
// Local Search
1530-
var moveSelectionConfigList = new ArrayList<MoveSelectorConfig>();
1531-
moveSelectionConfigList.add(new ChangeMoveSelectorConfig());
1532-
moveSelectionConfigList.add(new SwapMoveSelectorConfig());
1533-
moveSelectionConfigList.add(new ListChangeMoveSelectorConfig());
1534-
moveSelectionConfigList.add(new ListChangeMoveSelectorConfig());
1535-
moveSelectionConfigList.add(new ListSwapMoveSelectorConfig());
1536-
moveSelectionConfigList.add(new KOptListMoveSelectorConfig());
1565+
// Local search
15371566
var localSearchConfig =
15381567
new LocalSearchPhaseConfig()
1539-
.withMoveSelectorConfig(new UnionMoveSelectorConfig(moveSelectionConfigList))
1540-
.withTerminationConfig(new TerminationConfig().withStepCountLimit(16));
1568+
.withMoveSelectorConfig(moveSelectionConfig)
1569+
.withTerminationConfig(new TerminationConfig().withMoveCountLimit(40L));
15411570
// Solver Config
15421571
var solverConfig = PlannerTestUtils.buildSolverConfig(
15431572
TestdataListMultiEntitySolution.class, TestdataListMultiEntityFirstEntity.class,

core/src/test/java/ai/timefold/solver/core/testdomain/multivar/list/multientity/TestdataListMultiEntitySolution.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@
99
import ai.timefold.solver.core.api.domain.solution.ProblemFactCollectionProperty;
1010
import ai.timefold.solver.core.api.domain.valuerange.ValueRangeProvider;
1111
import ai.timefold.solver.core.api.score.buildin.simple.SimpleScore;
12+
import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
1213

1314
@PlanningSolution
1415
public class TestdataListMultiEntitySolution {
1516

17+
public static SolutionDescriptor<TestdataListMultiEntitySolution> buildSolutionDescriptor() {
18+
return SolutionDescriptor.buildSolutionDescriptor(TestdataListMultiEntitySolution.class,
19+
TestdataListMultiEntityFirstEntity.class, TestdataListMultiEntitySecondEntity.class);
20+
}
21+
1622
public static TestdataListMultiEntitySolution generateUninitializedSolution(int entityListSize, int valueListSize,
1723
int otherValueListSize) {
1824
var solution = new TestdataListMultiEntitySolution();

0 commit comments

Comments
 (0)