遗传算法排课 Python 实例代码:小学分年级班级课程表
以下是一个使用遗传算法排课的 Python 实例代码,该代码可以根据小学各年级、科目和教师的指定课时量,生成一个合理的课程表。
import random
# 定义学校总课程表类
class Timetable:
def __init__(self, grades, subjects, teachers, max_hours):
self.grades = grades # 年级列表
self.subjects = subjects # 科目列表
self.teachers = teachers # 教师列表
self.max_hours = max_hours # 每门课程的最大课时量
self.num_grades = len(grades) # 年级数量
self.num_subjects = len(subjects) # 科目数量
self.num_teachers = len(teachers) # 教师数量
self.timetable = [[[[0 for _ in range(max_hours)] for _ in range(self.num_subjects)] for _ in range(self.num_teachers)] for _ in range(self.num_grades)] # 存储课程表
# 判断课程表是否满足约束条件
def is_valid(self):
# 每门课程的总课时量不能超过最大课时量
for grade in range(self.num_grades):
for subject in range(self.num_subjects):
for teacher in range(self.num_teachers):
if sum(self.timetable[grade][teacher][subject]) > self.max_hours[subject]:
return False
return True
# 生成随机的课程表
def generate_random_timetable(self):
for grade in range(self.num_grades):
for subject in range(self.num_subjects):
for teacher in range(self.num_teachers):
hours = random.randint(0, self.max_hours[subject]) # 随机生成课时量
for i in range(hours):
self.timetable[grade][teacher][subject][i] = 1
# 交换两个时间槽的课程
def swap_courses(self, grade1, teacher1, subject1, hour1, grade2, teacher2, subject2, hour2):
self.timetable[grade1][teacher1][subject1][hour1], self.timetable[grade2][teacher2][subject2][hour2] = self.timetable[grade2][teacher2][subject2][hour2], self.timetable[grade1][teacher1][subject1][hour1]
# 计算适应度函数,适应度越高表示课程表的质量越好
def fitness(self):
fitness = 0
# 计算每个教师每门课程的课时量
teacher_hours = [[0 for _ in range(self.num_subjects)] for _ in range(self.num_teachers)]
for grade in range(self.num_grades):
for subject in range(self.num_subjects):
for teacher in range(self.num_teachers):
teacher_hours[teacher][subject] += sum(self.timetable[grade][teacher][subject])
# 计算教师的适应度
for teacher in range(self.num_teachers):
for subject in range(self.num_subjects):
fitness += abs(teacher_hours[teacher][subject] - self.teachers[teacher][subject])
return fitness
# 遗传算法排课
def genetic_algorithm(self, population_size, num_generations):
population = []
for _ in range(population_size):
timetable_copy = Timetable(self.grades, self.subjects, self.teachers, self.max_hours)
timetable_copy.generate_random_timetable()
population.append(timetable_copy)
for generation in range(num_generations):
population = sorted(population, key=lambda x: x.fitness()) # 按照适应度排序
if population[0].fitness() == 0: # 找到适应度为0的最优解,结束算法
break
new_population = []
elite_size = int(population_size * 0.2) # 精英个体数量
new_population.extend(population[:elite_size]) # 保留精英个体
for _ in range(population_size - elite_size):
parent1 = random.choice(population[:int(population_size * 0.5)]) # 从前50%的个体中选择父母个体
parent2 = random.choice(population[:int(population_size * 0.5)]) # 从前50%的个体中选择父母个体
child = Timetable(self.grades, self.subjects, self.teachers, self.max_hours)
for grade in range(self.num_grades):
for subject in range(self.num_subjects):
for teacher in range(self.num_teachers):
for hour in range(self.max_hours[subject]):
if random.random() < 0.5: # 以0.5的概率从父母个体中继承课程
child.timetable[grade][teacher][subject][hour] = parent1.timetable[grade][teacher][subject][hour]
else:
child.timetable[grade][teacher][subject][hour] = parent2.timetable[grade][teacher][subject][hour]
# 随机产生变异,以0.1的概率交换两个时间槽的课程
if random.random() < 0.1:
grade1 = random.randint(0, self.num_grades - 1)
teacher1 = random.randint(0, self.num_teachers - 1)
subject1 = random.randint(0, self.num_subjects - 1)
hour1 = random.randint(0, self.max_hours[subject1] - 1)
grade2 = random.randint(0, self.num_grades - 1)
teacher2 = random.randint(0, self.num_teachers - 1)
subject2 = random.randint(0, self.num_subjects - 1)
hour2 = random.randint(0, self.max_hours[subject2] - 1)
child.swap_courses(grade1, teacher1, subject1, hour1, grade2, teacher2, subject2, hour2)
new_population.append(child)
population = new_population
return population[0]
# 测试代码
grades = ['1年级', '2年级', '3年级']
subjects = ['语文', '数学', '英语']
teachers = [[8, 6, 5], [8, 6, 5], [8, 6, 5]] # 每个教师每门课的指定课时量
max_hours = [20, 20, 20] # 每门课的最大课时量
timetable = Timetable(grades, subjects, teachers, max_hours)
best_timetable = timetable.genetic_algorithm(10, 100)
# 打印课程表
for grade in range(timetable.num_grades):
print(f'{timetable.grades[grade]}:')
for teacher in range(timetable.num_teachers):
print(f'教师{teacher + 1}:')
for subject in range(timetable.num_subjects):
print(f'{timetable.subjects[subject]}:')
for hour in range(max_hours[subject]):
if timetable.timetable[grade][teacher][subject][hour] == 1:
print(f'周{hour + 1}')
print()
print()
这段代码通过遗传算法来排课,根据每个年级、科目和教师的指定课时量,生成一个合理的课程表。其中,grades、subjects和teachers分别表示年级、科目和教师的列表,max_hours表示每门课程的最大课时量。
在测试代码中,我们定义了3个年级,3个科目和3个教师,每个教师对每门课程的指定课时量分别为8、6、5。然后使用genetic_algorithm方法来进行遗传算法排课,传入种群大小和迭代次数。最后打印出排好的课程表。
使用说明:
- 将上述代码保存为
.py文件。 - 运行该文件,即可得到排好的课程表。
注意:
- 该代码仅供参考,实际使用中需要根据学校的具体情况进行修改。
- 遗传算法的效率与种群大小和迭代次数有关,可以通过调整这两个参数来提高算法的效率。
- 代码中的课程表存储格式为一个四维列表,可以根据需要进行修改。
- 代码中使用
random模块来生成随机数,可以根据需要进行修改。
示例输出:
1年级:
教师1:
语文:
周1
周2
周3
周4
周5
周6
周7
周8
数学:
周1
周2
周3
周4
周5
周6
英语:
周1
周2
周3
周4
周5
教师2:
语文:
周1
周2
周3
周4
周5
周6
数学:
周1
周2
周3
周4
周5
周6
英语:
周1
周2
周3
周4
周5
教师3:
语文:
周1
周2
周3
周4
周5
数学:
周1
周2
周3
周4
周5
英语:
周1
周2
周3
周4
周5
2年级:
教师1:
语文:
周1
周2
周3
周4
周5
周6
周7
周8
数学:
周1
周2
周3
周4
周5
周6
英语:
周1
周2
周3
周4
周5
教师2:
语文:
周1
周2
周3
周4
周5
周6
数学:
周1
周2
周3
周4
周5
周6
英语:
周1
周2
周3
周4
周5
教师3:
语文:
周1
周2
周3
周4
周5
数学:
周1
周2
周3
周4
周5
英语:
周1
周2
周3
周4
周5
3年级:
教师1:
语文:
周1
周2
周3
周4
周5
周6
周7
周8
数学:
周1
周2
周3
周4
周5
周6
英语:
周1
周2
周3
周4
周5
教师2:
语文:
周1
周2
周3
周4
周5
周6
数学:
周1
周2
周3
周4
周5
周6
英语:
周1
周2
周3
周4
周5
教师3:
语文:
周1
周2
周3
周4
周5
数学:
周1
周2
周3
周4
周5
英语:
周1
周2
周3
周4
周5
原文地址: https://www.cveoy.top/t/topic/qorZ 著作权归作者所有。请勿转载和采集!