3.4. スコアの設定

Business Oprtimizer は、スコア が最も高い ソリューション を探します。この例では、HardSoftScore を使用し、Business Oprtimizer がハード制約に違反していない (またはハードウェア要件を満たす) ソリューションと、ソフト制約に違反する数が最も少ない (メンテナンスコストが最も低い) ソリューションを探します。

scoreComparisonCloudBalancing

当然ながら、Business Optimizer には、これらのドメイン固有のスコア制約についても指定する必要があります。Java 言語または Drools 言語を使用して制約を定義できます。

3.4.1. Java を使用したスコア計算の設定

スコア関数を定義する方法の 1 つに、Plain Java での EasyScoreCalculator インターフェース実装があります。

手順

  1. cloudBalancingSolverConfig.xml ファイルで設定を追加するか、アンコメントします。

      <scoreDirectorFactory>
        <easyScoreCalculatorClass>org.optaplanner.examples.cloudbalancing.optional.score.CloudBalancingEasyScoreCalculator</easyScoreCalculatorClass>
      </scoreDirectorFactory>
  2. calculateScore(Solution) メソッドを実装して HardSoftScore インスタンスを返します。

    例3.6 CloudBalancingEasyScoreCalculator.java

    public class CloudBalancingEasyScoreCalculator implements EasyScoreCalculator<CloudBalance> {
    
        /**
         * A very simple implementation. The double loop can easily be removed by using Maps as shown in
         * {@link CloudBalancingMapBasedEasyScoreCalculator#calculateScore(CloudBalance)}.
         */
        public HardSoftScore calculateScore(CloudBalance cloudBalance) {
            int hardScore = 0;
            int softScore = 0;
            for (CloudComputer computer : cloudBalance.getComputerList()) {
                int cpuPowerUsage = 0;
                int memoryUsage = 0;
                int networkBandwidthUsage = 0;
                boolean used = false;
    
                // Calculate usage
                for (CloudProcess process : cloudBalance.getProcessList()) {
                    if (computer.equals(process.getComputer())) {
                        cpuPowerUsage += process.getRequiredCpuPower();
                        memoryUsage += process.getRequiredMemory();
                        networkBandwidthUsage += process.getRequiredNetworkBandwidth();
                        used = true;
                    }
                }
    
                // Hard constraints
                int cpuPowerAvailable = computer.getCpuPower() - cpuPowerUsage;
                if (cpuPowerAvailable < 0) {
                    hardScore += cpuPowerAvailable;
                }
                int memoryAvailable = computer.getMemory() - memoryUsage;
                if (memoryAvailable < 0) {
                    hardScore += memoryAvailable;
                }
                int networkBandwidthAvailable = computer.getNetworkBandwidth() - networkBandwidthUsage;
                if (networkBandwidthAvailable < 0) {
                    hardScore += networkBandwidthAvailable;
                }
    
                // Soft constraints
                if (used) {
                    softScore -= computer.getCost();
                }
            }
            return HardSoftScore.valueOf(hardScore, softScore);
        }
    
    }

上記のコードを最適化し、Map を使用して processList を 1 回だけ反復した場合でも、インクリメンタルスコアの計算が行われないため、処理が遅いままです

これを修正するには、インクリメント Java スコア計算か、Drools スコア計算を使用します。インクリメント Java スコア計算については、本書では触れません。