第4章 プランニングソリューションでのドメインオブジェクトの収集

TimeTable インスタンスは、単一データセットの TimeslotRoom および Lesson インスタンスをラップます。さらに、このインスタンスには、特定のプランニング変数の状態を持つ授業がすべて含まれているので、このインスタンスは プランニングソリューション となり、スコアが割り当てられます。

  • 授業がまだ割り当てられていない場合には、スコアが -4init/0hard/0soft のソリューションなど、初期化されていない ソリューションとなります。
  • ハード制約に違反する場合には、スコアが -2hard/-3soft のソリューションなど、実行不可 なソリューションとなります。
  • 全ハード制約に準拠している場合には、スコアが 0hard/-7soft など、実行可能 なソリューションとなります。

TimeTable クラスには、@PlanningSolution アノテーションが含まれているので Red Hat Business Optimizer はこのクラスに全入出力データが含まれていることを認識します。

具体的には、このクラスは問題の入力です。

  • 全時間枠が含まれる timeslotList フィールド

    • これは、解決時に変更されないので、問題ファクトリストです。
  • 全部屋が含まれる roomList フィールド

    • これは、解決時に変更されないので、問題ファクトリストです。
  • 全授業が含まれる lessonList フィールド

    • これは、解決時に変更されるので、プランニングエンティティーです。
    • Lesson:

      • timeslot および room フィールドの値は通常、null で未割り当てです。これらの値は、プランニング変数です。
      • subjectteacher および studentGroup などの他のフィールドは入力されます。これらのフィールドは問題プロパティーです。

ただし、このクラスはソリューションの出力でもあります。

  • Lesson インスタンスごとの lessonList フィールドには、解決後は null ではない timeslotroom フィールドが含まれます。
  • 出力ソリューションの質を表す score フィールド (例: 0hard/-5soft)

手順

src/main/java/com/example/domain/TimeTable.java クラスを作成します。

package com.example.domain;

import java.util.List;

import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningScore;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore;

@PlanningSolution
public class TimeTable {

    @ValueRangeProvider(id = "timeslotRange")
    @ProblemFactCollectionProperty
    private List<Timeslot> timeslotList;

    @ValueRangeProvider(id = "roomRange")
    @ProblemFactCollectionProperty
    private List<Room> roomList;

    @PlanningEntityCollectionProperty
    private List<Lesson> lessonList;

    @PlanningScore
    private HardSoftScore score;

    private TimeTable() {
    }

    public TimeTable(List<Timeslot> timeslotList, List<Room> roomList,
            List<Lesson> lessonList) {
        this.timeslotList = timeslotList;
        this.roomList = roomList;
        this.lessonList = lessonList;
    }

    // ********************************
    // Getters and setters
    // ********************************

    public List<Timeslot> getTimeslotList() {
        return timeslotList;
    }

    public List<Room> getRoomList() {
        return roomList;
    }

    public List<Lesson> getLessonList() {
        return lessonList;
    }

    public HardSoftScore getScore() {
        return score;
    }

}

値の範囲のプロバイダー

timeslotList フィールドは、値の範囲プロバイダーで、Timeslot インスタンスを保持し、Red Hat Business Optimizer がこのインスタンスを選択して、Lesson インスタンスの timeslot フィールドに割り当てることができます。timeslotList フィールドには、Lesson 内にある @PlanningVariablevalueRangeProviderRefsid を照合してこれらの 2 つを連携させる @ValueRangeProvider アノテーションが含まれています。

同じロジックに従い、roomList フィールドにも @ValueRangeProvider アノテーションが含まれています。

問題ファクトとプランニングエンティティーのプロパティー

さらに Red Hat Business Optimizer は 変更可能な Lesson インスタンス、さらに TimeTableConstraintProvider によるスコア計算に使用する TimeslotRoom インスタンスを取得する方法を把握しておく必要があります。

timeslotListroomList フィールドには @ProblemFactCollectionProperty アノテーションが含まれているので、TimeTableConstraintProvider はこれらのインスタンスから選択できます。

lessonList には @PlanningEntityCollectionProperty アノテーションが含まれているので、Red Hat Business Optimizer は解決時に変更でき、TimeTableConstraintProvider はこの中から選択することができます。