如何在OptaPlanner中优化含学生子组(选修课)的课程表?
OptaPlanner 班级选修子组课程表建模方案
核心建模思路
不拆分主班级,通过学生选修子组和课程受众范围两个维度,区分主干课(全员参与)和选修课(特定子组参与),在约束中控制课程冲突与受众匹配逻辑。
实体类设计
1. Student(学生实体)
包含两个核心属性:
mainClass:主班级标识(如"四年级"),用于关联主干课的受众范围electiveGroup:选修子组标识(如"4S"、"4E"),用于匹配选修课的受众
2. Course(课程定义)
区分课程类型并指定受众:
isCore:布尔值,标记是否为主干课程targetElectiveGroups:集合类型,存储该课程面向的选修子组- 主干课:集合包含主班级下所有选修子组(如
{"4S", "4E"}) - 选修课:集合仅包含对应子组(如science+对应
{"4S"},economics+对应{"4E"})
- 主干课:集合包含主班级下所有选修子组(如
3. Lesson(规划实体)
作为OptaPlanner的核心规划实体,代表一次具体授课,包含:
- 关联的
Course实例 - 规划变量:
timeSlot(时间槽)、room(教室) - 辅助属性:
teacher(授课教师)等
约束配置
硬约束(必须满足)
- 学生时间冲突约束:确保同一学生在同一时间没有两门需参与的课程
实现逻辑:对每个学生,检查同一时间槽内的所有Lesson,若Lesson的targetElectiveGroups包含该学生的electiveGroup,则不允许存在多个这样的Lesson。 - 选修课受众匹配约束:禁止选修子组外的学生被分配到对应选修课(通过课程的
targetElectiveGroups与学生electiveGroup的匹配实现) - 主干课完整性约束:主干课的Lesson必须覆盖主班级所有学生,不能拆分(通过将主干课的
targetElectiveGroups设为主班级所有子组来保证)
软约束(优化目标)
- 选修课尽量集中安排在连续时间段,减少学生切换场地的成本
- 教师授课时间分布均匀,避免连续多节授课
- 同一子组的选修课尽量使用同一教室,减少资源浪费
代码示例(约束实现)
用OptaPlanner的Constraint Streams实现学生时间冲突约束:
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; import org.optaplanner.core.api.score.stream.Constraint; import org.optaplanner.core.api.score.stream.ConstraintFactory; import org.optaplanner.core.api.score.stream.Joiners; public class TimetableConstraintProvider { public Constraint studentConflict(ConstraintFactory factory) { return factory.from(Student.class) // 关联学生需要参与的所有课程 .join(Lesson.class, Joiners.filtering((student, lesson) -> lesson.getCourse().getTargetElectiveGroups().contains(student.getElectiveGroup()))) // 关联同一学生同一时间的另一门课程 .join(Lesson.class, Joiners.equal((student, lesson1) -> student), Joiners.equal((student, lesson1) -> lesson1.getTimeSlot()), Joiners.lessThan(Lesson::getId)) // 避免重复配对 // 检查另一门课程是否也属于该学生的受众范围 .filter((student, lesson1, lesson2) -> lesson2.getCourse().getTargetElectiveGroups().contains(student.getElectiveGroup())) .penalize("Student has conflicting lessons", HardSoftScore.ONE_HARD); } }
额外注意事项
- 生成Lesson时,主干课仅需创建1个实例(覆盖所有子组),选修课需为每个目标子组创建独立实例(如4E的science-和economics+各对应1个Lesson)
- 若教室资源有限,可添加软约束:同一时间槽内,同一子组的选修课尽量使用相同教室,避免资源浪费
内容的提问来源于stack exchange,提问作者Berteh
相关产品推荐
相关产品推荐

