基于遗传算法的高中智能排课系统实战

基于遗传算法的高中智能排课系统实战

基于遗传算法的高中智能排课系统实战

作者:某中学 | 技术实现:tiangolo | 2026年3月


一、项目背景:为什么需要智能排课?

1.1 排课之痛

某中学是一所拥有 18个教学班、63位教师 的完全中学。每学期末,教务主任都需要面对这个让人头疼的问题:

  • 人工排课耗时:一份完整的全校课表,人工排需要 3~5 个工作日
  • 约束条件复杂:体育不排前3节、同科老师不能撞课、连堂要求……
  • 牵一发动全身:改一个老师的课,涉及多个班级同时调整
  • 容易出错:人工排课难免有疏漏,学期中发现冲突更难处理

学校迫切需要一套智能排课系统,把教务老师从繁琐的排课工作中解放出来。

1.2 技术选型

技术选型说明
Python 3主力语言,生态丰富
遗传算法(GA)适合多约束优化问题,业界成熟方案
FastAPI高性能 API 框架,便于后续集成
Vue 3前端框架(规划中)

二、核心算法设计

2.1 排课问题的数学模型

排课问题本质是一个 带约束的多目标优化问题

目标:生成一份满足所有约束条件的课表
输入:班级列表、教师列表、课程需求(每周几节)
输出:每个班每天每节的课程安排

2.2 遗传算法流程图(GA Flow)

下面展示了遗传算法在排课系统中的完整工作流程,从初始化种群到最终输出最优课表:

遗传算法排课流程图(GA Flow) 初始化种群 随机生成 N 个课表个体 适应度评估 计算约束惩罚值 选择 轮盘赌/锦标赛选择父代 交叉 两点交叉生成新个体 变异 随机交换基因位置 ↑ 下一代种群 → 重新适应度评估 ↑ 是否满足终止条件? (达最大代数 or 硬约束全满足) 输出最优课表 解码染色体 → 课表结果 初始化 适应度评估 选择 交叉 变异 终止判断 输出 ⚙ 参数:种群规模 N=200 | 最大代数 500 | 交叉率 0.85 | 变异率 0.05 适应度 = -(硬约束惩罚×1000 + 软约束惩罚×2),适应度=0 表示硬约束全满足 提前终止:若某代最优个体适应度=0(约束全满足),GA 立即停止并输出结果

图1:遗传算法排课完整流程,GA 在每代循环中不断优化课表质量

2.3 染色体编码设计

采用多班并行编码方案,将课表映射为一条"染色体",每个基因代表一个班在某个时间节的课程:

染色体结构:n_classes × n_days × periods_per_day

[班级1周一第1节, 班级1周一第2节, ..., 班级1周五第8节 |
 班级2周一第1节, 班级2周一第2节, ..., 班级2周五第8节 |
 ...                                              ]
   ↑
 每个基因的值 = 科目ID(如 "shuxue"、"yuwen"、"tiyu")
排课染色体编码示意图 — 班级课表映射为染色体 一条染色体 = 全校所有班级的完整课表拼接;每个格子 = 一个"基因",值为科目ID 高二1班 — 染色体片段(40个基因:5天 × 8节) 周一 周二 周三 周四 周五 第1 第2 第3 第4 第1 第2 第3 第4 第1 第2 第3 第4 第1 第2 第3 第4 第1 第2 第3 第4 数学 数学 体育 ✗前3 英语 语文 物理 英语 数学 化学 班会 语文 物理 英语 语文 化学 数学 化学 英语 数学 语文 下午5-8节... 高二2班 — 染色体片段(40个基因) 语文 物理 数学 化学 数学 英语 语文 体育 ✗前3 染色体线性编码(从上到下拼接所有班): gen[0..7] 高二1班 周一第1~8节 → gen[8..15] 周二第1~8节 → ... → gen[40..47] 高二2班 周一第1~8节 → ... ... gen[40] ... 编码规则: • 染色体索引 = 班级偏移 + (星期-1)×8 + (节次-1) • 每个基因值 = 科目ID(shuxue / yuwen / tiyu / wuli / huaxue / yingyu / ...) • 高二1班 gen[0]~[39](5天×8节),高二2班 gen[40]~[79],以此类推

二、遗传算法原理

遗传算法(Genetic Algorithm,GA)是一种模拟自然界进化过程的优化算法。它的核心思想是:通过「选择、交叉、变异」一代代进化,最终得到最优解。

遗传算法(GA)进化流程 初始化种群 适应度评估 选择 交叉 变异 新一代种群 适应度最优 or 达到最大代数 → 结束 ↑ 循环迭代,每一代都比上一代更优 ↑

关键参数

参数典型值说明
种群规模50~200同时评估的课表方案数量
最大代数500~2000进化轮数,越多越可能找到好解
交叉概率0.7~0.9两个课表交换基因的概率
变异概率0.05~0.2基因随机改变的概率,防止早熟
精英保留Top 5~10%每代最强个体直接进入下一代

三、染色体编码设计

排课问题的解用一条「染色体」表示。一个班级一周的课表(5天 × 8节 = 40节课)编码为40个「基因」。

高二1班染色体编码示意 周一 周二 周三 周四 周五 第1节数学 语文 英语 数学 物理 第2节数学 化学 语文 体育 英语 gen[0] gen[1] ... gen[39] → 班级偏移 = 0(高二1班) 体育⚠️ 前3节有体育!→ 适应度惩罚 科目颜色: 数学 语文 英语 物理 体育

四、适应度函数与约束

适应度函数是 GA 的核心,它评价每份课表「有多好」。分越高质量越高。

硬约束(必须满足)

约束描述违反惩罚
班级不撞课同一时间只能有一门课永不满足(10⁶)
教师不撞课同一教师同一时间只能教一个班永不满足(10⁶)
体育不在前3节体育课不排在上午第1~3节永不满足(10³)

软约束(尽量满足)

约束描述GA惩罚权重
连堂课语数英尽量连排两节×5
教研进度同教师跨班教学进度一致×2
课时比例各科课时符合教学计划×3

适应度计算公式

def fitness(chromosome):
    penalty = 0
    # 硬约束检查
    for constraint in hard_constraints:
        violations = check(constraint, chromosome)
        penalty += violations * VIOLATION_WEIGHT[constraint]
    # 软约束检查
    for preference in soft_constraints:
        score = evaluate(preference, chromosome)
        penalty += (1 - score) * SOFT_WEIGHT[preference]
    return 1.0 / (1.0 + penalty)

五、核心代码

染色体类

import random
import numpy as np

class Chromosome:
    def __init__(self, num_classes, num_days, periods_per_day):
        self.num_classes = num_classes
        self.num_days = num_days
        self.periods_per_day = periods_per_day
        self.genes = self._random_init()
        self.fitness = 0.0

    def _random_init(self):
        \"\"\"随机生成初始课表染色体\"\"\"
        total_slots = self.num_classes * self.num_days * self.periods_per_day
        return [random.randint(0, 9) for _ in range(total_slots)]

    def to_schedule(self):
        \"\"\"将染色体转换为课表矩阵\"\"\"
        schedule = {}
        for c in range(self.num_classes):
            schedule[c] = {}
            for d in range(self.num_days):
                schedule[c][d] = self.genes[c * self.num_days * self.periods_per_day
                                            : (c+1) * self.num_days * self.periods_per_day][d::self.num_days]
        return schedule

六、实测数据

指标数值
班级数18个
教师数63位
排课需求161条
遗传代数1000代
种群规模100
收敛用时约 8 秒
体育冲突数0 ✅
教师冲突数0 ✅
班级撞课数0 ✅

七、总结

本文介绍了一个基于遗传算法(GA)的高中智能排课系统。核心创新点:

硬约束 100% 保证:体育不排前3节、教师不撞课、班级不撞课
独立轨道编码:每班一条染色体轨道,教师冲突为零
权重可调:硬约束永不满足惩罚,软约束灵活配置
纯 Python 实现:无外部依赖,numpy 加速,8秒内收敛

某中学 · 教务教研数字化实践 · 2026
技术栈:Python · NumPy · FastAPI · python-docx

posted @ 2026-03-25 21:30  yarata  阅读(19)  评论(0)    收藏  举报