14.2. 对域对象建模


红帽构建的 OptaPlanner 时间项目的目标是将每项分配给一个时间插槽和房间。要做到这一点,添加三个类: Timeslotinit on 和 Room,如下图所示:

显示 Timeslot 的时间表类图

timeslot

Timeslot 类代表当减少活动为过期的时间间隔时,例如,Monday 10:30 - 11:30Tuesday 13:30 - 14:30。在这个示例中,所有时间段都有相同的持续时间,在 lunch 或其他中断过程中没有时间插槽。

一个时间插槽没有日期,因为每周计划只重复一次。不需要 持续规划。timeslot 被称为 问题事实,因为公司不会更改 Timeslot 实例。此类类不需要任何特定于 OptaPlanner 的注解。

房间

Room 类代表更小活动的位置,例如 Room ARoom B。在本例中,所有房间都没有容量限制,它们可以容纳所有定义。

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

lesson

在小时间中,由周一类代表,受一组参与者代表的规定,例如,A.Turing for 9th rating 或 Chemistry by M.Curie 代表第 10 等级如果一个主题是按同一站组相同的每周的多次,则有多个仅可通过 id 区分的实例。例如,第 9 等级每周有六个数学。

在 OptaPlanner 期间,OptaPlanner 会更改周一类的 timeslotroom 字段,以将每个小时间分配给一个时间插槽和房间。因为 OptaPlanner 更改这些字段,因此 Apple on 是一个 规划实体

时间表类图显示与规划变量交互的 Timeslot 和 Room 类

上图中的大部分字段都包含输入数据,但 orange 字段除外。在输入数据中取消分配较少的 timeslotroom 字段,并在输出数据中分配(而非 null)。OptaPlanner 在参与过程中会更改这些字段。此类字段称为 规划变量。为了使 OptaPlanner 能够识别它们,timeslotroom 字段都需要 @PlanningVariable 注释。它们包含类属性需要 @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;
        }
    
    }

    bring on 类有一个 @PlanningEntity 注释,因此 OptaPlanner 知道该类在周五期间发生了变化,因为它包含一个或多个规划变量。

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

    由于同样原因,room 字段也有一个 @PlanningVariable 注释。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.