1717import ai .timefold .solver .core .impl .localsearch .decider .acceptor .lateacceptance .LateAcceptanceAcceptor ;
1818import ai .timefold .solver .core .impl .localsearch .decider .acceptor .simulatedannealing .SimulatedAnnealingAcceptor ;
1919import ai .timefold .solver .core .impl .localsearch .decider .acceptor .stepcountinghillclimbing .StepCountingHillClimbingAcceptor ;
20+ import ai .timefold .solver .core .impl .localsearch .decider .acceptor .tabu .AbstractTabuAcceptor ;
2021import ai .timefold .solver .core .impl .localsearch .decider .acceptor .tabu .EntityTabuAcceptor ;
2122import ai .timefold .solver .core .impl .localsearch .decider .acceptor .tabu .MoveTabuAcceptor ;
2223import ai .timefold .solver .core .impl .localsearch .decider .acceptor .tabu .ValueTabuAcceptor ;
@@ -58,11 +59,10 @@ public Acceptor<Solution_> buildAcceptor(HeuristicConfigPolicy<Solution_> config
5859 } else if (acceptorList .size () > 1 ) {
5960 return new CompositeAcceptor <>(acceptorList );
6061 } else {
61- throw new IllegalArgumentException (
62- "The acceptor does not specify any acceptorType (" + acceptorConfig .getAcceptorTypeList ()
63- + ") or other acceptor property.\n "
64- + "For a good starting values,"
65- + " see the docs section \" Which optimization algorithms should I use?\" ." );
62+ throw new IllegalArgumentException ("""
63+ The acceptor does not specify any acceptorType (%s) or other acceptor property.
64+ For good starting values, see the docs section "Which optimization algorithms should I use?"."""
65+ .formatted (acceptorConfig .getAcceptorTypeList ()));
6666 }
6767 }
6868
@@ -94,34 +94,35 @@ private Optional<StepCountingHillClimbingAcceptor<Solution_>> buildStepCountingH
9494 }
9595
9696 private Optional <EntityTabuAcceptor <Solution_ >> buildEntityTabuAcceptor (HeuristicConfigPolicy <Solution_ > configPolicy ) {
97+ var entityTabuSize = acceptorConfig .getEntityTabuSize ();
98+ var entityTabuRatio = acceptorConfig .getEntityTabuRatio ();
99+ var fadingEntityTabuSize = acceptorConfig .getFadingEntityTabuSize ();
100+ var fadingEntityTabuRatio = acceptorConfig .getFadingEntityTabuRatio ();
97101 if (acceptorTypeListsContainsAcceptorType (AcceptorType .ENTITY_TABU )
98- || acceptorConfig . getEntityTabuSize () != null || acceptorConfig . getEntityTabuRatio () != null
99- || acceptorConfig . getFadingEntityTabuSize () != null || acceptorConfig . getFadingEntityTabuRatio () != null ) {
102+ || entityTabuSize != null || entityTabuRatio != null
103+ || fadingEntityTabuSize != null || fadingEntityTabuRatio != null ) {
100104 var acceptor = new EntityTabuAcceptor <Solution_ >(configPolicy .getLogIndentation ());
101- if (acceptorConfig . getEntityTabuSize () != null ) {
102- if (acceptorConfig . getEntityTabuRatio () != null ) {
103- throw new IllegalArgumentException ("The acceptor cannot have both acceptorConfig.getEntityTabuSize() ("
104- + acceptorConfig . getEntityTabuSize () + ") and acceptorConfig.getEntityTabuRatio() ( "
105- + acceptorConfig . getEntityTabuRatio () + ")." );
105+ if (entityTabuSize != null ) {
106+ if (entityTabuRatio != null ) {
107+ throw new IllegalArgumentException (
108+ "The acceptor cannot have both entityTabuSize (%d) and entityTabuRatio (%f). "
109+ . formatted ( entityTabuSize , entityTabuRatio ) );
106110 }
107- acceptor .setTabuSizeStrategy (new FixedTabuSizeStrategy <>(acceptorConfig . getEntityTabuSize () ));
108- } else if (acceptorConfig . getEntityTabuRatio () != null ) {
109- acceptor .setTabuSizeStrategy (new EntityRatioTabuSizeStrategy <>(acceptorConfig . getEntityTabuRatio () ));
110- } else if (acceptorConfig . getFadingEntityTabuSize () == null && acceptorConfig . getFadingEntityTabuRatio () == null ) {
111+ acceptor .setTabuSizeStrategy (new FixedTabuSizeStrategy <>(entityTabuSize ));
112+ } else if (entityTabuRatio != null ) {
113+ acceptor .setTabuSizeStrategy (new EntityRatioTabuSizeStrategy <>(entityTabuRatio ));
114+ } else if (fadingEntityTabuSize == null && fadingEntityTabuRatio == null ) {
111115 acceptor .setTabuSizeStrategy (new EntityRatioTabuSizeStrategy <>(0.1 ));
112116 }
113- if (acceptorConfig . getFadingEntityTabuSize () != null ) {
114- if (acceptorConfig . getFadingEntityTabuRatio () != null ) {
117+ if (fadingEntityTabuSize != null ) {
118+ if (fadingEntityTabuRatio != null ) {
115119 throw new IllegalArgumentException (
116- "The acceptor cannot have both acceptorConfig.getFadingEntityTabuSize() ("
117- + acceptorConfig .getFadingEntityTabuSize ()
118- + ") and acceptorConfig.getFadingEntityTabuRatio() ("
119- + acceptorConfig .getFadingEntityTabuRatio () + ")." );
120+ "The acceptor cannot have both fadingEntityTabuSize (%d) and fadingEntityTabuRatio (%f)."
121+ .formatted (fadingEntityTabuSize , fadingEntityTabuRatio ));
120122 }
121- acceptor .setFadingTabuSizeStrategy (new FixedTabuSizeStrategy <>(acceptorConfig .getFadingEntityTabuSize ()));
122- } else if (acceptorConfig .getFadingEntityTabuRatio () != null ) {
123- acceptor .setFadingTabuSizeStrategy (
124- new EntityRatioTabuSizeStrategy <>(acceptorConfig .getFadingEntityTabuRatio ()));
123+ acceptor .setFadingTabuSizeStrategy (new FixedTabuSizeStrategy <>(fadingEntityTabuSize ));
124+ } else if (fadingEntityTabuRatio != null ) {
125+ acceptor .setFadingTabuSizeStrategy (new EntityRatioTabuSizeStrategy <>(fadingEntityTabuRatio ));
125126 }
126127 if (configPolicy .getEnvironmentMode ().isFullyAsserted ()) {
127128 acceptor .setAssertTabuHashCodeCorrectness (true );
@@ -132,46 +133,47 @@ private Optional<EntityTabuAcceptor<Solution_>> buildEntityTabuAcceptor(Heuristi
132133 }
133134
134135 private Optional <ValueTabuAcceptor <Solution_ >> buildValueTabuAcceptor (HeuristicConfigPolicy <Solution_ > configPolicy ) {
136+ var valueTabuSize = acceptorConfig .getValueTabuSize ();
137+ var fadingValueTabuSize = acceptorConfig .getFadingValueTabuSize ();
135138 if (acceptorTypeListsContainsAcceptorType (AcceptorType .VALUE_TABU )
136- || acceptorConfig . getValueTabuSize () != null || acceptorConfig . getFadingValueTabuSize () != null ) {
137- if (acceptorConfig . getValueTabuSize () == null && acceptorConfig . getFadingValueTabuSize () == null ) {
139+ || valueTabuSize != null || fadingValueTabuSize != null ) {
140+ if (valueTabuSize == null && fadingValueTabuSize == null ) {
138141 throw new IllegalArgumentException (
139142 "The acceptorType (%s) requires either valueTabuSize or fadingValueTabuSize to be configured."
140143 .formatted (AcceptorType .VALUE_TABU ));
141144 }
142145 var acceptor = new ValueTabuAcceptor <Solution_ >(configPolicy .getLogIndentation ());
143- if (acceptorConfig .getValueTabuSize () != null ) {
144- acceptor .setTabuSizeStrategy (new FixedTabuSizeStrategy <>(acceptorConfig .getValueTabuSize ()));
145- }
146- if (acceptorConfig .getFadingValueTabuSize () != null ) {
147- acceptor .setFadingTabuSizeStrategy (new FixedTabuSizeStrategy <>(acceptorConfig .getFadingValueTabuSize ()));
148- }
149- if (configPolicy .getEnvironmentMode ().isFullyAsserted ()) {
150- acceptor .setAssertTabuHashCodeCorrectness (true );
151- }
146+ configureFixedSizeTabuAcceptor (acceptor , configPolicy , valueTabuSize , fadingValueTabuSize );
152147 return Optional .of (acceptor );
153148 }
154149 return Optional .empty ();
155150 }
156151
152+ private static <Solution_ > void configureFixedSizeTabuAcceptor (AbstractTabuAcceptor <Solution_ > acceptor ,
153+ HeuristicConfigPolicy <Solution_ > configPolicy , Integer tabuSize , Integer fadingTabuSize ) {
154+ if (tabuSize != null ) {
155+ acceptor .setTabuSizeStrategy (new FixedTabuSizeStrategy <>(tabuSize ));
156+ }
157+ if (fadingTabuSize != null ) {
158+ acceptor .setFadingTabuSizeStrategy (new FixedTabuSizeStrategy <>(fadingTabuSize ));
159+ }
160+ if (configPolicy .getEnvironmentMode ().isFullyAsserted ()) {
161+ acceptor .setAssertTabuHashCodeCorrectness (true );
162+ }
163+ }
164+
157165 private Optional <MoveTabuAcceptor <Solution_ >> buildMoveTabuAcceptor (HeuristicConfigPolicy <Solution_ > configPolicy ) {
166+ var moveTabuSize = acceptorConfig .getMoveTabuSize ();
167+ var fadingMoveTabuSize = acceptorConfig .getFadingMoveTabuSize ();
158168 if (acceptorTypeListsContainsAcceptorType (AcceptorType .MOVE_TABU )
159- || acceptorConfig . getMoveTabuSize () != null || acceptorConfig . getFadingMoveTabuSize () != null ) {
160- if (acceptorConfig . getMoveTabuSize () == null && acceptorConfig . getFadingMoveTabuSize () == null ) {
169+ || moveTabuSize != null || fadingMoveTabuSize != null ) {
170+ if (moveTabuSize == null && fadingMoveTabuSize == null ) {
161171 throw new IllegalArgumentException (
162172 "The acceptorType (%s) requires either moveTabuSize or fadingMoveTabuSize to be configured."
163173 .formatted (AcceptorType .MOVE_TABU ));
164174 }
165175 var acceptor = new MoveTabuAcceptor <Solution_ >(configPolicy .getLogIndentation ());
166- if (acceptorConfig .getMoveTabuSize () != null ) {
167- acceptor .setTabuSizeStrategy (new FixedTabuSizeStrategy <>(acceptorConfig .getMoveTabuSize ()));
168- }
169- if (acceptorConfig .getFadingMoveTabuSize () != null ) {
170- acceptor .setFadingTabuSizeStrategy (new FixedTabuSizeStrategy <>(acceptorConfig .getFadingMoveTabuSize ()));
171- }
172- if (configPolicy .getEnvironmentMode ().isFullyAsserted ()) {
173- acceptor .setAssertTabuHashCodeCorrectness (true );
174- }
176+ configureFixedSizeTabuAcceptor (acceptor , configPolicy , moveTabuSize , fadingMoveTabuSize );
175177 return Optional .of (acceptor );
176178 }
177179 return Optional .empty ();
@@ -184,9 +186,10 @@ private Optional<MoveTabuAcceptor<Solution_>> buildMoveTabuAcceptor(HeuristicCon
184186 var acceptor = new SimulatedAnnealingAcceptor <Solution_ >();
185187 if (acceptorConfig .getSimulatedAnnealingStartingTemperature () == null ) {
186188 // TODO Support SA without a parameter
187- throw new IllegalArgumentException ("The acceptorType (" + AcceptorType .SIMULATED_ANNEALING
188- + ") currently requires a acceptorConfig.getSimulatedAnnealingStartingTemperature() ("
189- + acceptorConfig .getSimulatedAnnealingStartingTemperature () + ")." );
189+ throw new IllegalArgumentException (
190+ "The acceptorType (%s) currently requires a acceptorConfig.getSimulatedAnnealingStartingTemperature() (%s)."
191+ .formatted (AcceptorType .SIMULATED_ANNEALING ,
192+ acceptorConfig .getSimulatedAnnealingStartingTemperature ()));
190193 }
191194 acceptor .setStartingTemperature (
192195 configPolicy .getScoreDefinition ().parseScore (acceptorConfig .getSimulatedAnnealingStartingTemperature ()));
@@ -224,19 +227,20 @@ private Optional<GreatDelugeAcceptor<Solution_>> buildGreatDelugeAcceptor(Heuris
224227 var acceptor = new GreatDelugeAcceptor <Solution_ >();
225228 if (acceptorConfig .getGreatDelugeWaterLevelIncrementScore () != null ) {
226229 if (acceptorConfig .getGreatDelugeWaterLevelIncrementRatio () != null ) {
227- throw new IllegalArgumentException ("The acceptor cannot have both a "
228- + " acceptorConfig.getGreatDelugeWaterLevelIncrementScore() ("
229- + acceptorConfig .getGreatDelugeWaterLevelIncrementScore ()
230- + ") and a acceptorConfig.getGreatDelugeWaterLevelIncrementRatio() ("
231- + acceptorConfig .getGreatDelugeWaterLevelIncrementRatio () + ")." );
230+ throw new IllegalArgumentException ("" "
231+ The acceptor cannot have both a acceptorConfig.getGreatDelugeWaterLevelIncrementScore() (%s) \
232+ and a acceptorConfig.getGreatDelugeWaterLevelIncrementRatio() (%s)."""
233+ . formatted ( acceptorConfig .getGreatDelugeWaterLevelIncrementScore (),
234+ acceptorConfig .getGreatDelugeWaterLevelIncrementRatio ()) );
232235 }
233236 acceptor .setWaterLevelIncrementScore (
234237 configPolicy .getScoreDefinition ().parseScore (acceptorConfig .getGreatDelugeWaterLevelIncrementScore ()));
235238 } else if (acceptorConfig .getGreatDelugeWaterLevelIncrementRatio () != null ) {
236239 if (acceptorConfig .getGreatDelugeWaterLevelIncrementRatio () <= 0.0 ) {
237- throw new IllegalArgumentException ("The acceptorConfig.getGreatDelugeWaterLevelIncrementRatio() ("
238- + acceptorConfig .getGreatDelugeWaterLevelIncrementRatio ()
239- + ") must be positive because the water level should increase." );
240+ throw new IllegalArgumentException ("""
241+ The acceptorConfig.getGreatDelugeWaterLevelIncrementRatio() (%s) must be positive \
242+ because the water level should increase."""
243+ .formatted (acceptorConfig .getGreatDelugeWaterLevelIncrementRatio ()));
240244 }
241245 acceptor .setWaterLevelIncrementRatio (acceptorConfig .getGreatDelugeWaterLevelIncrementRatio ());
242246 } else {
0 commit comments