第10章 OptaPlanner Score インターフェイス
スコアは、Comparable インターフェイスを拡張した Score インターフェイスによって表されます。
public interface Score<...> extends Comparable<...> {
...
}
使用するスコア実装は、ユースケースによって異なります。スコアが単一の long 値に効率的に収まらない可能性があります。OptaPlanner にはいくつかの組み込みスコア実装がありますが、カスタムスコアを実装することもできます。ほとんどの使用例では、組み込みの HardSoftScore スコアが使用されます。

すべての Score 実装には initScore (int) もあります。これは主に OptaPlanner での内部使用を目的としており、初期化されていない計画変数の負の数です。ユーザーの観点から見ると、すべての計画変数を初期化する前に構築ヒューリスティックが終了しない限り、これは 0 です。この場合、Score.isSolutionInitialized() は false を返します。
スコアの実装 (例: HardSoftScore) は、ソルバーランタイム全体で同じである必要があります。スコアの実装は、ソリューションドメインクラスで設定されます。
@PlanningSolution
public class CloudBalance {
...
@PlanningScore
private HardSoftScore score;
}10.1. スコア計算における浮動小数点数
スコア計算では浮動小数点数型 float または double を使用しないでください。代わりに BigDecimal またはスケーリングされた Long を使用してください。浮動小数点数は 10 進数を正しく表すことができません。たとえば、double には値 0.05 を正しく含めることはできません。代わりに、最も近い表現可能な値が含まれます。浮動小数点数を使用する加算や減算を含む算術演算は、特に計画問題においては、次の図に示すように誤った決定につながります。

さらに、浮動小数点数の加算は結合的ではありません。
System.out.println( ((0.01 + 0.02) + 0.03) == (0.01 + (0.02 + 0.03)) ); // returns false
これは スコアの破損 につながります。
10 進数 (BigDecimal) にはこれらの問題はありません。
BigDecimal の算術演算は、int、long、または double の算術演算よりもかなり遅くなります。一部の実験では、スコアの計算に 5 倍の時間がかかります。
したがって、多くの場合、1 つのスコアの重みの すべての 数値を 10 の倍数で乗算し、スコアの重みがスケーリングされた int または long に収まるようにすることは価値があります。たとえば、すべての重みに 1000 を乗算すると、fuelCost 0.07 は、fuelCostMillis 70 になり、10 進数のスコア重みは使用されなくなります。