10.2. 对域对象建模


红帽构建的 OptaPlanner timetable 项目旨在为每个时间插槽和房间分配。要做到这一点,添加三个类、TimeslotLessonRoom,如下图所示:

Timeslot

Timeslot 类代表在教授课程时的时间间隔,例如: 星期一 10:30 - 11:30Tuesday 13:30 - 14:30。在这个示例中,所有时间插槽都具有相同的持续时间,在午餐或其他中断期间都没有时间插槽。

时间插槽没有日期,因为高校的计划仅每周重复。不需要 持续规划。一个时间被认为是个问题,因为在解决 过程中,实例不会发生改变。此类类不需要任何特定于 OptaPlanner 的注解。

room

Room 类代表教授课程的位置,例如 Room ARoom B。在这个示例中,所有房间都没有容量限制,它们可以适应所有课程。

空间 实例在解决过程中不会改变,因此 Room 也是 问题事实

courseon

在课程学习期间,教员将教授一门主题给一组学员,例如: A.Turing for 9th gradeChemistry,M.Curie 为 10th grade如果每周向同一学员组教授了多次主题,则有多个较少实例,只有 id 区分。例如,每周的第 9 个学分有 6 个学分。

在解决期间,OptaPlanner 会改变下课的计时和 房间 字段,以将每个上课时间分配到一个时间插槽和房间。 因为 OptaPlanner 更改了这些字段,所以 Lesson 是一个 计划实体

上图中的大多数字段都包含输入数据,但 orange 字段除外。在输入数据中未分配(空),并在输出数据中分配(非 null)字段的不计时和 房间 字段。在解决过程中,OptaPlanner 会更改这些字段。此类字段称为规划变量。为了使 OptaPlanner 能够识别它们,lot 和 room 字段都需要 @PlanningVariable 注解。它们包含类 Lesson,需要 @PlanningEntity 注释。

流程

  1. 创建 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;
        }
    
    }
    Copy to Clipboard Toggle word wrap

    注意 toString () 方法保持输出短,以便更轻松地读取 OptaPlanner 的 DEBUGTRACE 日志,如后文所示。

  2. 创建 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;
        }
    
    }
    Copy to Clipboard Toggle word wrap
  3. 创建 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;
        }
    
    }
    Copy to Clipboard Toggle word wrap

    Lesson 类具有 @PlanningEntity 注释,因此 OptaPlanner 知道该类在解决问题过程中发生了变化,因为它包含一个或多个规划变量。

    timeslot 字段具有 @PlanningVariable 注释,因此 OptaPlanner 知道它可以更改其值。要查找分配给此字段的潜在 Timeslot 实例,OptaPlanner 使用 valueRangeProviderRefs 属性连接到提供 List<Timeslot > 来选择的值范围供应商。有关值范围供应商的信息,请参阅 第 10.4 节 “在规划解决方案中收集域对象”

    room 字段也具有 @PlanningVariable 注释,理由相同。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat