搜索

18.2. 对域对象建模

download PDF

红帽构建的 OptaPlanner timetable 项目的目标是为每个课程分配时间插槽和房间。要做到这一点,请添加三个类,Timeslot , lesson , 和 Room,如下图所示:

时区类图显示 Timeslot

timeslot

Timeslot 类代表了在课程时的间隔,例如 Monday 10:30 - 11:30Tuesday 13:30 - 14:30。在这个示例中,所有时间插槽都有相同的持续时间,在 lunch 或其他间没有时间插槽。

时间段没有日期,因为高校计划每周都会重复。不需要 持续规划。一个 timeslot 被称为 问题,因为在 解决过程中没有 Timeslot 实例改变。此类类不需要任何 OptaPlanner 特定注解。

房间

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

房间 实例在解决时 不会改变,因此也 是一个问题

lesson

在短时间内,由 Lesson 类表示,教员向一组学员提供主题,例如 Math by A.Turing for 9th gradeChemistry by M.Curie for 10th grade。如果每周由同一生组多次学习一个主题,则有多个仅通过 id 区分的 lesson 实例。例如,第 9 个评级每周有 6 个数个。

在解决期间,OptaPlanner 更改了 Lesson 类的 timeslotroom 字段,为每个课程分配时间插槽和房间。因为 OptaPlanner 更改这些字段,所以 lesson 是一个 规划实体

Timetable 类图显示 Timeslot 和 Room 类与计划变量交互

上图中的大部分字段包含输入数据,但 orange 字段除外。一个 lesson 的 timeslotroom 字段在输入数据中未分配(空 ),并在输出数据中分配(非 null)。OptaPlanner 在解决过程中更改这些字段。此类字段称为计划变量。为了让 OptaPlanner 识别它们,timeslotroom 字段都需要 @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;
        }
    
    }

    注意 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;
        }
    
    }
  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;
        }
    
    }

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

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

    room 字段还具有 @PlanningVariable 注释,原因相同。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.