1. 项目背景与核心需求
教务排课是高校教学管理中最复杂的工作之一。传统手工排课需要教务人员花费数周时间反复调整,仍难以避免教室冲突、教师时间冲突、课程分布不合理等问题。我在某高校信息化部门工作期间,曾亲眼目睹教务主任为排课连续加班两周,最终方案仍被多个院系投诉。
这个基于SpringBoot+Vue的自动排课系统正是为解决这一痛点而生。系统通过算法自动处理以下核心约束条件:
- 教室容量与课程人数匹配
- 教师时间可用性(避免同一教师多个课程时间重叠)
- 专业课程优先级(如核心课优先安排在黄金时段)
- 教室类型匹配(如实验课需要特殊实验室)
- 学生课程表合理性(避免连续空堂或过度集中)
2. 技术架构设计
2.1 后端技术栈选型
选择SpringBoot作为后端框架主要基于三点考量:
- 快速迭代:教务政策每年都有调整,需要快速响应需求变化。SpringBoot的约定优于配置特性可减少XML配置工作量。
- 算法集成:排课核心是约束满足问题(CSP),使用Java的Optaplanner引擎实现。实测在16核服务器上,200个班级的排课可在90分钟内完成。
- 事务保障:排课结果涉及多表关联写入,采用@Transactional注解确保数据一致性。
关键依赖示例:
xml复制<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-core</artifactId>
<version>8.29.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2.2 前端技术方案
Vue3+Element Plus的组合满足教务系统的特殊需求:
- 复杂表单处理:使用v-for动态渲染课程约束条件表单,结合VeeValidate实现三级联动校验
- 可视化展示:通过ECharts生成教室利用率热力图,帮助教务人员直观评估排课质量
- 权限控制:基于路由守卫实现院系-教务处两级权限隔离
典型排课结果展示组件:
vue复制<template>
<el-table :data="timetable" border>
<el-table-column
v-for="(time,index) in timeRanges"
:key="index"
:prop="time"
:label="time" />
</el-table>
</template>
3. 核心算法实现
3.1 排课问题建模
将排课抽象为三维资源分配问题:
- 时间维度:以30分钟为最小单位,每天划分为14个时段
- 空间维度:教室资源池包含普通教室、实验室、多媒体教室等
- 对象维度:课程、教师、班级三类实体的关联关系
使用Optaplanner的@PlanningEntity注解定义课程安排变量:
java复制@PlanningEntity
public class CourseAssignment {
@PlanningVariable(valueRangeProviderRefs = "timeRange")
private Timeslot timeslot;
@PlanningVariable(valueRangeProviderRefs = "roomRange")
private Classroom classroom;
// 硬约束:教室容量必须≥选课人数
@ConstraintWeight("教室容量")
private HardMediumSoftScore calculateCapacityScore() {
return classroom.getCapacity() < course.getStudentCount() ?
HardMediumSoftScore.ONE_HARD.negate() :
HardMediumSoftScore.ZERO;
}
}
3.2 约束规则配置
通过Drools规则引擎定义软硬约束:
drl复制rule "教师时间冲突"
when
$c1 : CourseAssignment(teacher == $t, $id : id != null)
$c2 : CourseAssignment(teacher == $t, id != $id,
timeslot == $c1.timeslot)
then
scoreHolder.addHardConstraintMatch(kcontext, -1);
end
rule "专业核心课优先时段"
when
$c : CourseAssignment(course.type == CourseType.MAJOR_CORE,
timeslot.hour < 10)
then
scoreHolder.addSoftConstraintMatch(kcontext, 1);
end
4. 系统特色功能
4.1 冲突可视化提示
当手动调整排课方案时,系统实时检测以下冲突类型:
- 红色警示:硬约束违反(如教室超容)
- 黄色提醒:软约束未达标(如专业课排在晚上)
- 蓝色建议:优化机会(同一专业课程间隔过远)
前端通过WebSocket接收实时校验结果:
javascript复制socket.onmessage = (event) => {
const conflicts = JSON.parse(event.data);
this.conflictList = conflicts.map(c => ({
type: c.level === 'HARD' ? 'error' : 'warning',
message: `${c.teacherName}的${c.courseName}在${c.time}冲突`
}));
};
4.2 多方案对比
系统支持生成多个备选方案,教务人员可从不同维度对比:
- 教室利用率标准差(衡量资源分配均衡性)
- 学生课程离散度(评估学习强度分布)
- 教师满意度(基于历史调整记录训练预测模型)
对比数据接口示例:
java复制@GetMapping("/compare")
public List<CompareDTO> compareSolutions(@RequestParam List<Long> solutionIds) {
return solutionIds.stream()
.map(id -> {
Timetable t = repository.findById(id);
return new CompareDTO(
t.getClassroomUtilizationStd(),
t.getCourseDistributionScore(),
t.getTeacherSatisfaction()
);
}).collect(Collectors.toList());
}
5. 部署与性能优化
5.1 服务器配置建议
根据实测数据给出硬件选型建议:
- 200个班级规模:4核8G内存,SSD存储
- 500个班级规模:8核16G内存,NVMe SSD
- 集群模式:使用Hazelcast实现Optaplanner的分布式求解
关键JVM参数:
bash复制java -jar -Xmx6g -XX:+UseG1GC \
-Dspring.profiles.active=prod \
-Doptaplanner.solver.termination.spentLimit=2h \
timetable.jar
5.2 前端性能提升
针对教务人员常用的IE11浏览器特别优化:
- 使用babel-polyfill处理ES6语法兼容
- 将ECharts换成轻量级的Chart.js
- 采用Vue的异步组件加载排课结果页
实测首屏加载时间从8s降至3s:
javascript复制const TimetableResult = () => import('./views/TimetableResult.vue');
6. 踩坑实录
6.1 算法调优陷阱
初期直接使用Optaplanner默认配置导致的问题:
- 问题现象:排课结果出现同一教室同一时间安排多门课程
- 根因分析:未正确配置@PlanningId导致求解器无法识别相同实体
- 解决方案:为所有参与规划的实体添加数据库主键映射
修正后的实体定义:
java复制@PlanningEntity
public class CourseAssignment {
@PlanningId
private Long id;
@ManyToOne
private Course course;
// 其他字段...
}
6.2 事务一致性难题
批量保存排课结果时遇到的典型问题:
- 问题场景:保存2000条排课记录时部分失败
- 错误表现:部分课程没有教室分配信息
- 根本原因:默认JPA批量操作未启用事务传播
- 最终方案:采用分批次提交策略
优化后的保存逻辑:
java复制@Transactional
public void saveInBatch(List<CourseAssignment> assignments) {
List<List<CourseAssignment>> batches = Lists.partition(assignments, 200);
batches.forEach(batch -> {
assignmentRepository.saveAll(batch);
entityManager.flush();
entityManager.clear();
});
}
7. 扩展方向
7.1 移动端适配
通过PWA技术实现教务人员移动审批:
- 使用Vue的响应式布局适配不同屏幕
- 添加Service Worker缓存关键API响应
- 采用Web App Manifest实现桌面图标安装
7.2 智能预测
基于历史数据训练预测模型:
- 使用TensorFlow Java预测教室需求波动
- 分析教师偏好的时间模式(如老教授倾向上午授课)
- 结合学生选课数据预测热门课程规模
