Python 公平转移分配

Python 公平转移分配,python,or-tools,Python,Or Tools,我有一个稍微修改过的护士sat版本 我有一本字典,里面有(白天、护士、轮班)=布尔瓦尔的关键值pare 我想让所有护士每班都有相同的工作量 例如:假设我们有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(

我有一个稍微修改过的护士sat版本

我有一本字典,里面有(白天、护士、轮班)=布尔瓦尔的关键值pare 我想让所有护士每班都有相同的工作量

例如:假设我们有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)]))
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)))
因此,护士的最大k班次数等于最小值,如果num_天数为30天,他们都应该有10个k班次

然而,我不能让它工作,我不确定为什么。为了使用IntVar而不是_SumArray,我做了如下操作:

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)]))
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的情况下,它工作,但给出错误的结果。我想我总结了一些错误,但我不确定是什么。

fairshift={}
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)
对于范围内的n(数量): 对于范围内的s(num_移位): 班次之和[(n,s)]=model.NewIntVar(0,num_天,'sum_of_班次之和'%i'%(n,s)) model.Add(班次之和[(n,s)]==范围内d的班次之和[(d,n,s)](天数))) 对于范围内的s(num_移位): min\u fair\u shift=model.NewIntVar(0,num\u天,'min\u fair\u shift\u%i'%s) max\u fair\u shift=model.NewIntVar(0,num\u天,'max\u fair\u shift\u%i'%s) 模型.AddMinEquality(范围内n(护士人数)]的最小/平均/班次[班次之和[(n,s)]) model.AddMaxEquality(范围内n(num)的最大公平移位[移位总和[(n,s)]) Add(max_fair_shift-min_fair_shift
fairshift={}
对于范围内的n(数量):
对于范围内的s(num_移位):
班次之和[(n,s)]=model.NewIntVar(0,num_天,'sum_of_班次之和'%i'%(n,s))
model.Add(班次之和[(n,s)]==范围内d的班次之和[(d,n,s)](天数)))
对于范围内的s(num_移位):
min\u fair\u shift=model.NewIntVar(0,num\u天,'min\u fair\u shift\u%i'%s)
max\u fair\u shift=model.NewIntVar(0,num\u天,'max\u fair\u shift\u%i'%s)
模型.AddMinEquality(范围内n(护士人数)]的最小/平均/班次[班次之和[(n,s)])
model.AddMaxEquality(范围内n(num)的最大公平移位[移位总和[(n,s)])

Add(max_fair_shift-min_fair_shift)第一个快速注释,您应该有
max(fair_shift)-min(fair_shift),但真正的问题是,您不能使用python的min()和max()运算符,因为这是在模型不理解的情况下扩展的。它适用于sum()但不适用于最小值/最大值。您应该使用带有中间整数变量的
model.AddMaxEquality()
model.AddMinEquality()
。您好@Laurent Perron,我认为是因为max([IntVar])返回IntVar,它也可以工作,现在已经修复了。我之前尝试过AddMaxEquality,但是我遇到了一个错误,但是_SumArray没有索引,但是它可以将IntVar分配给fairshift[(j,k)]。谢谢!如果你想得到这个答案,我很乐意接受。第一个快速评论,你应该有
max(fairshift)-min(fair_shifts)但真正的问题是,您不能使用python的min()和max()运算符,因为这是在模型无法理解的情况下展开的。它适用于sum(),但不适用于min/max。您应该使用
model.AddMaxEquality()
model.AddMinEquality()
使用中间整数变量。Hello@Laurent Perron,我想既然max([IntVar])返回IntVar,它也可以工作,现在它已经修复了。我之前尝试过AddMaxEquality,但我遇到了一个错误,但是_SumArray没有索引,但它可以将IntVar分配给fairshift[(j,k)].谢谢!如果你愿意回答这个问题,我很乐意接受。