小学课程表自动生成:基于遗传算法的Python代码实现
以下是使用遗传算法排课的Python代码,将每天每节课的课程表输出到Excel中:
import pandas as pd
import numpy as np
import random
# 定义班级、科目和老师信息
grades = [1, 2, 3, 4, 5, 6]
subjects = ['语文', '数学', '英语', '体育', '科学', '音乐', '美术']
teachers = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
# 定义每个年级每个科目的课时量
class_hours = {
1: {'语文': 4, '数学': 4, '英语': 3, '体育': 2, '科学': 2, '音乐': 1, '美术': 1},
2: {'语文': 4, '数学': 4, '英语': 3, '体育': 2, '科学': 2, '音乐': 1, '美术': 1},
3: {'语文': 4, '数学': 4, '英语': 3, '体育': 2, '科学': 2, '音乐': 1, '美术': 1},
4: {'语文': 4, '数学': 4, '英语': 3, '体育': 2, '科学': 2, '音乐': 1, '美术': 1},
5: {'语文': 4, '数学': 4, '英语': 3, '体育': 2, '科学': 2, '音乐': 1, '美术': 1},
6: {'语文': 4, '数学': 4, '英语': 3, '体育': 2, '科学': 2, '音乐': 1, '美术': 1}
}
# 定义每个老师每个科目的课时量
teacher_hours = {
'A': {'语文': 6, '数学': 4, '英语': 4, '体育': 2, '科学': 2, '音乐': 2, '美术': 2},
'B': {'语文': 4, '数学': 6, '英语': 4, '体育': 2, '科学': 2, '音乐': 2, '美术': 2},
'C': {'语文': 4, '数学': 4, '英语': 6, '体育': 2, '科学': 2, '音乐': 2, '美术': 2},
'D': {'语文': 4, '数学': 4, '英语': 4, '体育': 4, '科学': 2, '音乐': 2, '美术': 2},
'E': {'语文': 4, '数学': 4, '英语': 4, '体育': 2, '科学': 4, '音乐': 2, '美术': 2},
'F': {'语文': 4, '数学': 4, '英语': 4, '体育': 2, '科学': 2, '音乐': 4, '美术': 2},
'G': {'语文': 4, '数学': 4, '英语': 4, '体育': 2, '科学': 2, '音乐': 2, '美术': 4},
'H': {'语文': 4, '数学': 4, '英语': 4, '体育': 2, '科学': 2, '音乐': 2, '美术': 2},
'I': {'语文': 4, '数学': 4, '英语': 4, '体育': 2, '科学': 2, '音乐': 2, '美术': 2},
'J': {'语文': 4, '数学': 4, '英语': 4, '体育': 2, '科学': 2, '音乐': 2, '美术': 2},
'K': {'语文': 4, '数学': 4, '英语': 4, '体育': 2, '科学': 2, '音乐': 2, '美术': 2}
}
# 定义遗传算法参数
POP_SIZE = 50 # 种群数量
CROSS_RATE = 0.8 # 交叉概率
MUTATION_RATE = 0.01 # 突变概率
N_GENERATIONS = 100 # 迭代次数
# 初始化课程表
def init_schedule():
schedule = []
for _ in range(6): # 6个年级
grade_schedule = []
for _ in range(5): # 一周5天
day_schedule = []
for _ in range(7): # 每天7节课
day_schedule.append('')
grade_schedule.append(day_schedule)
schedule.append(grade_schedule)
return schedule
# 检查是否满足每个科目的课时量要求
def check_hours(schedule):
for grade in range(6):
for day in range(5):
for hour in range(7):
subject = schedule[grade][day][hour]
if subject != '':
class_hour = class_hours[grade+1][subject]
if class_hour <= 0:
return False
class_hours[grade+1][subject] -= 1
return True
# 计算适应度函数
def get_fitness(schedule):
fitness = 0
for grade in range(6):
for day in range(5):
for hour in range(7):
subject = schedule[grade][day][hour]
if subject != '':
teacher = subject_teacher[subject]
teacher_hour = teacher_hours[teacher][subject]
if teacher_hour <= 0:
fitness -= 1
else:
teacher_hours[teacher][subject] -= 1
fitness += 1
return fitness
# 交叉繁殖
def crossover(parents):
children = []
for parent in parents:
child = parent.copy()
if np.random.rand() < CROSS_RATE:
cross_day = np.random.randint(0, 5) # 随机选择一天进行交叉
child[cross_day] = parents[1 - parents.index(parent)][cross_day]
children.append(child)
return children
# 突变
def mutate(children):
for child in children:
if np.random.rand() < MUTATION_RATE:
mutate_day = np.random.randint(0, 5) # 随机选择一天进行突变
mutate_hour1, mutate_hour2 = np.random.choice(range(7), size=2, replace=False) # 随机选择两个课时进行交换
child[mutate_day][mutate_hour1], child[mutate_day][mutate_hour2] = child[mutate_day][mutate_hour2], child[mutate_day][mutate_hour1]
return children
# 轮盘赌选择
def select(population, fitness):
idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True, p=(fitness + 1) / (fitness + 1).sum())
return [population[i] for i in idx]
# 主函数
def main():
population = [init_schedule() for _ in range(POP_SIZE)] # 初始化种群
for generation in range(N_GENERATIONS):
fitness = np.array([get_fitness(schedule) for schedule in population])
best_schedule = population[np.argmax(fitness)]
population = select(population, fitness)
population = crossover(population)
population = mutate(population)
population.append(best_schedule)
print('Generation:', generation+1, '| Max Fitness:', np.max(fitness))
# 输出最佳课程表到Excel
best_schedule_df = pd.DataFrame(best_schedule, index=['Grade 1', 'Grade 2', 'Grade 3', 'Grade 4', 'Grade 5', 'Grade 6'],
columns=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'])
best_schedule_df.to_excel('class_schedule.xlsx', index=True)
if __name__ == '__main__':
main()
这段代码使用遗传算法来排课,初始化了种群并进行了交叉繁殖和突变操作,通过适应度函数来评估每个课程表的优劣,并选择适应度较高的个体进行下一代的繁殖。最后输出最佳课程表到Excel文件中。
请注意,代码中的课时量和老师分配是随机生成的,你可以根据实际情况进行调整。此外,代码中使用的是pandas库来生成和输出Excel文件,确保你已经安装了该库。
原文地址: https://www.cveoy.top/t/topic/qosp 著作权归作者所有。请勿转载和采集!