Алгоритм создания школьного расписания

Мне было интересно, есть ли известные решения для алгоритма создания школьного расписания. В основном это касается оптимизации "часового рассеяния" (как в случае преподавателей, так и в классах) для данных ассоциаций класс-субъект-учитель. Мы можем предположить, что у нас есть наборы классов, предметы урока и преподаватели, связанные друг с другом на входе, и это расписание должно соответствовать между 8AM и 4PM.

Я предполагаю, что для этого, вероятно, нет точного алгоритма, но, возможно, кто-то знает хорошее приближение или подсказки для его разработки.

Ответ 1

Эта проблема NP-Complete!
В двух словах нужно изучить все возможные комбинации, чтобы найти список приемлемых решений. Из-за различий в обстоятельствах, в которых проблема возникает в разных школах (например: существуют ли ограничения в отношении классных комнат?). Некоторые из классов в некоторых подгруппах разделяются некоторое время? Это недельный график? и т.д.) нет известного класса проблем, который соответствует всем задачам планирования. Возможно, проблема Knapsack имеет много элементов сходства с этими проблемами в целом.

Подтверждение того, что это и тяжелая проблема, и одна, для которой люди постоянно ищут решение, состоит в том, чтобы проверить этот (длинный) список ( в основном коммерческие) средства планирования программного обеспечения

Из-за большого числа задействованных переменных наибольший источник из которых, как правило, желает преподаватель, -)..., обычно нецелесообразно рассматривать перечисление всех возможных комбинаций. Вместо этого нам нужно выбрать подход, который посещает подмножество пространства проблем/решений.
- Генетические алгоритмы, процитированные в другом ответе (или, похоже, ИМХО), хорошо подготовленные для выполнения такого рода полу-ориентированного поиска (проблема заключается в том, чтобы найти хорошую функцию оценки для кандидатов, которые будут сохранены для следующего поколения)
- Переписывание графа также используются с такими комбинаторными задачами оптимизации.

Вместо того, чтобы сосредоточиться на конкретных реализациях автоматической программы генератора расписания, я хотел бы предложить несколько стратегий, которые могут быть применены, на уровне определения проблемы.
Общее обоснование заключается в том, что в большинстве задач планирования реального мира потребуются некоторые компромиссы, а не все ограничения, выраженные и подразумеваемые: будут полностью выполнены. Поэтому мы помогаем себе:

  • Определение и ранжирование всех известных ограничений
  • Сокращение проблемного пространства вручную путем предоставления набора дополнительных ограничений. Это может показаться противоречивым, но, например, путем предоставления начального, частично заполненного графика (скажем, примерно 30% временных интервалов), таким образом, который полностью удовлетворяет всем ограничениям, и, рассматривая это неотвратимое частичное расписание, мы значительно сокращаем время/пространство, необходимые для получения решений кандидата.
    Еще один способ, который помогает дополнительные ограничения, - это, например, "искусственное" добавление ограничения, препятствующего обучению некоторые предметы в некоторые дни недели (если это недельный график...); этот тип ограничений приводит к уменьшению пространства проблем/решений, без, как правило, исключая значительное количество хороших кандидатов.
  • Обеспечение быстрого вычисления некоторых ограничений проблемы. Это часто связано с выбором модели данных, используемой для представления проблемы; идея состоит в том, чтобы иметь возможность быстро выбрать (или вырезать) некоторые из параметров.
  • Переопределить проблему и несколько раз сломать некоторые из ограничений (обычно к конечным узлам графика). Идея здесь заключается в том, чтобы либо устранить некоторые ограничения для заполнения последних нескольких слотов в расписании, либо сделать автоматическую программу генератора расписаний незаметной для завершения всего графика, вместо этого предоставив нам список из дюжины или около того правдоподобных кандидатов. Человек часто находится в лучшем положении, чтобы закончить головоломку, как указано, возможно, нарушив некоторые из противопоказаний, используя информацию, которая обычно не разделяется с автоматизированной логикой (например, правило "Нет математики во второй половине дня" может быть нарушено для класса "передовой математики и физики" или "Лучше нарушить один из требований г-на Джонса, чем один из Ms Smith...;-))

В доказательстве этого ответа я понимаю, что он довольно стесняется дать определенный ответ, но тем не менее он имеет практические предложения. Я надеюсь, что эта помощь, с чем, в конце концов, "сложная проблема".

Ответ 2

Это беспорядок. королевский беспорядок. Чтобы добавить к ответам, уже очень полный, я хочу указать на мой семейный опыт. Моя мать была учителем и использовала участие в этом процессе.

Оказывается, что наличие компьютера для этого не только сложно само по себе, но и сложно, потому что есть условия, которые трудно определить для предварительно испеченной компьютерной программы. Примеры:

  • Учитель учит как в вашей школе, так и в другом институте. Ясно, что если он закончит урок там в 10.30, он не может начать в вашем помещении в 10.30, потому что ему нужно некоторое время, чтобы добираться между институтами.
  • два учителя состоят в браке. В целом, он считает, что хорошая практика заключается не в том, чтобы иметь двух замужних учителей в одном классе. Поэтому у этих двух учителей должны быть два разных класса.
  • два учителя женятся, и их ребенок посещает одну и ту же школу. Опять же, вы должны помешать двум учителям преподавать в определенном классе, где находится их ребенок.
  • В школе есть отдельные объекты, например, в один день класс находится в одном институте, а в другой день класс находится в другом.
  • в школе есть лаборатории, но эти лаборатории доступны только в определенные рабочие дни (по соображениям безопасности, например, когда требуется дополнительный персонал).
  • У некоторых учителей есть предпочтения в течение свободного дня: некоторые предпочитают в понедельник, некоторые - в пятницу, некоторые - в среду. Некоторые предпочитают прибывать рано утром, некоторые предпочитают приезжать позже.
  • у вас не должно быть ситуаций, когда у вас есть урок, скажем, история в первый час, затем три часа математики, затем еще один час истории. Это не имеет смысла для студентов, а также для учителя.
  • вы должны равномерно распределять аргументы. Не имеет смысла иметь первые дни только на математике, а затем всю оставшуюся неделю.
  • вы должны дать учителям два последовательных часа для проведения оценочных тестов.

Как вы можете видеть, проблема не NP-полная, она NP-безумная.

Итак, что они делают, так это то, что у них большой стол с маленькими пластиковыми вставками, и они перемещают вставки до получения удовлетворительного результата. Они никогда не начинаются с нуля: они обычно начинаются с расписания предыдущего года и корректируются.

Ответ 3

Международный конкурс по расписанию 2007 был составлен график составления графика для отслеживания и отслеживания экзаменов. В этом конкурсе участвовали многие исследователи. Было опробовано множество эвристик и метаэвристики, но в итоге метаэвристика локального поиска (такая как Tabu Search и Simulated Annealing) явно превзошла другие алгоритмы (такие как генетические алгоритмы).

Взгляните на 2 рамки с открытым исходным кодом, используемые некоторыми финалистами:

  • JBoss OptaPlanner (Java, с открытым исходным кодом)
  • Unitime (Java, с открытым исходным кодом) - больше для университетов

Ответ 4

Одно из моих полусрочных назначений - генерация школьной таблицы генетического алгоритма.

Целая таблица - это один "организм". Были внесены некоторые изменения и предостережения в общий подход к генетическим алгоритмам:

  • Были приняты правила для "незаконных таблиц": два класса в одном классе, один учитель одновременно преподавал две группы и т.д. Эти мутации считались смертельными немедленно, а новый "организм" был прорастан вместо "умершего" немедленно. Первоначальная была создана серией случайных попыток получить юридическую (если она бессмысленная). Смертельная мутация не учитывалась в отношении количества мутаций на итерации.

  • Мутации "Exchange" были гораздо более распространены, чем мутации "Модифицировать". Изменения были только между частями гена, которые имели смысл - не заменяя учителя классной комнатой.

  • Маленькие бонусы были назначены для объединения определенных 2 часов вместе, для назначения одного и того же родового класса в последовательности для одной и той же группы, для сохранения продолжительности работы учителя и непрерывной загрузки класса. Умеренные бонусы были назначены для предоставления правильных классных комнат для данного предмета, хранения часов занятий в рамках облигаций (утром или днем) и т.д. Большие бонусы были предназначены для задания правильного количества заданного предмета, заданной рабочей нагрузки для учителя и т.д.

  • Учителя могут создавать графики рабочей нагрузки "хочу работать тогда", "нормально работать", "не любит работать", "не может работать", с соответствующими весами. Целые 24 часа были законными рабочими часами, кроме ночного времени, было очень нежелательным.

  • Весовая функция... о да. Весовая функция была огромной, чудовищной продукцией (как при умножении) весов, присвоенных выбранным свойствам и свойствам. Это было очень круто, одно свойство легко могло изменить его на порядок вверх или вниз - и в одном организме существовали сотни или тысячи свойств. Это привело к абсолютно ОГРОМНЫМ номерам в качестве весов, и в качестве прямого результата необходимо использовать библиотеку bignum (gmp) для выполнения вычислений. Для небольшого тестового теста из 10 групп, 10 учителей и 10 классных комнат начальный набор начинался с отметки 10 ^ -200 и что с 10 ^ + 300. Это было совершенно неэффективно, когда оно было более плоским. Кроме того, ценности росли на более широком расстоянии с более крупными "школами".

  • Среднее время вычислений было мало различий между небольшой популяцией (100) в течение длительного времени и большой совокупностью (10k +) за меньшее количество поколений. Вычисление за одно и то же время произвело примерно одинаковое качество.

  • Расчет (на некотором 1 ГГц ЦП) потребовал бы приблизительно 1 ч, чтобы стабилизировать около 10 ^ + 300, генерируя графики, которые выглядели неплохо, для упомянутого тестового примера 10x10x10.

  • Проблема легко паралелизуема, предоставляя сетевое средство, которое будет обмениваться лучшими образцами между компьютерами, на которых выполняется вычисление.

В результате программа никогда не видела дневного света, чтобы получить хороший класс в течение семестра. Это показало некоторые обещания, но у меня никогда не было достаточной мотивации, чтобы добавить какой-либо графический интерфейс и сделать его полезным для широкой публики.

Ответ 5

Эта проблема сложнее, чем кажется.

Как говорили другие, это NP-полная проблема, но пусть анализирует, что это значит.

В принципе, это означает, что вы должны смотреть на все возможные комбинации.

Но "смотреть" не говорит вам, что вам нужно делать.

Создание всех возможных комбинаций легко. Это может привести к огромному количеству данных, но у вас не должно быть проблем с пониманием концепций этой части проблемы.

Вторая проблема заключается в оценке того, является ли данная возможная комбинация хорошей, плохой или лучшей, чем предыдущее "хорошее" решение.

Для этого вам нужно больше, чем просто "это возможное решение".

Например, тот же самый учитель, который работает 5 дней в неделю в течение X недель подряд? Даже если это рабочее решение, это может быть не лучшим решением, чем чередование между двумя людьми, чтобы каждый учитель делал каждую неделю каждый. О, ты об этом не думал? Помните, что это люди, с которыми вы имеете дело, а не просто проблема распределения ресурсов.

Даже если один преподаватель может работать полный рабочий день в течение 16 недель подряд, это может быть неоптимальное решение по сравнению с решением, в котором вы пытаетесь чередовать учителей, и такого рода балансирование очень сложно встроить в программное обеспечение.

Подводя итог, создание хорошего решения этой проблемы будет стоить много, для многих людей. Следовательно, это непростая задача - сломать и решить. Будьте готовы сделать несколько целей, которые не являются 100%, и называя их "достаточно хорошими".

Ответ 6

UPDATE: из комментариев... также должны быть эвристики!

Я бы пошел с Prolog... затем использовал Ruby или Perl или что-то, чтобы очистить ваше решение в более красивой форме.

teaches(Jill,math).
teaches(Joe,history).

involves(MA101,math).
involves(SS104,history).

myHeuristic(D,A,B) :- [test_case]->D='<';D='>'.
createSchedule :- findall(Class,involves(Class,Subject),Classes),
                  predsort(myHeuristic,Classes,ClassesNew),
                  createSchedule(ClassesNew,[]).
createSchedule(Classes,Scheduled) :- [the actual recursive algorithm].

Я (по-прежнему) в процессе выполнения чего-то подобного этой проблеме, но используя тот же путь, что я только что упомянул. Prolog (как функциональный язык) действительно облегчает решение проблем NP-Hard.

Ответ 9

Мой алгоритм расписания, реализованный в FET (Free Timetabling Software, http://lalescu.ro/liviu/fet/, успешное приложение):

Алгоритм эвристический. Я назвал его "рекурсивной заменой".

Вход: набор действий A_1... A_n и ограничения.

Выход: набор времен TA_1... TA_n (временной интервал каждого вида деятельности. Для удобства здесь исключены номера). Алгоритм должен поместить каждое действие в временной интервал, соблюдая ограничения. Каждый TA_i находится между 0 (T_1) и max_time_slots-1 (T_m).

Ограничения:

C1) Basic: список пар действий, которые не могут быть одновременными (например, A_1 и A_2, потому что у них один и тот же учитель или те же ученики);

C2) Множество других ограничений (исключается здесь для простоты).

Алгоритм расписания (который я назвал "рекурсивной заменой" ):

  • Сортировка, наиболее сложная задача. Не критический шаг, но ускоряет алгоритм, возможно, в 10 раз и более.
  • Постарайтесь разместить каждое действие (A_i) в разрешенном временном интервале, следуя приведенному выше порядку, по одному за раз. Найдите доступный слот (T_j) для A_i, в котором эта активность может быть установлена ​​с учетом ограничений. Если доступно больше слотов, выберите случайный. Если ни один из них не доступен, выполните рекурсивную замену:

    а. Для каждого временного интервала T_j рассмотрите, что произойдет, если вы поместите A_i в T_j. Будет список других действий, которые не согласуются с этим движением (например, активность A_k находится в одном слоте T_j и имеет того же учителя или тех же студентов, что и A_i). Сохраните список конфликтующих действий для каждого временного интервала T_j.

    б. Выберите слот (T_j) с наименьшим количеством конфликтующих действий. Скажем, список действий в этом слоте содержит 3 действия: A_p, A_q, A_r.

    с. Поместите A_i в T_j и сделайте A_p, A_q, A_r нераспределенным.

    д. Рекурсивно попытайтесь поместить A_p, A_q, A_r (если уровень рекурсии не слишком велик, скажем, 14, и если общее количество рекурсивных вызовов, подсчитанных после шага 2) на начальном A_i, не слишком велико, скажем 2 * n), как на этапе 2).

    е. Если успешно поставлены A_p, A_q, A_r, вернитесь с успехом, в противном случае попробуйте другие временные интервалы (перейдите к шагу 2 b) и выберите следующий лучший временной интервал).

    е. Если все (или разумное количество) временных интервалов были безуспешными, вернитесь без успеха.

    г. Если мы находимся на уровне 0, и нам не удавалось разместить A_i, поместите его, как на шагах 2 b) и 2 c), но без рекурсии. У нас теперь 3 - 1 = еще 2 мероприятия для размещения. Перейдите к шагу 2) (здесь используются некоторые методы, чтобы избежать циклирования).

Ответ 10

Я разработал коммерческие алгоритмы как для расписания занятий, так и для расписания экзаменов. Для первого я использовал целочисленное программирование; для второй эвристики, основанной на максимизации целевой функции, путем выбора слотов, очень похожей на первоначальный ручной процесс, который был развит. Главное в принятии таких решений - способность представлять все ограничения реального мира; и для человеческих расписаний не сможет увидеть способы улучшить решение. В итоге алгоритмическая часть была довольно простой и простой в реализации по сравнению с подготовкой баз данных, пользовательским интерфейсом, возможностью сообщать о статистике, как использование помещений, обучение пользователей и т.д.

Ответ 11

В этой статье описывается проблема школьного расписания и их подход к алгоритму довольно хорошо: " Разработка SYLLABUS-Интерактивного планировщика на основе ограничений для школ и колледжи." [PDF]

Автор сообщает мне, что ПО SYLLABUS по-прежнему используется/развивается здесь: http://www.scientia.com/uk/

Ответ 12

Я работаю над широко используемым механизмом планирования, который делает именно это. Да, это NP-Complete; наилучшие подходы направлены на приближение оптимального решения. И, конечно, есть много разных способов сказать, какое из них является "лучшим" решением - важнее ли, чтобы ваши учителя были довольны их расписанием или, например, учащимися во всех своих классах?

Абсолютным самым важным вопросом, который необходимо решить на раннем этапе, является , что делает один способ планирования этой системы лучше, чем другой? То есть, если у меня есть график с миссис Джонс, преподающим математику в 8 лет, а г-н Смит, преподающий математику в 9 лет, это лучше или хуже, чем в одном из них, у которых преподавание математики в 10 лет? Это лучше или хуже, чем с миссис Джонс, преподающим в 8 лет, а г-н Джонс учится в 2? Почему?

Главный совет, который я приведу здесь, - это как можно больше разделить проблему - возможно, курс, конечно, учитель, возможно, по комнате, - и сначала займитесь решением проблемы. Там вы должны получить множество решений на выбор и выбрать один из них, как наиболее оптимальный. Затем работа над созданием "более ранних" подзадач учитывает потребности более поздних под-проблем в оценке их потенциальных решений. Затем, возможно, вы будете работать над тем, как выйти из ситуации с раскрашенными в угол (при условии, что вы не можете предвидеть эти ситуации в более ранних проблемах), когда вы попадаете в состояние "без действительных решений".

Проход по оптимизации локального поиска часто используется для "отполирования" конечного ответа для достижения лучших результатов.

Обратите внимание, что мы обычно имеем дело с системами с ограниченными ресурсами в школьном планировании. Школы не проходят через год с большим количеством пустых комнат или учителей, сидящих в салоне 75% дня. Подходы, которые лучше всего работают в средах, богатых решениями, не обязательно применимы в школьном расписании.

Ответ 13

Как правило, программирование ограничений является хорошим подходом к этой проблеме планирования. Поиск по "программированию ограничений" и планированию или "планирование на основе ограничений" как при переполнении стека, так и в Google приведет к созданию хороших ссылок. Это не невозможно - о чем трудно подумать, когда используют традиционные методы оптимизации, такие как линейная или целая оптимизация. Один выход был бы - существует ли расписание, удовлетворяющее всем требованиям? Это само по себе, очевидно, полезно.

Удачи!

Ответ 14

Вы можете использовать его с генетическими алгоритмами, да. Но вы не должны:. Он может быть слишком медленным, и настройка параметров может быть слишком экономной и т.д.

Существуют и другие подходы. Все реализованы в проектах с открытым исходным кодом:

  • Подход, основанный на ограничениях
    • Реализовано в UniTime (не для школ)
    • Вы также можете пойти дальше и использовать программирование Integer. Успешно сделано в университете Удине, а также в университете Байройт (я был там задействован), используя коммерческое программное обеспечение (ILOG CPLEX)
    • Основанный на правилах подход с эвристикой - см. Планировщик Drools
  • Различные эвристики - FET и мои собственные

Смотрите здесь список расписаний расписания

Ответ 15

Я думаю, вы должны использовать генетический алгоритм, потому что:

Также посмотрите на аналогичный вопрос и другой

Ответ 16

Я не знаю, что кто-то согласится с этим кодом, но я разработал этот код с помощью моего собственного алгоритма и работает для меня в ruby.Hope он поможет тем, кто его ищет в следующем коде флагов periodflag, дневной флагом dayflag и флагом teacher являются хешем с соответствующим id и значением флага, которое является булевым. Любую проблему свяжитесь со мной....... (-_-)

periodflag.each do | k2, v2 |

            if(TimetableDefinition.find(k2).period.to_i != 0)
                subjectflag.each do |k3,v3|
                    if (v3 == 0)
                        if(getflag_period(periodflag,k2))
                            @teachers=EmployeesSubject.where(subject_name: @subjects.find(k3).name, division_id: division.id).pluck(:employee_id)
                            @teacherlists=Employee.find(@teachers)
                            teacherflag=Hash[teacher_flag(@teacherlists,teacherflag,flag).to_a.shuffle] 
                            teacherflag.each do |k4,v4|
                                if(v4 == 0)
                                    if(getflag_subject(subjectflag,k3))
                                        subjectperiod=TimetableAssign.where("timetable_definition_id = ? AND subject_id = ?",k2,k3)
                                        if subjectperiod.blank?
                                            issubjectpresent=TimetableAssign.where("section_id = ? AND subject_id = ?",section.id,k3)
                                            if issubjectpresent.blank?
                                                isteacherpresent=TimetableAssign.where("section_id = ? AND employee_id = ?",section.id,k4)
                                                if isteacherpresent.blank?
                                                    @finaltt=TimetableAssign.new
                                                    @[email protected]_struct.id
                                                    @finaltt.employee_id=k4
                                                    @finaltt.section_id=section.id
                                                    @finaltt.standard_id=standard.id
                                                    @finaltt.division_id=division.id
                                                    @finaltt.subject_id=k3
                                                    @finaltt.timetable_definition_id=k2
                                                    @finaltt.timetable_day_id=k1
                                                    set_school_id(@finaltt,current_user)
                                                    if(@finaltt.save)

                                                        setflag_sub(subjectflag,k3,1)
                                                        setflag_period(periodflag,k2,1)
                                                        setflag_teacher(teacherflag,k4,1)
                                                    end
                                                end
                                            else
                                                @subjectdetail=TimetableAssign.find_by_section_id_and_subject_id(@section.id,k3)
                                                @finaltt=TimetableAssign.new
                                                @[email protected]_struct_id
                                                @[email protected]_id
                                                @finaltt.section_id=section.id
                                                @finaltt.standard_id=standard.id
                                                @finaltt.division_id=division.id
                                                @[email protected]_id
                                                @finaltt.timetable_definition_id=k2
                                                @finaltt.timetable_day_id=k1
                                                set_school_id(@finaltt,current_user)
                                                if(@finaltt.save)

                                                    setflag_sub(subjectflag,k3,1)
                                                    setflag_period(periodflag,k2,1)
                                                    setflag_teacher(teacherflag,k4,1)
                                                end
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end