Мне задали вопрос, где я должен создать набор команд с простым ограничением, когда есть два массива наборов, в которых два члена должны быть вместе, а какие нет. Я новичок в Minizinc, поэтому мне трудно работать с переменной решения с массивом наборов. Команды также должны быть размером n.

Например:

GroupsThatMustBePaired = [{1,3},{4,5}]
GroupsThatShouldNot = [{2,3}]

Output = [{1,3},{4,5},{2,6}..etc]

Любая помощь?

1
David Goliath 24 Апр 2020 в 11:57

1 ответ

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

Ниже приведен пример того, как вы можете написать свою модель. У него есть несколько дополнительных ограничений, чтобы убедиться, что «команды» содержат всех, дважды никого, а максимальная вместимость включает «all_disjoint.mzn»;

set of int: MEMBERS = 1..6;
set of int: GROUPS = 1..3;
array[int] of set of MEMBERS: GroupsThatMustBePaired = [{1,3},{4,5}];
array[int] of set of MEMBERS: GroupsThatShouldNot = [{2,3}];

array[GROUPS] of var set of MEMBERS: teams;

% Team members can only be part of one team
constraint all_disjoint(teams);
% Everyone must be part of a team
constraint array_union(teams) = MEMBERS;
% Maximal number of people per group
constraint forall(g in GROUPS) ( card(teams[g]) <= 2 );

% Eliminate bad groups
constraint forall(g in GROUPS, i in index_set(GroupsThatShouldNot)) (
  not (GroupsThatShouldNot[i] subset teams[g])
);

% Enforce good groups
constraint forall(i in index_set(GroupsThatMustBePaired)) (
  exists(g in GROUPS) (
    GroupsThatMustBePaired[i] subset teams[g]
  )
);

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

В этом конкретном случае вы можете рассмотреть возможность использования целочисленных переменных. Эту проблему можно рассматривать как проблему назначения, когда участники распределяются по командам. При этом учитывается точка зрения членов команды, а не команды. Хотя это, вероятно, затруднит написание ограничения subset, эта структура устранит необходимость в ограничениях all_disjoint и array_union, поскольку мы знаем все будут в команде, и никто не будет в нескольких командах. В этом случае ограничение набора card (количество элементов) можно заменить целочисленным ограничением global_cardinality_low_up.

2
Dekker1 25 Апр 2020 в 02:22
Спасибо большое! Это было большим подспорьем. Знаете ли вы какие-либо ресурсы, которые я мог бы использовать, чтобы попрактиковаться в этом больше? В частности, работа с установленными переменными.
 – 
David Goliath
25 Апр 2020 в 04:17
Вы можете посмотреть примеры Set в учебнике MiniZinc: minizinc.org/doc-2.4.3/en/modelling2.html#set-constraints. Как правило, практика в MiniZinc основана на создании моделей. Я думаю, что разумно сосредоточиться на моделировании, а не на каком-то конкретном аспекте MiniZinc. Три курса MiniZinc на Coursera — отличная отправная точка, если у вас нет большого опыта работы с MiniZinc.
 – 
Dekker1
25 Апр 2020 в 10:46
Эй, большое спасибо! У меня также был еще один быстрый вопрос. Я рассчитываю общую конкуренцию турнира, когда один игрок объединяется с другим, которые очень хорошо дополняют друг друга. Итак, у нас есть efficiencyGroup = {[4,5], [6]}. Конкуренция рассчитывается по тому, сколько людей в группе эффективности объединяется в пары. Итак, если игрок 1 (строка i соответствует игроку i) объединяется с 4 и 5, то счет равен 2. Я хотел сделать пересечение, но у меня возникли проблемы с тем, как мне его повторить. Любые идеи?
 – 
David Goliath
29 Апр 2020 в 07:20