我在一家非政府组织工作,我们正在尝试为志愿者组织轮班。
目标:分配志愿者轮班,最大限度地增加可行的轮班数量并尊重每个人的可用性。
轮班数=当月天数(每天1班)
轮班可行性的限制:
对志愿者的限制:
基于这个例子我成功地对问题进行了建模。
# X_is = 1 if volunteer i is assigned to shift s
var_X = {}
for i in all_volunteers:
for s in all_shifts:
var_X[(i, s)] = model.NewBoolVar(f"X_i{i}_s{s}")
# At least 3 volunteers by shifts
for s in all_shifts:
model.Add(sum(var_X[i, s] for i in all_volunteers) >= 3)
# Maximum 4 volunteers by shift
for s in all_shifts:
model.Add(sum(var_X[i, s] for i in all_volunteers) <= 4)
# At least one referent by shift with y[i] = 1 if volunteer i is referent
for s in all_shifts:
model.Add(sum((var_X[i, s]*y[i]) for i in all_volunteers) >= 1)
# Max 3 shifts by volunteer
for i in all_volunteers:
model.Add(sum(var_X[i, s] for s in all_shifts) <= 3)
# Break of 6 days between shifts
time_break = 6
range_max = range(nb_shifts - time_break)
for i in all_volunteers:
for s in range_max:
model.Add(sum(var_X[i, w] for w in range(s, s + (time_break + 1))) <= 1)
# Objective function with var_D[i][s] = 1 if volunteer i is availiable on shift s:
model.Maximize(
sum(
(var_X[(i,s)] * var_D[i][s])
for i in all_volunteers
for s in all_shifts
)
)
一切正常,但我有一个主要问题:
当前模型试图最大化分配的任务,但目标是最大化可行轮班的数量(轮班不必每天进行)。如何相应地定义模型?我应该添加一个二元变量来鼓励模型产生可行的转变吗?
感谢您的专业知识!
每个班次创建一个布尔变量,如果执行班次,该变量将为 true,然后最大化这些变量的总和。