Алгоритм для составления школьного расписания
Вообщем, составляю расписание на питоне. Данные гружу из файлов, структура примерно такая:
Класс (5, 6, 7 и тд):
Список {урок - кол-во часов в неделю}:
Русский язык: 3
Математика: 4 и тд.
Учитель:
Список: {урок - у каких классов ведет}
Русский язык: (5, 6)
Математика: (8, 11)
Нужно составить расписание на 5 дней, с кол-вом уроков в сумме совпадающих по часам их исходного файла.
При этом, нужно также соблюдать несколько условий:
Такой-то учитель не работает во вторник (пример)
У такого-то учителя в пятницу уроки только с 4 ставить
А также некоторые уроки в классах должны быть принудительно совмещены, не важно когда, важно совмещены.
Физкультура - (9, 11)
Я попробовал создавать расписание обычным циклом, структура расписания примерно такая:
class Week:
days: list[Day]
class Day:
schedule: dict[Class, list[Lesson]
class Lesson:
teacher: Teacher
_class: Class
subject: str
Так вот я проходился по очереди по каждому классу каждый день:
первый урок в понедельник пятый класс, первый урок в понедельник шестой класс, ...
первый урок во вторник пятый класс...
Чтобы таблица заполнялась более менее равномерно.
Исключения, вроде 'Учителя в такой то день не ставить' я еще кое как сделал, но когда сказали про принудительные совмещения, я выпал
Мне нужна идея, совет, без понятия вообще как это можно сделать
+ Код:
def create_shedule():
for day in shedule.days:
for sclass in classes:
day.shedule[sclass] = []
for i in range(1, 12):
for day in shedule.days:
for sclass in classes:
if not sclass in day.shedule.keys():
day.shedule[sclass] = []
choose_subject(sclass, day, i)
def choose_subject(sclass: Class, day: Day, lesson_num: int):
if day.name == "Понедельник" and lesson_num == 1:
add_lesson(Lesson(Teacher('Кл. руководитель'), sclass, 'Разговор о важном'), day)
return
a_subjects: list[str] = []
for subject, hours in sclass.subjects.items():
if hours > 0:
a_subjects.append(subject)
# Получает уроки которые сейчас
now_lessons: list[Lesson] = []
for _sclass, _lessons in day.shedule.items():
if sclass.number != _sclass.number:
if lesson_num <= len(_lessons):
now_lessons.append(_lessons[lesson_num-1])
# Выбираем уроки учителей, которые не заняты
a_teachers: list[Teacher] = []
for teacher in teachers:
take = True
for lesson in now_lessons:
if teacher.name == lesson.teacher.name:
take = False
break
if take:
a_teachers.append(teacher)
if day.name == "Понедельник" and sclass.number == 7 and lesson_num == 1:
print('eere')
print(*a_teachers)
if day.name == "Вторник":
for teacher in a_teachers:
if teacher.name == "К - конфеденциальность":
a_teachers.remove(teacher)
break
if (day.name == "Вторник" or day.name == "Четверг") and lesson_num <= 4:
for teacher in a_teachers:
if teacher.name == "К - конфеденциальность":
a_teachers.remove(teacher)
break
if day.name == "Пятница" and lesson_num == 4:
for teacher in a_teachers:
if teacher.name == "К - конфеденциальность":
a_teachers.remove(teacher)
break
# Выбираем уроки, которые есть у доступных учителей
r_subjects: list[str] = []
for subject in a_subjects:
for teacher in a_teachers:
for _subject, c in teacher.subjects.items():
if sclass.number in c:
if subject == _subject:
r_subjects.append(subject)
# Выбираем уроки которые еще не были
wn_subjects: list[str] = []
tmp: list[str] = []
for _sclass, lessons in day.shedule.items():
if _sclass.number == sclass.number:
for lesson in lessons:
tmp.append(lesson.subject)
break
for subject in r_subjects:
if subject not in tmp:
wn_subjects.append(subject)
teach, subj = Teacher('err'), 'None'
# Окончательный выбор урока
if len(wn_subjects) > 0:
if rnd:
subject = random.choice(wn_subjects)
else:
subject = wn_subjects[0]
for teacher in teachers:
for tsubject in teacher.subjects.keys():
if subject == tsubject:
if sclass.number in teacher.subjects[subject]:
teach = teacher
subj = subject
break
else:
if len(r_subjects) > 0:
if rnd:
subject = random.choice(r_subjects)
else:
subject = r_subjects[0]
for teacher in teachers:
for tsubject in teacher.subjects.keys():
if subject == tsubject:
if sclass.number in teacher.subjects[subject]:
teach = teacher
subj = subject
break
if subj == "Старт в науку" and sclass.number == 7:
set_lesson(Lesson(teach, classes[4], subj), day, lesson_num)
if subj == "Практикум по географии" and sclass.number == 8:
set_lesson(Lesson(teach, classes[5], subj), day, lesson_num)
if subj == "Информатика" and sclass.number == 9:
set_lesson(Lesson(teach, classes[5], subj), day, lesson_num)
if subj == "История" and sclass.number == 9:
set_lesson(Lesson(teach, classes[5], subj), day, lesson_num)
if subj == "ОДКНР" and sclass.number == 5:
set_lesson(Lesson(teach, classes[1], subj), day, lesson_num)
if subj == "Физическая культура" and sclass.number == 9:
set_lesson(Lesson(teach, classes[5], subj), day, lesson_num)
if subj == "ОБЗР" and sclass.number == 9:
print('Hello')
set_lesson(Lesson(teach, classes[5], subj), day, lesson_num)
if teach.name != 'err':
add_lesson(Lesson(teach, sclass, subj), day)
return
def add_lesson(lesson: Lesson, day: Day):
try:
if lesson.sclass.subjects[lesson.subject] > 0:
day.shedule[lesson.sclass].append(lesson)
lesson.sclass.subjects[lesson.subject] -= 1
except Exception as ex:
pass
def set_lesson(lesson: Lesson, day: Day, lesson_num: int):
try:
if lesson.sclass.subjects[lesson.subject] > 0:
day.shedule[lesson.sclass].insert(lesson_num-1, lesson)
lesson.sclass.subjects[lesson.subject] -= 1
except Exception as ex:
pass
Просто прохожусь циклами, проверяю доступность уроков