我正在编写一个程序,根据预先定义的班次(时间段)和学生可用性(以及时间段)帮助安排我们大学的学生员工。
这让我觉得类似于Air Crew问题,除了模拟一个员工不仅仅是普遍可用的约束:它取决于他们的日程安排。
一个经验丰富的约束程序员可以推荐哪些建模策略来解决这个问题?
(我正在使用Gecode。)
答案 0 :(得分:3)
这样做最好(或好)的方式肯定取决于你对时间表的表示。
一个简单的变体是添加二进制可用性矩阵,其中x [i,j] = 1表示第i个人在第j天可用(或根据您对时间表的表示进行转置)。
这个(简单)示例是通过采用MiniZinc的护士排班标准模型(“tutorial / nurse.mzn”,“常规”约束的展示案例),然后添加可用性矩阵。这是我的版本:http://www.hakank.org/minizinc/nurse_rostering_with_availability.mzn
为某人的特定位置分配必须确保某人在特定日期可以工作,如下所示(“available [i,j] = 1”)。
% availability matrix
array[1..num_nurses, 1..num_days] of int: available =
array2d(1..num_nurses, 1..num_days,
[
% days
1,1,0,1,1,1,1, 1,1,1,0,1,1,1, % nurses
0,1,1,1,0,1,1, 0,1,1,1,1,1,1,
1,0,1,1,0,1,1, 1,0,0,1,1,0,1,
1,1,1,1,1,0,1, 1,0,1,1,1,1,0,
1,1,1,0,1,1,1, 1,1,1,1,0,1,1,
1,1,0,1,1,0,1, 1,1,0,1,1,1,0,
1,1,1,0,1,1,1, 1,1,1,0,1,1,1,
]);
% ...
% for each day the must be at least 3 nurses with day shift,
% and 2 nurses with night shifht
constraint
forall(j in 1..num_days) (
sum(i in 1..num_nurses) (
bool2int(x[i,j] == day_shift /\ available[i,j] = 1) ) >= 3
/\
sum(i in 1..num_nurses) (
bool2int(x[i,j] == night_shift /\ available[i,j] = 1) ) >= 2
)
;
另外,为了在他/她不可用的那天强迫某人下班,我们在此模型中将其设置为“off_shift”。
constraint
forall(i in 1..num_nurses, j in 1..num_days) (
if available[i,j] = 0 then
x[i,j] = off_shift
else
true
endif
)
;