基于OR-Tools的志愿者排班优化:最大化可行班次的模型调整问询
调整志愿者排班模型以最大化可行班次数量
要实现最大化可行班次数量的目标,必须添加二进制变量标记班次是否开设,并调整约束和目标函数,具体步骤如下:
1. 新增班次状态变量
定义二进制变量var_Y[s],其中var_Y[s] = 1表示班次s被开设(即该班次是可行的),var_Y[s] = 0表示班次s不开设。
var_Y = {} for s in all_shifts: var_Y[s] = model.NewBoolVar(f"Y_s{s}")
2. 修改班次约束,关联班次状态
原有班次约束(人数范围、负责人要求)仅需对被开设的班次生效,因此要将约束与var_Y[s]绑定:
- 每个开设的班次至少3名志愿者:
for s in all_shifts: model.Add(sum(var_X[i, s] for i in all_volunteers) >= 3 * var_Y[s])
- 每个开设的班次最多4名志愿者:
for s in all_shifts: model.Add(sum(var_X[i, s] for i in all_volunteers) <= 4 * var_Y[s])
- 每个开设的班次至少1名负责人(
y[i]为1表示志愿者i是负责人):
for s in all_shifts: model.Add(sum(var_X[i, s] * y[i] for i in all_volunteers) >= 1 * var_Y[s])
- 额外约束:若志愿者被指派到班次
s,则该班次必须开设(避免出现无人开设但有志愿者指派的矛盾):
for i in all_volunteers: for s in all_shifts: model.Add(var_X[(i, s)] <= var_Y[s])
3. 调整目标函数
将原目标(最大化志愿者指派数)替换为最大化被开设的班次数量:
model.Maximize(sum(var_Y[s] for s in all_shifts))
4. 保留原有志愿者约束
原有的志愿者约束(每人最多3个班次、班次间隔6天休息)无需修改,因为var_X[i,s]仅在var_Y[s]=1时可能为1,约束会自动对有效指派生效。
内容的提问来源于stack exchange,提问作者Julien Chil
相关产品推荐
相关产品推荐

