公平的班次分配

时间:2018-11-17 22:25:54

标签: python or-tools

我有一个稍微修改过的版本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个班次等于最小的1个班次,如果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的情况下,它可以工作,但给出错误的结果。我想我是在总结错误,但是我不确定是什么。

1 个答案:

答案 0 :(得分:2)

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)