第2章 ドメインオブジェクトのモデル化
Red Hat Business Optimizer の時間割プロジェクトの目標は、レッスンごとに時間枠と部屋に割り当てることです。これには、次の図に示すように、Timeslot
、Lesson
および Room
の 3 つのクラスを追加します。
Timeslot
Timeslot
クラスは、Monday 10:30 - 11:30
または Tuesday 13:30 - 14:30
など、授業の長さを表します。この例では、時間枠はすべて同じ長さ (期間) で、昼休みまたは他の休憩時間にはこのスロットはありません。
高校のスケジュールは毎週 (同じ内容が) 繰り返されるだけなので、時間枠には日付がありません。また、継続的プランニング は必要ありません。 解決時に Timeslot
インスタンスが変更しないので、Timeslot
は 問題ファクト と呼ばれます。このようなクラスには Red Hat Business Optimizer 固有のアノテーションは必要ありません。
Room
Room
クラスは、Room A
または Room B
など、授業の場所を表します。以下の例では、どの部屋も定員制限がなく、すべての授業に対応できます。
Room
インスタンスは解決時に変化しないので Room
は 問題ファクト でもあります。
Lesson
授業中 (Lesson
クラスで表現)、教師は複数の生徒に Math by A.Turing for 9th grade
または Chemistry by M.Curie for 10th grade
などの教科を指導します。ある教科が同じ生徒グループに、同じ教師により複数回、指導される場合には、Lesson
インスタンスが複数使用されますが、それらは id
で識別可能です。たとえば、9 年生の場合には、1 週間に 6 回数学の授業があります。
解決中に Red Hat Business Optimizer は、Lesson
クラスの timeslot
と room
フィールドを変更して、各授業を、時間枠 1 つ、部屋 1 つに割り当てます。Red Hat Business Optimizer はこれらのフィールドを変更するので、Lesson
は プランニングエンティティー となります。
前図のフィールドにはオレンジのフィールドを除きほぼ、入力データが含まれます。 授業の timeslot
と room
フィールドは、入力データに割り当てられておらず (null
)、出力データに割り当てられて (null
ではない) います。Red Hat Business Optimizer は、解決時にこれらのフィールドを変更します。このようなフィールドはプランニング変数と呼ばれます。このフィールドを Red Hat Business Optimizer に認識させるには、timeslot
と room
のフィールドに @PlanningVariable
アノテーションが必要です。このフィールドに含まれるLesson
クラスには、@PlanningEntity
アノテーションが必要です。
手順
src/main/java/com/example/domain/Timeslot.java
クラスを作成します。package com.example.domain; import java.time.DayOfWeek; import java.time.LocalTime; public class Timeslot { private DayOfWeek dayOfWeek; private LocalTime startTime; private LocalTime endTime; private Timeslot() { } public Timeslot(DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime) { this.dayOfWeek = dayOfWeek; this.startTime = startTime; this.endTime = endTime; } @Override public String toString() { return dayOfWeek + " " + startTime.toString(); } // ******************************** // Getters and setters // ******************************** public DayOfWeek getDayOfWeek() { return dayOfWeek; } public LocalTime getStartTime() { return startTime; } public LocalTime getEndTime() { return endTime; } }
後述しているように、
toString()
メソッドで出力を短くするので、Red Hat Business Optimizer のDEBUG
またはTRACE
ログの読み取りが簡単になっています。src/main/java/com/example/domain/Room.java
クラスを作成します。package com.example.domain; public class Room { private String name; private Room() { } public Room(String name) { this.name = name; } @Override public String toString() { return name; } // ******************************** // Getters and setters // ******************************** public String getName() { return name; } }
src/main/java/com/example/domain/Lesson.java
クラスを作成します。package com.example.domain; import org.optaplanner.core.api.domain.entity.PlanningEntity; import org.optaplanner.core.api.domain.variable.PlanningVariable; @PlanningEntity public class Lesson { private Long id; private String subject; private String teacher; private String studentGroup; @PlanningVariable(valueRangeProviderRefs = "timeslotRange") private Timeslot timeslot; @PlanningVariable(valueRangeProviderRefs = "roomRange") private Room room; private Lesson() { } public Lesson(Long id, String subject, String teacher, String studentGroup) { this.id = id; this.subject = subject; this.teacher = teacher; this.studentGroup = studentGroup; } @Override public String toString() { return subject + "(" + id + ")"; } // ******************************** // Getters and setters // ******************************** public Long getId() { return id; } public String getSubject() { return subject; } public String getTeacher() { return teacher; } public String getStudentGroup() { return studentGroup; } public Timeslot getTimeslot() { return timeslot; } public void setTimeslot(Timeslot timeslot) { this.timeslot = timeslot; } public Room getRoom() { return room; } public void setRoom(Room room) { this.room = room; } }
Lesson
クラスには@PlanningEntity
アノテーションが含まれており、その中にプランニング変数が 1 つ以上含まれているので、Red Hat Business Optimizer はこのクラスが解決時に変化することを認識します。timeslot
フィールドには、@PlanningVariable
アノテーションがあるので Red Hat Business Optimizer は、このフィールドの値が変化することを認識しています。このフィールドに割り当てることのできるTimeslot
インスタンスを見つけ出すために、Red Hat Business Optimizer はvalueRangeProviderRefs
プロパティーを使用して値の範囲プロバイダーと連携し、List<Timeslot>
を提供して選択できるようにします。値の範囲プロバイダーに関する詳細は、4章プランニングソリューションでのドメインオブジェクトの収集を参照してください。room
フィールドにも、同じ理由で@PlanningVariable
アノテーションが含まれます。