问题
I have a slightly modified version of nurse_sat
https://github.com/google/or-tools/blob/master/examples/python/nurses_sat.py
where I have a dictionary of key - value pares of (day, nurse, shift) = BoolVar
I want to make it so all nurses have same amount of each shift.
E.G: Let's assume that we have 30 days, and there are 3 shifts per day {0, 1, 2} and we have 3 nurses {a, b, c}
I would like to have all nurses do 10 of shift 0, 10 of shift 2 and 10 of shift 3.
The way I am trying to achieve this is:
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))
In theory, that should give me how many particular shift a nurse had. E.G: fairshift[(0, 0)] should have the number of the 0 shifts Nurse A had throughout the week. And then to make them equal, I did something like this:
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)]))
So that max number of k shifts a nurse had would be equal to the min one and if num_days is 30 they all should have 10 shifts of shift k.
However, I can't get it to work and I am unsure of why. To have IntVar instead of _SumArray, I did something like this:
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)))
In the case of min .== max, it works but gives wrong results. I think I'm summing something wrong, but I am unsure what it is.
回答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)
来源:https://stackoverflow.com/questions/53356121/fair-shift-distribution