Проблемы с пониманием того, как выразить проблему реального мира в opensolver или minizinc для распределения рабочих

Я собираюсь начать с того, что я плохо разбираюсь в Minizinc или программировании ограничений, я смотрел учебные пособия по Excel на YouTube, которые я могу понять, но я не вижу, как я могу перевести свою проблему в решение, способное решить Excel , ни Minizinc, если на то пошло.

Чтобы объяснить проблему, у меня есть то, что я считаю проблемой многоуровневого рюкзака, но могу ошибаться. Вот что я считаю ограничениями

There are 25 "admin" who supervise over 200 "staff".
Each admin has a unique workload allocation.
Each admin also has to moderate staff 
    that is both equal to or greater than their supervisorial allocation 
    and has the ability to rate their moderation preference
Admin cannot supervise and moderate the same staff member.
Every staff member has to have both a supervisor and a moderator.

Чтобы понять проблему, я представил ее в виде таблицы

табличное представление набора образцов данных

  • a # = админ
  • s # = персонал
  • b = руководитель
  • v # = предпочтение модерации (ниже = лучше)

Взяв прилагаемый пример, мы можем видеть

admin1 является руководителем для Staff1, 13 и 17. Они вызвались умеренно staff2, 20, 10 и 23 в указанном порядке (предпочтение) .


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

  1. в каждой строке количество модераторов равно или больше руководителей,
  2. и в каждом столбце есть как уникальный руководитель, так и модератор (где учитывается возможный приоритет ниже = лучше).

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

Спасибо.


person Aaran    schedule 06.03.2019    source источник


Ответы (1)


Вы можете попробовать следующую MIP-модель в MiniZinc с решателем, установленным на OsiCbc.

int: n = 10;
int: m = 24;
set of int: ADMIN = 1..n;
set of int: STAFF = 1..m;

array[ADMIN,STAFF] of var 0..1: supervise;
array[ADMIN,STAFF] of var 0..1: moderate;

array[ADMIN, STAFF] of int: moderateValue = [|
0,4,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,3,0,0,1,0|
3,2,0,0,0,0,0,0,4,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0|
0,0,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,3,0,0,0,2|
0,0,0,1,0,0,0,0,0,0,3,2,0,0,0,0,0,4,0,0,0,0,0,0|
0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,3,0,0,0,0,2,0,1|
0,0,0,0,2,4,0,0,0,0,0,0,0,0,3,1,0,0,0,0,0,0,0,0|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,2,3,0,0,0,0,0,0|
0,2,0,0,0,0,0,4,0,0,0,0,3,1,0,0,0,0,0,0,0,0,0,0|
0,0,0,0,0,0,3,0,0,0,0,4,0,0,2,1,0,0,0,0,0,0,0,0|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,3,2,1|];

% admin member cannot both supervise and moderate staff member
constraint forall(a in ADMIN, s in STAFF)
    (supervise[a,s] + moderate[a,s] <= 1);

% each staff member is supervised by exactly one admin member
constraint forall(s in STAFF)
    (sum(col(supervise, s)) = 1);

% each staff member is moderated by exactly one admin member
constraint forall(s in STAFF)
    (sum(col(moderate, s)) = 1);

% each admin member cannot supervise more staff members than moderated
constraint forall(a in ADMIN)
    (sum(row(supervise, a)) <= sum(row(moderate, a)));

var int: obj = sum(a in ADMIN, s in STAFF)(moderateValue[a,s]*moderate[a,s]);

solve maximize obj;

output ["obj = \(obj)\n"] ++ ["assignment = \n"] ++ [show2d(array2d(ADMIN, STAFF, [if supervise[a,s] = 1 then 1 elseif moderate[a,s] = 1 then 2 else 0 endif | a in ADMIN, s in STAFF]))];

Не уверен, что понял все ваши требования, но надеюсь, что модель может послужить основой. Каждый admin участник может указать здесь значения модерации 4, 3, 2 и 1 для staff участников. Затем цель состоит в том, чтобы максимизировать сумму назначенных модераций. В выходных данных 1 означает, что член администратора контролирует сотрудника, 2 означает, что член администратора модерирует сотрудника, в противном случае отображается 0. Данные в модели основаны на приведенном примере.

Изменить: чтобы сделать supervise предопределенное изменение, выполните следующие действия:

%array[ADMIN,STAFF] of var 0..1: supervise;

array[ADMIN, STAFF] of int: supervise = [|
1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0|
0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0|
0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0|
0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0|
0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0|
0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1|
0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0|];
person Magnus Åhlander    schedule 07.03.2019
comment
Прежде всего, спасибо, что нашли время и помогли мне разобраться в этом. Я понял, что мой предыдущий комментарий не имеет смысла, поэтому я включил изображение ссылку, чтобы попытаться объяснить. Проблема заключается в том, что зеленое значение b является статическим, поэтому каждый столбец имеет 1 из них, решателю не нужно их перемещать, просто учитывайте их расположение при попытке решить, какую из доступных желтых ячеек v # выбрать для этот перикулярный столбец. Я надеюсь, что это продолжение имеет смысл. - person Aaran; 08.03.2019
comment
Что здесь означают b и v#? Контролирует и модерирует соответственно? Что исправить и что еще предстоит решить? - person Magnus Åhlander; 08.03.2019
comment
Привет, 'b' представляет заранее определенную роль супервизора, смотрящую на образцы данных. A1 - супервизор для s1, s13 и s17. v # - это варианты модерации переменных, a1 - s2, s10, s20 и s23. Я надеюсь, что это поможет прояснить это. - person Aaran; 12.03.2019
comment
Обновлен ответ, указав supervise заранее. - person Magnus Åhlander; 12.03.2019
comment
Могу я проверить, какую версию minizinc вы используете? У меня последняя версия IDE, но она выдает ошибку MiniZinc: type error: undefined identifier `meanValue 'Я попробую с предыдущей версией, так как это может быть ошибкой. - person Aaran; 13.03.2019
comment
Я могу скопировать и вставить код в ответ MiniZinc IDE, и он будет работать без ошибок. - person Magnus Åhlander; 13.03.2019
comment
Я дважды проверил, но все еще получаю сообщение об ошибке вывода проблемы imgur.com/zSON3x3 - person Aaran; 14.03.2019
comment
Вы случайно удалили moderateValue-параметр. Просто возьмите код из исходного ответа, затем замените supervise-часть кодом после редактирования (не удаляйте moderateValue). - person Magnus Åhlander; 14.03.2019
comment
Получилось, спасибо за то, что проявили достаточно терпения, чтобы провести меня через это. - person Aaran; 14.03.2019