/*
* 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.api.score.buildin.simplelong;
import org.optaplanner.core.api.score.AbstractScore;
import org.optaplanner.core.api.score.Score;
/**
* This {@link Score} is based on 1 level of long constraints.
* <p>
* This class is immutable.
* @see Score
*/
public final class SimpleLongScore extends AbstractScore<SimpleLongScore> {
public static final SimpleLongScore ZERO = new SimpleLongScore(0, 0L);
public static SimpleLongScore parseScore(String scoreString) {
String[] scoreTokens = parseScoreTokens(SimpleLongScore.class, scoreString, "");
int initScore = parseInitScore(SimpleLongScore.class, scoreString, scoreTokens[0]);
long score = parseLevelAsLong(SimpleLongScore.class, scoreString, scoreTokens[1]);
return valueOfUninitialized(initScore, score);
}
public static SimpleLongScore valueOfUninitialized(int initScore, long score) {
return new SimpleLongScore(initScore, score);
}
public static SimpleLongScore valueOf(long score) {
return new SimpleLongScore(0, score);
}
// ************************************************************************
// Fields
// ************************************************************************
private final long score;
/**
* Private default constructor for default marshalling/unmarshalling of unknown frameworks that use reflection.
* Such integration is always inferior to the specialized integration modules, such as
* optaplanner-persistence-jpa, optaplanner-persistence-xstream, optaplanner-persistence-jaxb, ...
*/
@SuppressWarnings("unused")
private SimpleLongScore() {
super(Integer.MIN_VALUE);
score = Long.MIN_VALUE;
}
private SimpleLongScore(int initScore, long score) {
super(initScore);
this.score = score;
}
/**
* The total of the broken negative constraints and fulfilled positive constraints.
* Their weight is included in the total.
* The score is usually a negative number because most use cases only have negative constraints.
* @return higher is better, usually negative, 0 if no constraints are broken/fulfilled
*/
public long getScore() {
return score;
}
// ************************************************************************
// Worker methods
// ************************************************************************
@Override
public SimpleLongScore toInitializedScore() {
return initScore == 0 ? this : new SimpleLongScore(0, score);
}
@Override
public SimpleLongScore withInitScore(int newInitScore) {
assertNoInitScore();
return new SimpleLongScore(newInitScore, score);
}
@Override
public SimpleLongScore add(SimpleLongScore augment) {
return new SimpleLongScore(
initScore + augment.getInitScore(),
score + augment.getScore());
}
@Override
public SimpleLongScore subtract(SimpleLongScore subtrahend) {
return new SimpleLongScore(
initScore - subtrahend.getInitScore(),
score - subtrahend.getScore());
}
@Override
public SimpleLongScore multiply(double multiplicand) {
return new SimpleLongScore(
(int) Math.floor(initScore * multiplicand),
(long) Math.floor(score * multiplicand));
}
@Override
public SimpleLongScore divide(double divisor) {
return new SimpleLongScore(
(int) Math.floor(initScore / divisor),
(long) Math.floor(score / divisor));
}
@Override
public SimpleLongScore power(double exponent) {
return new SimpleLongScore(
(int) Math.floor(Math.pow(initScore, exponent)),
(long) Math.floor(Math.pow(score, exponent)));
}
@Override
public SimpleLongScore negate() {
return new SimpleLongScore(-initScore, -score);
}
@Override
public Number[] toLevelNumbers() {
return new Number[]{score};
}
@Override
public boolean equals(Object o) {
// A direct implementation (instead of EqualsBuilder) to avoid dependencies
if (this == o) {
return true;
} else if (o instanceof SimpleLongScore) {
SimpleLongScore other = (SimpleLongScore) o;
return initScore == other.getInitScore()
&& score == other.getScore();
} else {
return false;
}
}
@Override
public int hashCode() {
// A direct implementation (instead of HashCodeBuilder) to avoid dependencies
return ((17 * 37)
+ initScore) * 37
+ Long.valueOf(score).hashCode();
}
@Override
public int compareTo(SimpleLongScore other) {
// A direct implementation (instead of CompareToBuilder) to avoid dependencies
if (initScore != other.getInitScore()) {
return initScore < other.getInitScore() ? -1 : 1;
} else {
return Long.compare(score, other.getScore());
}
}
@Override
public String toShortString() {
return buildShortString((n) -> ((Long) n).longValue() != 0L, "");
}
@Override
public String toString() {
return getInitPrefix() + score;
}
@Override
public boolean isCompatibleArithmeticArgument(Score otherScore) {
return otherScore instanceof SimpleLongScore;
}
}