-
Feature Request
-
Resolution: Done
-
Major
-
6.0.0.Beta2
-
None
When using the following combination of a Bendable score and a composite termination:
<scoreDirectorFactory> <scoreDefinitionType>BENDABLE</scoreDefinitionType> <bendableHardLevelCount>1</bendableHardLevelCount> <bendableSoftLevelCount>1</bendableSoftLevelCount> <scoreDrl>/ar/com/eox/palletbuild/rules/scoreRules.drl</scoreDrl> </scoreDirectorFactory> <termination> <terminationCompositionStyle>OR</terminationCompositionStyle> <scoreAttained>0/0</scoreAttained> <maximumSecondsSpend>600</maximumSecondsSpend> </termination>
I get the following exception at the the localSearch phase:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at org.optaplanner.core.api.score.buildin.bendable.BendableScore.getSoftScore(BendableScore.java:96)
at org.optaplanner.core.impl.score.buildin.bendable.BendableScoreDefinition.calculateTimeGradient(BendableScoreDefinition.java:124)
at org.optaplanner.core.impl.score.buildin.bendable.BendableScoreDefinition.calculateTimeGradient(BendableScoreDefinition.java:27)
at org.optaplanner.core.impl.termination.ScoreAttainedTermination.calculateSolverTimeGradient(ScoreAttainedTermination.java:50)
at org.optaplanner.core.impl.termination.OrCompositeTermination.calculateSolverTimeGradient(OrCompositeTermination.java:69)
at org.optaplanner.core.impl.termination.OrCompositeTermination.calculateSolverTimeGradient(OrCompositeTermination.java:69)
at org.optaplanner.core.impl.termination.PhaseToSolverTerminationBridge.calculatePhaseTimeGradient(PhaseToSolverTerminationBridge.java:80)
at org.optaplanner.core.impl.localsearch.DefaultLocalSearchSolverPhase.solve(DefaultLocalSearchSolverPhase.java:60)
at org.optaplanner.core.impl.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:190)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:155)
This seems to be caused by an error in these lines in BendableScoreDefinition:
int levelCount = hardLevelCount + softLevelCount; for (int i = 0; i < levelCount; i++) { if (i != (levelCount - 1)) { levelTimeGradientWeight *= recursiveTimeGradientWeight; } int startScoreLevel = (i < hardLevelCount) ? startScore.getHardScore(i) : startScore.getSoftScore(i); int endScoreLevel = (i < hardLevelCount) ? endScore.getHardScore(i) : endScore.getSoftScore(i); int scoreLevel = (i < hardLevelCount) ? score.getHardScore(i) : score.getSoftScore(i);
as the call to score.getSoftScore(...) is not taking into account that i is offset by hardLevelCount.