/*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.optaplanner.core.impl.score.buildin.bendable;
import java.util.Arrays;
import org.optaplanner.core.api.score.buildin.bendable.BendableScore;
import org.optaplanner.core.api.score.buildin.bendable.BendableScoreHolder;
import org.optaplanner.core.config.score.trend.InitializingScoreTrendLevel;
import org.optaplanner.core.impl.score.definition.AbstractBendableScoreDefinition;
import org.optaplanner.core.impl.score.trend.InitializingScoreTrend;
public class BendableScoreDefinition extends AbstractBendableScoreDefinition<BendableScore> {
public BendableScoreDefinition(int hardLevelsSize, int softLevelsSize) {
super(hardLevelsSize, softLevelsSize);
}
// ************************************************************************
// Worker methods
// ************************************************************************
@Override
public Class<BendableScore> getScoreClass() {
return BendableScore.class;
}
@Override
public BendableScore getZeroScore() {
return BendableScore.zero(hardLevelsSize, softLevelsSize);
}
@Override
public BendableScore parseScore(String scoreString) {
BendableScore score = BendableScore.parseScore(scoreString);
if (score.getHardLevelsSize() != hardLevelsSize) {
throw new IllegalArgumentException("The scoreString (" + scoreString
+ ") for the scoreClass (" + BendableScore.class.getSimpleName()
+ ") doesn't follow the correct pattern:"
+ " the hardLevelsSize (" + score.getHardLevelsSize()
+ ") doesn't match the scoreDefinition's hardLevelsSize (" + hardLevelsSize + ").");
}
if (score.getSoftLevelsSize() != softLevelsSize) {
throw new IllegalArgumentException("The scoreString (" + scoreString
+ ") for the scoreClass (" + BendableScore.class.getSimpleName()
+ ") doesn't follow the correct pattern:"
+ " the softLevelsSize (" + score.getSoftLevelsSize()
+ ") doesn't match the scoreDefinition's softLevelsSize (" + softLevelsSize + ").");
}
return score;
}
@Override
public BendableScore fromLevelNumbers(int initScore, Number[] levelNumbers) {
if (levelNumbers.length != getLevelsSize()) {
throw new IllegalStateException("The levelNumbers (" + Arrays.toString(levelNumbers)
+ ")'s length (" + levelNumbers.length + ") must equal the levelSize (" + getLevelsSize() + ").");
}
int[] hardScores = new int[hardLevelsSize];
for (int i = 0; i < hardLevelsSize; i++) {
hardScores[i] = (Integer) levelNumbers[i];
}
int[] softScores = new int[softLevelsSize];
for (int i = 0; i < softLevelsSize; i++) {
softScores[i] = (Integer) levelNumbers[hardLevelsSize + i];
}
return BendableScore.valueOfUninitialized(initScore, hardScores, softScores);
}
public BendableScore createScore(int... scores) {
return createScoreUninitialized(0, scores);
}
public BendableScore createScoreUninitialized(int initScore, int... scores) {
int levelsSize = hardLevelsSize + softLevelsSize;
if (scores.length != levelsSize) {
throw new IllegalArgumentException("The scores (" + Arrays.toString(scores)
+ ")'s length (" + scores.length
+ ") is not levelsSize (" + levelsSize + ").");
}
return BendableScore.valueOfUninitialized(initScore,
Arrays.copyOfRange(scores, 0, hardLevelsSize),
Arrays.copyOfRange(scores, hardLevelsSize, levelsSize));
}
@Override
public BendableScoreHolder buildScoreHolder(boolean constraintMatchEnabled) {
return new BendableScoreHolder(constraintMatchEnabled, hardLevelsSize, softLevelsSize);
}
@Override
public BendableScore buildOptimisticBound(InitializingScoreTrend initializingScoreTrend, BendableScore score) {
InitializingScoreTrendLevel[] trendLevels = initializingScoreTrend.getTrendLevels();
int[] hardScores = new int[hardLevelsSize];
for (int i = 0; i < hardLevelsSize; i++) {
hardScores[i] = (trendLevels[i] == InitializingScoreTrendLevel.ONLY_DOWN)
? score.getHardScore(i) : Integer.MAX_VALUE;
}
int[] softScores = new int[softLevelsSize];
for (int i = 0; i < softLevelsSize; i++) {
softScores[i] = (trendLevels[hardLevelsSize + i] == InitializingScoreTrendLevel.ONLY_DOWN)
? score.getSoftScore(i) : Integer.MAX_VALUE;
}
return BendableScore.valueOfUninitialized(0, hardScores, softScores);
}
@Override
public BendableScore buildPessimisticBound(InitializingScoreTrend initializingScoreTrend, BendableScore score) {
InitializingScoreTrendLevel[] trendLevels = initializingScoreTrend.getTrendLevels();
int[] hardScores = new int[hardLevelsSize];
for (int i = 0; i < hardLevelsSize; i++) {
hardScores[i] = (trendLevels[i] == InitializingScoreTrendLevel.ONLY_UP)
? score.getHardScore(i) : Integer.MIN_VALUE;
}
int[] softScores = new int[softLevelsSize];
for (int i = 0; i < softLevelsSize; i++) {
softScores[i] = (trendLevels[hardLevelsSize + i] == InitializingScoreTrendLevel.ONLY_UP)
? score.getSoftScore(i) : Integer.MIN_VALUE;
}
return BendableScore.valueOfUninitialized(0, hardScores, softScores);
}
}