Этот новый ответ имеет дело с более общей проблемой генерации действительного расписания. В этом случае мы имеем дело с переменными решения , поэтому другой подход не может быть легко реализован.
Мое предложение состоит в том, чтобы использовать регулярное глобальное ограничение иметь дело с подсчетом чисел m
и l
. Это гарантирует, что предоставленное решение не помещает в последовательность более 6
подпоследовательный m
(игнорируя o
и одиночный l
).
Пример:
include "globals.mzn";
enum TypeOfShift = {l,m,o};
% sat:
%array[1..30] of var TypeOfShift: shift = [m, m, m, l, l, o, m, m, m, m, l, l, l, m, m, m, m, m, m, l, l, m, m, m, m, m, l, l, l, l];
% sat:
%array[1..30] of var TypeOfShift: shift = [l, l, l, l, l, m, m, m, o, o, l, l, l, m, m, m, m, m, l, l, l, m, m, m, m, m, l, l, m, m];
% unsat: too many m
% array[1..30] of var TypeOfShift: shift = [m, m, l, l, m, o, m, m, m, m, l, l, l, m, m, m, m, m, m, m, m, m, m, m, m, m, l, l, l, m];
% unsat: o breaks double l
% array[1..30] of var TypeOfShift: shift = [l, l, l, l, l, m, m, m, o, o, l, l, l, m, m, m, m, m, l, o, l, m, m, m, m, m, l, l, m, m];
% free assignment
% [NOTE: this will give a trivial answer because of missing constraints]
array[1..30] of var TypeOfShift: shift;
% | 1 2 3 <= Input Values
% | m o l
% ----------------------------
% 1 m0_l0 | m1_l0 m0_l0 m0_l1
% 2 m1_l0 | m2_l0 m1_l0 m1_l1
% 3 m2_l0 | m3_l0 m2_l0 m2_l1
% 4 m3_l0 | m4_l0 m3_l0 m3_l1
% 5 m4_l0 | m5_l0 m4_l0 m4_l1
% 6 m5_l0 | m6_l0 m5_l0 m5_l1
% 7 m6_l0 | - m6_l0 m6_l1
% 8 m0_l1 | m1_l0 m0_l0 m0_l0
% 9 m1_l1 | m2_l0 m1_l0 m0_l0
% 10 m2_l1 | m3_l0 m2_l0 m0_l0
% 11 m3_l1 | m4_l0 m3_l0 m0_l0
% 12 m4_l1 | m5_l0 m4_l0 m0_l0
% 13 m5_l1 | m6_l0 m5_l0 m0_l0
% 14 m6_l1 | - m6_l0 m0_l0
% ^
% states
array[1..14, 1..3] of 0..14: transition_relation =
[| 2, 1, 8, % m0_l0
| 3, 2, 9, % m1_l0
| 4, 3, 10, % m2_l0
| 5, 4, 11, % m3_l0
| 6, 5, 12, % m4_l0
| 7, 6, 13, % m5_l0
| 0, 7, 14, % m6_l0
| 2, 1, 1, % m0_l1
| 3, 2, 1, % m0_l2
| 4, 3, 1, % m0_l3
| 5, 4, 1, % m0_l4
| 6, 5, 1, % m0_l5
| 7, 6, 1, % m0_l6
| 0, 7, 1, % m0_l7
|];
constraint regular(
[ if s == m then 1 else
if s == o then 2 else
3 endif
endif
| s in shift], % sequence of input values
14, % number of states
card(TypeOfShift), % number of different input values of state machine
transition_relation, % transition relation
1, % initial state
1..14, % final states
);
solve satisfy;
Важные примечания:
также можно использовать для проверки существующих решений;
следует поместить ограничение normal в предикат , чтобы его можно было легко применить ко всем сотрудникам без дублирования кода;
MiniZinc
печатает тривиальный ответ для этой модели только потому, что нет никаких других ограничений на массив shifts
(т. Е. минимальное число m
, требуемое в месяц ).