@@ -143,6 +143,84 @@ void testPlacersForConstructionHeuristic() {
143143 assertThat (placerIterator .hasNext ()).isFalse ();
144144 }
145145
146+ @ Test
147+ void testPinnedPlacersForConstructionHeuristic () {
148+ var solutionDescriptor = TestdataListMultiVarSolution .buildSolutionDescriptor ();
149+ var configPolicy = new HeuristicConfigPolicy .Builder <TestdataListMultiVarSolution >()
150+ .withEnvironmentMode (PHASE_ASSERT )
151+ .withInitializingScoreTrend (new InitializingScoreTrend (new InitializingScoreTrendLevel [] { ANY }))
152+ .withSolutionDescriptor (solutionDescriptor )
153+ .withEntitySorterManner (DECREASING_DIFFICULTY_IF_AVAILABLE )
154+ .withValueSorterManner (INCREASING_STRENGTH_IF_AVAILABLE )
155+ .withReinitializeVariableFilterEnabled (true )
156+ .withInitializedChainedValueFilterEnabled (true )
157+ .withUnassignedValuesAllowed (true )
158+ .withRandom (new Random (0 ))
159+ .build ();
160+ var valueSelectorConfig = new ValueSelectorConfig ("valueList" )
161+ .withId ("valueList" );
162+ var mimicReplayingValueSelectorConfig = new ValueSelectorConfig ()
163+ .withMimicSelectorRef ("valueList" )
164+ .withVariableName ("valueList" );
165+ var valuePlacerConfig = new QueuedValuePlacerConfig ()
166+ .withValueSelectorConfig (valueSelectorConfig )
167+ .withMoveSelectorConfig (new ListChangeMoveSelectorConfig ()
168+ .withValueSelectorConfig (mimicReplayingValueSelectorConfig ));
169+ var entityPlacerConfig = new QueuedEntityPlacerConfig ();
170+ var placerConfig = new QueuedMultiplePlacerConfig ()
171+ .withPlacerConfigList (List .of (valuePlacerConfig , entityPlacerConfig ));
172+ var placer = EntityPlacerFactory .<TestdataListMultiVarSolution > create (placerConfig ).buildEntityPlacer (configPolicy );
173+
174+ var problem = TestdataListMultiVarSolution .generateUninitializedSolution (2 , 2 , 2 );
175+ // Pin the first entity
176+ problem .getEntityList ().get (0 ).setPinned (true );
177+ problem .getEntityList ().get (0 ).setPinnedIndex (2 );
178+ problem .getEntityList ().get (0 ).setBasicValue (problem .getOtherValueList ().get (0 ));
179+ problem .getEntityList ().get (0 ).setSecondBasicValue (problem .getOtherValueList ().get (0 ));
180+ problem .getEntityList ().get (0 ).setValueList (List .of (problem .getValueList ().get (0 )));
181+
182+ var solverScope = mock (SolverScope .class );
183+ var scoreDirector = mock (InnerScoreDirector .class );
184+ var random = new Random (0L );
185+ when (solverScope .getScoreDirector ()).thenReturn (scoreDirector );
186+ when (solverScope .getWorkingRandom ()).thenReturn (random );
187+ when (scoreDirector .getWorkingSolution ()).thenReturn (problem );
188+ when (scoreDirector .getWorkingSolution ()).thenReturn (problem );
189+ when (scoreDirector .getSolutionDescriptor ()).thenReturn (solutionDescriptor );
190+
191+ var supplyManager = VariableListenerSupport .create (scoreDirector );
192+ when (scoreDirector .getSupplyManager ()).thenReturn (supplyManager );
193+ supplyManager .linkVariableListeners ();
194+ supplyManager .resetWorkingSolution ();
195+
196+ placer .solvingStarted (solverScope );
197+ var phaseScope = mock (AbstractPhaseScope .class );
198+ when (phaseScope .getScoreDirector ()).thenReturn (scoreDirector );
199+ placer .phaseStarted (phaseScope );
200+
201+ var placerIterator = placer .iterator ();
202+
203+ // Step 1
204+ // 1 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 0 -> basicValue - Generated Other Value 0 -> secondBasicValue
205+ // 2 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 0 -> basicValue - Generated Other Value 1 -> secondBasicValue
206+ // 3 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 1 -> basicValue - Generated Other Value 0 -> secondBasicValue
207+ // 4 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 1 -> basicValue - Generated Other Value 1 -> secondBasicValue
208+ assertThat (placerIterator .hasNext ()).isTrue ();
209+ var counter = new MutableInt ();
210+ placerIterator .next ().iterator ().forEachRemaining (move -> counter .increment ());
211+ assertThat (counter .intValue ()).isEqualTo (4 );
212+
213+ // Accept the move -> 1 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 0 -> basicValue - Generated Other Value 0 -> secondBasicValue
214+ problem .getEntityList ().get (1 ).setValueList (List .of (problem .getValueList ().get (1 )));
215+ problem .getEntityList ().get (1 ).setBasicValue (problem .getOtherValueList ().get (0 ));
216+ problem .getEntityList ().get (1 ).setSecondBasicValue (problem .getOtherValueList ().get (0 ));
217+ // Update all variables
218+ supplyManager .resetWorkingSolution ();
219+ var stepScope = mock (AbstractStepScope .class );
220+ placer .stepEnded (stepScope );
221+ assertThat (placerIterator .hasNext ()).isFalse ();
222+ }
223+
146224 @ Test
147225 void testUnassignedPlacersForConstructionHeuristic () {
148226 var solutionDescriptor = TestdataUnassignedListMultiVarSolution .buildSolutionDescriptor ();
@@ -303,4 +381,96 @@ void testUnassignedPlacersForConstructionHeuristic() {
303381 placerIterator .next ().iterator ().forEachRemaining (move -> counter .increment ());
304382 assertThat (counter .intValue ()).isEqualTo (18 );
305383 }
384+
385+ @ Test
386+ void testPinnedUnassignedPlacersForConstructionHeuristic () {
387+ var solutionDescriptor = TestdataUnassignedListMultiVarSolution .buildSolutionDescriptor ();
388+ var configPolicy = new HeuristicConfigPolicy .Builder <TestdataUnassignedListMultiVarSolution >()
389+ .withEnvironmentMode (PHASE_ASSERT )
390+ .withInitializingScoreTrend (new InitializingScoreTrend (new InitializingScoreTrendLevel [] { ANY }))
391+ .withSolutionDescriptor (solutionDescriptor )
392+ .withEntitySorterManner (DECREASING_DIFFICULTY_IF_AVAILABLE )
393+ .withValueSorterManner (INCREASING_STRENGTH_IF_AVAILABLE )
394+ .withReinitializeVariableFilterEnabled (true )
395+ .withInitializedChainedValueFilterEnabled (true )
396+ .withUnassignedValuesAllowed (true )
397+ .withRandom (new Random (0 ))
398+ .build ();
399+ var valueSelectorConfig = new ValueSelectorConfig ("valueList" )
400+ .withId ("valueList" );
401+ var mimicReplayingValueSelectorConfig = new ValueSelectorConfig ()
402+ .withMimicSelectorRef ("valueList" )
403+ .withVariableName ("valueList" );
404+ var valuePlacerConfig = new QueuedValuePlacerConfig ()
405+ .withValueSelectorConfig (valueSelectorConfig )
406+ .withMoveSelectorConfig (new ListChangeMoveSelectorConfig ()
407+ .withValueSelectorConfig (mimicReplayingValueSelectorConfig ));
408+ var entityPlacerConfig = new QueuedEntityPlacerConfig ();
409+ var placerConfig = new QueuedMultiplePlacerConfig ()
410+ .withPlacerConfigList (List .of (valuePlacerConfig , entityPlacerConfig ));
411+ var placer = EntityPlacerFactory .<TestdataUnassignedListMultiVarSolution > create (placerConfig )
412+ .buildEntityPlacer (configPolicy );
413+
414+ var problem = TestdataUnassignedListMultiVarSolution .generateUninitializedSolution (2 , 2 , 2 );
415+ // Pin the first entity
416+ problem .getEntityList ().get (0 ).setPinned (true );
417+ problem .getEntityList ().get (0 ).setPinnedIndex (2 );
418+ problem .getEntityList ().get (0 ).setBasicValue (problem .getOtherValueList ().get (0 ));
419+ problem .getEntityList ().get (0 ).setSecondBasicValue (problem .getOtherValueList ().get (0 ));
420+ problem .getEntityList ().get (0 ).setValueList (List .of (problem .getValueList ().get (0 )));
421+
422+ var solverScope = mock (SolverScope .class );
423+ var scoreDirector = mock (InnerScoreDirector .class );
424+ var random = new Random (0L );
425+ when (solverScope .getScoreDirector ()).thenReturn (scoreDirector );
426+ when (solverScope .getWorkingRandom ()).thenReturn (random );
427+ when (scoreDirector .getWorkingSolution ()).thenReturn (problem );
428+ when (scoreDirector .getWorkingSolution ()).thenReturn (problem );
429+ when (scoreDirector .getSolutionDescriptor ()).thenReturn (solutionDescriptor );
430+
431+ var supplyManager = VariableListenerSupport .create (scoreDirector );
432+ when (scoreDirector .getSupplyManager ()).thenReturn (supplyManager );
433+ supplyManager .linkVariableListeners ();
434+ supplyManager .resetWorkingSolution ();
435+
436+ placer .solvingStarted (solverScope );
437+ var phaseScope = mock (AbstractPhaseScope .class );
438+ when (phaseScope .getScoreDirector ()).thenReturn (scoreDirector );
439+ placer .phaseStarted (phaseScope );
440+
441+ var placerIterator = placer .iterator ();
442+ // Step 1
443+ // 1 = Generated Value 1 -> Entity 1[0] - Entity 1 - null -> basicValue - Generated Other Value 0 -> secondBasicValue
444+ // 2 = Generated Value 1 -> Entity 1[0] - Entity 1 - null -> basicValue - Generated Other Value 1 -> secondBasicValue
445+ // 3 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 0 -> basicValue - Generated Other Value 0 -> secondBasicValue
446+ // 4 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 0 -> basicValue - Generated Other Value 1 -> secondBasicValue
447+ // 5 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 1 -> basicValue - Generated Other Value 0 -> secondBasicValue
448+ // 6 = Generated Value 1 -> Entity 1[0] - Entity 1 - Generated Other Value 1 -> basicValue - Generated Other Value 1 -> secondBasicValue
449+ // 7 = NoChange - Entity 1 - null -> basicValue - Generated Other Value 0 -> secondBasicValue
450+ // 8 = NoChange - Entity 1 - null -> basicValue - Generated Other Value 1 -> secondBasicValue
451+ // 9 = NoChange - Entity 1 - Generated Other Value 0 -> basicValue - Generated Other Value 0 -> secondBasicValue
452+ // 10 = NoChange - Entity 1 - Generated Other Value 0 -> basicValue - Generated Other Value 1 -> secondBasicValue
453+ // 11 = NoChange - Entity 1 - Generated Other Value 1 -> basicValue - Generated Other Value 0 -> secondBasicValue
454+ // 12 = NoChange - Entity 1 - Generated Other Value 1 -> basicValue - Generated Other Value 1 -> secondBasicValue
455+ assertThat (placerIterator .hasNext ()).isTrue ();
456+ var counter = new MutableInt ();
457+ placerIterator .next ().iterator ().forEachRemaining (move -> counter .increment ());
458+ assertThat (counter .intValue ()).isEqualTo (12 );
459+
460+ // Accept the move - 7 = NoChange - Entity 1 - null -> basicValue - Generated Other Value 0 -> secondBasicValue
461+ problem .getEntityList ().get (1 ).setSecondBasicValue (problem .getOtherValueList ().get (0 ));
462+ // Update all variables
463+ supplyManager .resetWorkingSolution ();
464+ var stepScope = mock (AbstractStepScope .class );
465+ placer .stepEnded (stepScope );
466+ counter .setValue (0 );
467+ // 1 = Generated Value 1 -> Entity 1[0] - null -> secondBasicValue
468+ // 2 = Generated Value 1 -> Entity 1[0] - Generated Other Value 0 -> secondBasicValue
469+ // 3 = Generated Value 1 -> Entity 1[0] - Generated Other Value 1 -> secondBasicValue
470+ // 4 = NoChange - null -> secondBasicValue
471+ // 5 = NoChange - Generated Other Value 0 -> secondBasicValue
472+ // 6 = NoChange - Generated Other Value 1 -> secondBasicValue
473+ placerIterator .next ().iterator ().forEachRemaining (move -> counter .increment ());
474+ assertThat (counter .intValue ()).isEqualTo (6 );
475+ }
306476}
0 commit comments