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

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

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

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

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

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

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

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

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

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

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

  • Lesson インスタンスごとの lessonList フィールドには、解決後は null ではない timeslot フィールドと room フィールドが含まれます。
  • 出力ソリューションの品質を表す 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.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 インスタンスを保持し、OptaPlanner がこのインスタンスを選択して、Lesson インスタンスの timeslot フィールドに割り当てることができます。timeslotList フィールドには @ValueRangeProvider アノテーションがあり、id を、Lesson@PlanningVariablevalueRangeProviderRefs に一致させます。

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

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

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

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

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