公平班次分配
Posted
技术标签:
【中文标题】公平班次分配【英文标题】:Fair Shift Distribution 【发布时间】:2018-11-17 22:25:53 【问题描述】:我有一个稍微修改过的nurse_sat版本https://github.com/google/or-tools/blob/master/examples/python/nurses_sat.py 我有一个键值字典(天,护士,班次)= BoolVar 我想让所有护士每次轮班的数量都相同。
E.G:假设我们有 30 天,每天有 3 个班次 0,1,2,我们有 3 名护士 a,b,c 我想让所有护士做 0 班 10、2 班 10 和 3 班 10。
我试图实现的方法是:
fairshift =
for j in range(num_nurses):
for k in range(num_shifts):
fairshift[(j,k)] = sum(shifts[(i, j, k)] for i in range(num_days))
理论上,这应该让我知道一名护士有多少特定的班次。例如: fairshift[(0, 0)] 应该有护士 A 一周内的 0 班次的数量。然后为了让他们平等,我做了这样的事情:
for k in range(num_shifts):
solver.Add(min([fairshift[(j, k)] for j in range(num_nurses)]) == max([fairshift[(j,k)] for j in range(num_nurses)]))
因此,护士的最大 k 班次将等于最小的一次,如果 num_days 为 30,则他们都应该有 10 班 k 班次。
但是,我无法让它工作,我不确定为什么。为了有 IntVar 而不是 _SumArray,我做了这样的事情:
for j in range(num_nurses):
for k in range(num_shifts):
fairshift[(j,k)] = solver.NewIntVar(0, num_days, "%i,%i" % (j,k))
solver.Add(fairshift[(j,k)] == sum(shifts[(i, j, k)] for i in range(num_days)))
在 min .== max 的情况下,它可以工作,但会给出错误的结果。我想我总结错了,但我不确定它是什么。
【问题讨论】:
第一个快速评论,你应该有max(fair_shifts) - min(fair_shifts) <= 1
来解释当班次数不是人数的倍数时的情况。
但真正的问题是你不能使用 python 的 min() 和 max() 操作符,因为它被扩展为模型无法理解的东西。它适用于 sum() 但不适用于 min/max。您应该将model.AddMaxEquality()
和model.AddMinEquality()
与中间整数变量一起使用。
你好@Laurent Perron,我想既然 max([IntVar]) 返回 IntVar,它也可以工作,现在已经修复了。我之前尝试过 AddMaxEquality,但出现错误但 _SumArray 没有索引,但它可以将 IntVars 分配给 fairshift[(j, k)]。谢谢!如果您想将此作为答案,我很乐意接受。
【参考方案1】:
fairshift =
for n in range(num_nurses):
for s in range(num_shifts):
sum_of_shifts[(n, s)] = model.NewIntVar(0, num_days, 'sum_of_shifts_%i_%i' % (n, s))
model.Add(sum_of_shifts[(n, s)] == sum(shifts[(d, n, s)] for d in range(num_days)))
for s in range(num_shifts):
min_fair_shift = model.NewIntVar(0, num_days, 'min_fair_shift_%i' % s)
max_fair_shift = model.NewIntVar(0, num_days, 'max_fair_shift_%i' % s)
model.AddMinEquality(min_fair_shift, [sum_of_shifts[(n, s)] for n in range(num_nurses)])
model.AddMaxEquality(max_fair_shift, [sum_of_shifts[(n, s)] for n in range(num_nurses)])
model.Add(max_fair_shift - min_fair_shift <= 1)
【讨论】:
以上是关于公平班次分配的主要内容,如果未能解决你的问题,请参考以下文章