Interface Score<Score_ extends Score<Score_>>

Type Parameters:
Score_ - the actual score type to allow addition, subtraction and other arithmetic
All Superinterfaces:
Comparable<Score_>, Serializable
All Known Subinterfaces:
IBendableScore<Score_>
All Known Implementing Classes:
AbstractBendableScore, AbstractScore, BendableBigDecimalScore, BendableLongScore, BendableScore, HardMediumSoftBigDecimalScore, HardMediumSoftLongScore, HardMediumSoftScore, HardSoftBigDecimalScore, HardSoftLongScore, HardSoftScore, SimpleBigDecimalScore, SimpleLongScore, SimpleScore

public interface Score<Score_ extends Score<Score_>> extends Comparable<Score_>, Serializable
A Score is result of the score function (AKA fitness function) on a single possible solution.
  • Implementations must be immutable, preferably a Java record or even a primitive record, if the target JDK permits that.
  • Implementations must override initScore(), or else an endless loop occurs.
  • Implementations are allowed to optionally implement Pareto comparison and therefore slightly violate the transitive requirement of Comparable.compareTo(Object).
See Also:
  • Method Details

    • initScore

      default int initScore()
      The init score is the negative of the number of genuine planning variables set to null, unless null values are specifically allowed by PlanningVariable.allowsUnassigned() or PlanningListVariable.allowsUnassignedValues() Nulls are typically only allowed in over-constrained planning. In that case, there is no way how to tell a fully initialized solution with some values left unassigned, from a partially initialized solution where the initialization of some values wasn't yet attempted.

      During Comparable.compareTo(Object), init score is considered more important than the hard score. If the init score is 0 (which it usually is), the score's Object.toString() does not mention it.

      Returns:
      higher is better, always negative (except in statistical calculations); 0 if all planning variables are non-null, or if nulls are allowed.
    • getInitScore

      @Deprecated(forRemoval=true) default int getInitScore()
      Deprecated, for removal: This API element is subject to removal in a future version.
      Use initScore() instead.
      As defined by initScore().
    • withInitScore

      @NonNull Score_ withInitScore(int newInitScore)
      For example 0hard/-8soft with -7 returns -7init/0hard/-8soft.
      Parameters:
      newInitScore - always negative (except in statistical calculations), 0 if all planning variables are initialized
      Returns:
      equals score except that initScore() is set to newInitScore
    • add

      @NonNull Score_ add(@NonNull Score_ addend)
      Returns a Score whose value is (this + addend).
      Parameters:
      addend - value to be added to this Score
      Returns:
      this + addend
    • subtract

      @NonNull Score_ subtract(@NonNull Score_ subtrahend)
      Returns a Score whose value is (this - subtrahend).
      Parameters:
      subtrahend - value to be subtracted from this Score
      Returns:
      this - subtrahend, rounded as necessary
    • multiply

      @NonNull Score_ multiply(double multiplicand)
      Returns a Score whose value is (this * multiplicand). When rounding is needed, it should be floored (as defined by Math.floor(double)).

      If the implementation has a scale/precision, then the unspecified scale/precision of the double multiplicand should have no impact on the returned scale/precision.

      Parameters:
      multiplicand - value to be multiplied by this Score.
      Returns:
      this * multiplicand
    • divide

      @NonNull Score_ divide(double divisor)
      Returns a Score whose value is (this / divisor). When rounding is needed, it should be floored (as defined by Math.floor(double)).

      If the implementation has a scale/precision, then the unspecified scale/precision of the double divisor should have no impact on the returned scale/precision.

      Parameters:
      divisor - value by which this Score is to be divided
      Returns:
      this / divisor
    • power

      @NonNull Score_ power(double exponent)
      Returns a Score whose value is (this ^ exponent). When rounding is needed, it should be floored (as defined by Math.floor(double)).

      If the implementation has a scale/precision, then the unspecified scale/precision of the double exponent should have no impact on the returned scale/precision.

      Parameters:
      exponent - value by which this Score is to be powered
      Returns:
      this ^ exponent
    • negate

      default @NonNull Score_ negate()
      Returns a Score whose value is (- this).
      Returns:
      - this
    • abs

      @NonNull Score_ abs()
      Returns a Score whose value is the absolute value of the score, i.e. |this|.
    • zero

      @NonNull Score_ zero()
      Returns a Score, all levels of which are zero.
    • isZero

      default boolean isZero()
      Returns:
      true when this is equal to zero().
    • toLevelNumbers

      @NonNull Number @NonNull [] toLevelNumbers()
      Returns an array of numbers representing the Score. Each number represents 1 score level. A greater score level uses a lower array index than a lesser score level.

      When rounding is needed, each rounding should be floored (as defined by Math.floor(double)). The length of the returned array must be stable for a specific Score implementation.

      For example: -0hard/-7soft returns new int{-0, -7}

      The level numbers do not contain the initScore(). For example: -3init/-0hard/-7soft also returns new int{-0, -7}

    • toLevelDoubles

      default double @NonNull [] toLevelDoubles()
      As defined by toLevelNumbers(), only returns double[] instead of Number[].
    • isSolutionInitialized

      default boolean isSolutionInitialized()
      Checks if the PlanningSolution of this score was fully initialized when it was calculated. This only works for solutions where: For solutions which do allow unassigning values, initScore() is always zero and therefore this method always returns true.
      Returns:
      true if initScore() is 0
    • isFeasible

      boolean isFeasible()
      A PlanningSolution is feasible if it has no broken hard constraints and isSolutionInitialized() is true. Simple scores (SimpleScore, SimpleLongScore, SimpleBigDecimalScore) are always feasible, if their initScore() is 0.
      Returns:
      true if the hard score is 0 or higher and the initScore() is 0.
    • toShortString

      @NonNull String toShortString()
      Like Object.toString(), but trims score levels which have a zero weight. For example 0hard/-258soft returns -258soft.

      Do not use this format to persist information as text, use Object.toString() instead, so it can be parsed reliably.