Skip to content

Commit 5cb5932

Browse files
committed
fix: only call RNG in Tabu search when necessary
1 parent a682654 commit 5cb5932

1 file changed

Lines changed: 22 additions & 12 deletions

File tree

core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/tabu/AbstractTabuAcceptor.java

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ public boolean isAccepted(LocalSearchMoveScope<Solution_> moveScope) {
143143
return false;
144144
}
145145
var acceptChance = calculateFadingTabuAcceptChance(tabuStepCount - workingTabuSize);
146-
var accepted = moveScope.getWorkingRandom().nextDouble() < acceptChance;
147-
if (accepted) {
146+
var accepted = isAccepted(moveScope, acceptChance);
147+
if (isAccepted(moveScope, tabuStepCount)) {
148148
logger.trace("{} Proposed move ({}) is fading tabu with acceptChance ({}) and is accepted.",
149149
logIndentation,
150150
moveScope.getMove(), acceptChance);
@@ -156,6 +156,26 @@ public boolean isAccepted(LocalSearchMoveScope<Solution_> moveScope) {
156156
return accepted;
157157
}
158158

159+
/**
160+
* @param fadingTabuStepCount {@code 0 < fadingTabuStepCount <= fadingTabuSize}
161+
* @return {@code 0.0 < acceptChance < 1.0}
162+
*/
163+
private double calculateFadingTabuAcceptChance(int fadingTabuStepCount) {
164+
// The + 1's are because acceptChance should not be 0.0 or 1.0
165+
// when (fadingTabuStepCount == 0) or (fadingTabuStepCount + 1 == workingFadingTabuSize)
166+
return (workingFadingTabuSize - fadingTabuStepCount) / ((double) (workingFadingTabuSize + 1));
167+
}
168+
169+
private boolean isAccepted(LocalSearchMoveScope<Solution_> moveScope, double acceptChance) {
170+
if (Double.compare(acceptChance, 0.0d) <= 0) {
171+
return false;
172+
} else if (Double.compare(acceptChance, 1.0d) >= 0) {
173+
return true;
174+
}
175+
// Only affect the RNG when we actually need to.
176+
return moveScope.getWorkingRandom().nextDouble() < acceptChance;
177+
}
178+
159179
private int locateMaximumTabuStepIndex(LocalSearchMoveScope<Solution_> moveScope) {
160180
var checkingTabus = findTabu(moveScope);
161181
var maximumTabuStepIndex = -1;
@@ -183,16 +203,6 @@ private int locateMaximumTabuStepIndex(LocalSearchMoveScope<Solution_> moveScope
183203
return maximumTabuStepIndex;
184204
}
185205

186-
/**
187-
* @param fadingTabuStepCount {@code 0 < fadingTabuStepCount <= fadingTabuSize}
188-
* @return {@code 0.0 < acceptChance < 1.0}
189-
*/
190-
protected double calculateFadingTabuAcceptChance(int fadingTabuStepCount) {
191-
// The + 1's are because acceptChance should not be 0.0 or 1.0
192-
// when (fadingTabuStepCount == 0) or (fadingTabuStepCount + 1 == workingFadingTabuSize)
193-
return (workingFadingTabuSize - fadingTabuStepCount) / ((double) (workingFadingTabuSize + 1));
194-
}
195-
196206
/**
197207
* @param moveScope
198208
* @return some tabu lists allow null, some don't; children will override

0 commit comments

Comments
 (0)