Недавно я решил проблему назначения смены для крупного производственного предприятия. Сначала мы попытались сгенерировать чисто случайные расписания и вернуть любое, прошедшее тест is_schedule_valid
- алгоритм отката. Это было, конечно, медленно и неопределенно.
Затем мы попробовали генетические алгоритмы (как вы и предлагали), но не смогли найти хорошую фитнес-функцию, которая закрывала бы какое-либо жизнеспособное решение (потому что самое маленькое изменение может сделать весь график ПРАВИЛЬНЫМ или НЕПРАВИЛЬНЫМ - очков практически нет) 1004 *
Наконец мы выбрали следующий метод (который отлично работал!):
- Рандомизировать набор входных данных (т. Е. Вакансии, смены, персонал и т. Д.).
- Создайте допустимый кортеж и добавьте его в предварительное расписание.
- Если недопустимый кортеж может быть создан, выполните откат (и приращение) последнего добавленного кортежа.
- Передать частичное расписание функции, которая проверяет
could_schedule_be_valid
, то есть, может ли это расписание быть действительным, если оставшиеся кортежи были заполнены возможным способом
- Если
!could_schedule_be_valid
, просто откатить (и увеличить) кортеж, добавленный в (2).
- Если
schedule_is_complete
, return schedule
- Перейти (2)
Таким образом, вы постепенно строите частичный сдвиг. Преимущество состоит в том, что некоторые тесты для правильного расписания можно легко выполнить на шаге 2 (предварительные тесты), а другие должны остаться на шаге 5 (пост-тесты).
Удачи. Мы потратили впустую дни, пробуя первые два алгоритма, но получили рекомендованный алгоритм, генерирующий действительные графики мгновенно за менее чем 5 часов разработки.
Кроме того, мы поддерживали предварительную и последующую фиксацию назначений, которые будут соблюдаться алгоритмом. Вы просто не рандомизируете эти слоты на шаге 1. Вы обнаружите, что решения не должны быть где-то близко к оптимальным. Наше решение как минимум O (N * M), но выполняется на PHP (!) Менее чем за полсекунды для всего завода. Прелесть в том, чтобы быстро исключать плохие графики, используя хороший тест could_schedule_be_valid
.
Людям, которые привыкли делать это вручную, все равно, если это займет час - они просто знают, что им больше не нужно делать это вручную.