以下是使用遗传算法排课的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文件,确保你已经安装了该库。

小学课程表自动生成:基于遗传算法的Python代码实现

原文地址: https://www.cveoy.top/t/topic/qosp 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录