OR-工具最大化员工排班中的可行转变

问题描述 投票:0回答:1

我在一家非政府组织工作,我们正在尝试为志愿者组织轮班。

目标:分配志愿者轮班,最大限度地增加可行的轮班数量并尊重每个人的可用性。

轮班数=当月天数(每天1班)

轮班可行性的限制:

  • 为了可行,一个班次必须有 3 名志愿者
  • 为了可行,一个班次不能超过 4 名志愿者
  • 为了使轮班可行,必须将一名志愿者视为“参照人”

对志愿者的限制:

  • 志愿者每天轮班次数不得超过 3 次
  • 志愿者必须在两班之间休息六天

基于这个例子我成功地对问题进行了建模。

# 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
    )
)

一切正常,但我有一个主要问题:

当前模型试图最大化分配的任务,但目标是最大化可行轮班的数量(轮班不必每天进行)。如何相应地定义模型?我应该添加一个二元变量来鼓励模型产生可行的转变吗?

感谢您的专业知识!

python optimization scheduling or-tools cp-sat
1个回答
0
投票

每个班次创建一个布尔变量,如果执行班次,该变量将为 true,然后最大化这些变量的总和。

© www.soinside.com 2019 - 2024. All rights reserved.