Как эффективно и быстро найти допустимые комбинации из массива строковых элементов для планирования сотрудников? - PullRequest
5 голосов
/ 29 июня 2019

Я работаю над проектом, в котором необходимо очень точное планирование (и почему я не использую библиотеку). Это работает, но я пытаюсь найти более быстрое решение следующей проблемы:

У нас есть сотрудники, которые запрашивают часы каждую неделю. Они вводят свою общую доступность за неделю (например: 8-1 M, W, R). Все они должны работать 10 часов в неделю, и каждая смена должна длиться не менее 2 часов подряд. (Все смены непрерывны, между ними нет перерывов).

Например, сотрудник 1 говорит, что доступность составляет: 8-3 M, W, R, F: его можно запланировать на 3 часа на M, 3 часа на W и 2 на F или любую другую комбинацию (такую ​​как 4,4,2; 2,2,4 и т. Д.). Проблема в том, чтобы найти эти комбинации. Прямо сейчас я храню их доступность в виде строки, разделенной точкой с запятой (и т. Д .: 8,9,10,11,12,1; 8,9,10,11,12,1; 8,9,10 ;; 8,9 будет часов на каждый день (5 дней) Я разделяю их во время составления расписания на массив, и тогда это трудная часть для меня:

Я хочу иметь возможность определять комбинации этих часов, где каждая комбинация имеет не менее 2 часов на каждый день, где все часы непрерывны и выбрано 10 часов. Прямо сейчас мое решение - очень грубая сила.

Я использую комбинации itertools. Я беру их доступность и на каждый день добавляю к ней письмо соответствующего дня и складываю в один массив. Итак, пример 8,9,10,11; 8,9 ;; 8,9,10,11; становится [m8, m9, m10, m11, t8, t9, r8, r9, r10, r11]

Затем я использую комбинацию itertools для просмотра всех комбинаций этого массива, и у меня есть функция, которая считывает, чтобы видеть, есть ли у каждого дня непрерывные часы, как минимум 2-часовые смены и всего 10 часов (или другое число часов, это может измениться).

Это очень медленный процесс, потому что если кто-то имеет доступность 8-5 M-F, у него может быть множество комбинаций, которые работают и не работают. (Причина, по которой мне нужно проверить все, заключается в том, что у нас более 100 сотрудников, выполняющих аналогичные роли, и если одна роль занята, другой сотрудник не может быть назначен на это время)

Пример того, как я это делаю сейчас.


    # let availability be the string of availability 
    availability = "8,9,10,11;8,9;;8,9,10,11;"
    poss_times = availability.split(";")
    # where I put into one array with each day letter in front
    sched=[]
    sched.extend(["m" + day for day in list(filter(None,poss_times[0].split(",")))])
    sched.extend(["t" + day for day in list(filter(None,poss_times[1].split(",")))])
    sched.extend(["w" + day for day in list(filter(None,poss_times[2].split(",")))])
    sched.extend(["r" + day for day in list(filter(None,poss_times[3].split(",")))])
    sched.extend(["f" + day for day in list(filter(None,poss_times[4].split(",")))])
    sched.extend(["s" + day for day in list(filter(None,poss_times[5].split(",")))])
    sched.extend(["u" + day for day in list(filter(None,poss_times[6].split(",")))])

    for poss_combination in itertools.combinations(sched, 10):
        # check if the combination fulfills the requirements, and if so continue to see if it is possible to schedule that employee

Я надеюсь, что может быть более быстрое и элегантное решение, которое может ускорить процесс Спасибо за любую помощь.

1 Ответ

10 голосов
/ 06 июля 2019

Я думаю, что это пример известной проблемы планирования медсестры . Эта проблема сложна с точки зрения NP, то есть, чтобы найти оптимальное решение, вам нужно было создать все возможные комбинации назначений и выбрать наиболее подходящее. Так как это имеет экспоненциальную временную сложность, оно выполнимо только для небольших задач, а ваша, по-видимому, уже слишком велика.
Если вы хотите найти только разумное (не оптимальное) решение, можно применить стохастические алгоритмы общего назначения, как они упоминаются в упомянутом выше посте вики, например, стохастическая оптимизация, генетические алгоритмы и моделируемый отжиг. Но такие методы обычно имеют длительное время вычислений.
В любом случае, здесь - это пример, где проблема планирования медсестры решается с помощью генетического алгоритма. Может быть, вы можете попытаться приспособить его к вашей проблеме и проверить, улучшает ли это вашу ситуацию.

...