Проблема планирования работы

голоса
8

Я работаю над приложением, в котором я должен автоматически планировать рабочие места для членов по скользящему графику. Я не очень хорошо объяснять правила, так вот некоторые данные, чтобы помочь:

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

Для каждой даты в месяце, члены назначаются на должность (как в порядке возрастания). Если член назначается на должность в одной категории, в следующий раз, положение в той же категории придумывает, следующий член в алфавитном порядке (или в начале списка) получает назначение, например.

Пользователи: М1, М2, М3, М4
Позиции в категории С1: Р1, Р2, Р3
пользователей в положении P1: M1, M2, M3, M4 -
членов в положении Р2: M1, M2, M3
членов в положении Р2: М1, М3, M4

Если M1 предназначен для P1, P2, если будет дальше, M2 будет назначен. Дополнительный слой сложности вводится где, если P3 будет дальше вместо M3 получает назначение. Система должна следить за тем, что М2 «пропускаются» и назначить M2 ряда, если имеется, то назначить М4 рядом, или подождать, пока он не попадет в положение, в котором M2 доступен (это становится дополнительно усложняется, когда есть много «пропущено 'членов).

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

У меня уже есть временное [и грязное] решение, которое я уже не понимаю, хотя у меня есть много комментариев в нем, объясняющих каждый шаг. Ее недостатки в работе с пропущенными членами.

Если вы собираетесь кодировать это как бы вы об этом? Я реализую это в PHP, но псевдокод будет работать.

Задан 19/12/2009 в 11:20
источник пользователем
На других языках...                            


3 ответов

голоса
1

уфф. я не следовать за вами описание, но в подобных ситуациях я использовал SQL для решения такого рода проблем. если вы используете PHP я думаю, у вас есть SQL доступны.

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

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

Ответил 19/12/2009 в 13:09
источник пользователем

голоса
6

Мое решение: Вам нужен PriorityQueue (который доступен в PHP под SplPriorityQueue). PriorityQueue дает элементы с убывающим приоритетом (отсортированы по значениям, наименьшее значение имеет наивысший приоритет).

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

Таким образом, (п = 5):

  • Значение М1: 99999Albert Р1, Р2, Р3
  • Значение М2: 99999Susi Р1, Р2
  • Значение M3: 99999Bob P1, P3

Это позволяет легко сортировать пользователей по приоритету и имя.

Приготовление:

Солнечный день. Вы запрашиваете присвоенные позиции и категорию для данного дня. Каждый член загружен в длинном списке. Каждый участник, который не появляется на работе, не загружен, но получает его значение уменьшилось на минус два. Боб не здесь, так что его новое значение приобретает 99997Bob. Это означает, что Боб будет выбран автоматически в следующий раз. Все остальные участники получают их стоимость снизилась на минус один.

Положения, назначенные на определенный день отображаются (используйте SplObjectStorage):

P1-> М1, М2, М3, М4 и т.д. Р2-> и т.д.

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

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

Назначение:

  • Вы выбираете позицию для назначения
  • Получить список членов, которые могут заполнить позицию
  • Удалить имеющиеся элементы из списка и поместить их в PriorityQueue
  • Назначают позицию по экстракте () из PriorityQueue (правильное назначение сделано переключающихся автоматически). Каждый элемент, который присваивается воля получает значение увеличивается на единицу (так что уровни уменьшения и увеличения, если вы здесь и работать). Если вы здесь, а не назначены на должность по какой-либо причине, вы получите небольшой штраф одного. Если вы не здесь, вы получите штраф в размере двух.
  • После завершения, положить оставшиеся члены в списке снова снимите PQueue и переходите к следующему заданию.

Предостережения:

  • Вы должны быть осторожны, что всегда есть достаточное количество людей для позиции.
Ответил 02/01/2010 в 16:10
источник пользователем

голоса
0

То, что я понимаю, есть «м» членов и «п» позиции.

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

Группа: группа позиций - позиции в той же группе, должны быть назначены на разные дни.

И последнее, что позиция имеет список членов, которые могут заполнить его.

Глядя на это из структур данных точки зрения, поставить член в связанном списке - каждый участник должен иметь дополнительный список [позиция, день], что они, наконец, назначены. Затем для каждой позиции, есть список ссылок на член, которые могут заполнить эту позицию. Реализовать категории, как другой список ссылок на позицию о том, какие категории он находится.

Фактическое назначение: есть счетчик дней = 0, и перебирать позиции. Для каждой позиции P, перебирать членов, которые могут заполнить его. Член М может заполнить позицию, если:

  • Любая позиция, которую он заполнил P2 не разделяет категории с P.
  • Любая позиция, которую он заполнил P2 с днем ​​= daycounter не разделяет группу с P.

Если он может заполнить положение, в положение [, день] пара добавляется к элементу, и узел на члена перемещается в конец списка (поэтому ссылки нужны - все ссылки по-прежнему в силе, даже несмотря на то, узел перемещается). Это гарантирует, что «пропускаются» члены наивысший приоритет, и члены, которые не были достигнуты получили следующий наивысший приоритет.

После того, как позиция заполняется, перейти к следующей позиции. Если позиция разделяет группу с позиции уже назначен, пропустите его, перебирая все позиции, пока вы не можете назначить столько позиций, как вы можете на день 1. Затем увеличиваем счетчик дней и повторить за день 2. Это должно дать вам максимальное задание (не уверен, что максимум) для всех рабочих мест.

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

Ответил 02/01/2010 в 18:16
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more