这是 MiniZinc 中一个非常简单的约束编程模型 - 给定适当的求解器 - 为(我的解释)问题生成所有可能的有效解决方案。然而,正如@TimChippingtonDerrick 指出的那样,对于更复杂的问题实例,解决方案太多了。
也就是说,如果可以在模型中以某种方式说明目标(obj = "2a + 5b")(例如,使用面试官/申请人的一些额外数据等),只需将其更改为优化问题,即最小化或最大化该目标。
因此,这里是一个简单问题实例(x=10、y=5、z=10 和 m=3)的 MiniZinc 模型。注:在面试表中,数值0(零)表示当时没有面试官的面试。
include "globals.mzn";
int: x = 10; % number of time slots
int: y = 5; % number of faculty interviewers
int: z = 10; % number of applicants interviewing
int: m = 3; % number of times each applicants will be interviewed
% decision variables
% The interview table:
% 1..y: rows (interviewers)
% 1..x: columns (time slots)
array[1..y, 1..x] of var 0..z: s;
% solve satisfy;
solve :: int_search([s[i,j] | i in 1..y, j in 1..x], first_fail, indomain_random, complete) satisfy;
constraint
% A z digit can only appear once in each row/column like Sudoku (because an applicant
% can't interview with the same interviewer twice and he/she can't interview twice at once).
forall(a in 1..z) (
% rows
forall(i in 1..y) (
%sum([bool2int(s[i,j] = a) | j in 1..x]) <= 1
alldifferent_except_0([bool2int(s[i,j] = a) | j in 1..x])
)
/\
% columns
forall(j in 1..x) (
% sum([bool2int(s[i,j] = a) | i in 1..y]) <= 1
alldifferent_except_0([bool2int(s[i,j] = a) | i in 1..y])
)
)
% There has to be exactly 3 of each z number in the entire table
% (because all applicants have to interview exactly 3 times).
/\
forall(a in 1..z) (
count([s[i,j] | i in 1..y, j in 1..x], a, m)
)
;
% constraint
% % symmetry breaking: assign applicant a to interviewer a in time a (if possible)
% forall(a in 1..z where a <= y) (
% s[a,a] = a
% )
% ;
output [
"x (number of time slots (rows): " ++ show(x) ++ "\n" ++
"y (number of interviews (columns): " ++ show(y) ++ "\n" ++
"z (number of applicants): " ++ show(z) ++ "\n"
]
++
[
if j = 1 then "\n" else " " endif ++
show_int(2,s[i,j])
| i in 1..y, j in 1..x
];
对于这个问题(x=10,y=5,z=10),有大量的解决方案。这是其中的两个:
x (number of time slots (rows): 10
y (number of interviews (columns): 5
z (number of applicants): 10
5 2 10 8 0 6 7 4 3 9
3 1 5 7 0 2 9 6 8 4
8 0 0 5 6 1 10 3 0 7
2 10 1 0 0 9 0 0 0 0
0 0 0 0 0 4 0 0 0 0
----------
x (number of time slots (rows): 10
y (number of interviews (columns): 5
z (number of applicants): 10
5 2 10 8 0 6 7 4 3 9
3 1 5 7 0 2 9 6 8 4
8 0 0 5 6 1 10 3 0 7
2 10 0 1 0 9 0 0 0 0
0 0 0 0 0 4 0 0 0 0
(这个 MiniZinc 模型也在这里:http ://www.hakank.org/minizinc/interview_scheduling.mzn )
对一个更简单的问题 (x=6,y=3,z=3, m=3) 的数字注释以显示问题的多样性:不使用对称破坏时有 317760 种不同的解决方案(在代码)。随着对称性的破坏,它的解决方案要少得多:1300。这是这些解决方案之一:
1 0 0 3 2 0
3 2 1 0 0 0
0 1 3 2 0 0