第 9 章 Red Hat build of OptaPlanner on Red Hat build of Quarkus: 一个 IANA timetable 快速开始指南


本指南指导您完成创建带有 OptaPlanner 约束智能(AI)的红帽构建的 Quarkus 应用程序的过程。您将构建 REST 应用程序,该应用程序针对领导和专业者进行了优化。

您的服务将通过 AI 遵循以下硬和软 调度限制,自动将附件实例分配给 TimeslotRoom 实例:

  • 空间最多可以同时有一个小时间。
  • 一个架构师可以同时参与一个小时间。
  • 每天最多可同时参与一个小时间。
  • 交互式人员更喜欢在单个房间参与。
  • 指导人员更喜欢参与较少的活动,并排解少量间的差距。

mathematly 认为是 NP 硬性问题。这意味着难以扩展。只需将所有可能的组合与括号一起进行迭代,可以在非平量数据集中使用数百万年,即使在超级计算器上也是如此。AI 约束解析器(如 OptaPlanner)有高级算法,可在合理的时间内提供最接近的解决方案。认为是合理的时间,这取决于您的问题的目标。

先决条件

  • 已安装 OpenJDK 11 或更高版本。Red Hat build of Open JDK 位于红帽客户门户网站中的 Software Downloads 页面中(需要登录)。
  • 已安装 Apache Maven 3.8 或更高版本。Maven 可从 Apache Maven 项目网站 获得。
  • 提供了 IDE,如 IntelliJ IDEA、VSCode、Ecli 或 NetBeans。
  • 红帽构建的 Quarkus 项目提供了一个 OptaPlanner。有关创建 OptaPlanner Red Hat build of Quarkus 项目的说明,请参阅 Red Hat Build of OptaPlanner 部分的"使用 OptaPlanner 和 Quarkus"。

9.1. 对域对象建模

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

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 是一个 规划实体

上图中的大部分字段都包含输入数据,但 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;
        }
    
    }
    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

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

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

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

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2025 Red Hat