如何解决为什么ortools 严格设置约束?
我经历了 google ortools scheduling tutorial 并创建了稍微不同的约束。
- 每位护士只能在预先分配的班次上工作。根据表格,护士 0 必须在 0 或 1 班工作,护士 2 必须只在 2 班工作,依此类推。
- 此外,我添加了以下约束:“如果nurse_0 需要shift_0,那么她必须需要shif_1”。它由“is_child”列显示 - shift_1 是 child_shift for shift_0 fornurse_0。
df_dict = {
"slot_number":[1,1,2,3],"asset_name":['0','1','0','2'],"is_child":["No","No","Yes",'No','No']
}
df = pd.DataFrame.from_dict(df_dict)
创建变量和模型:
num_nurses = 3
num_shifts = 3
all_nurses = range(num_nurses)
all_shifts = range(num_shifts)
model = cp_model.CpModel()
shifts = {}
for n in all_nurses:
for s in all_shifts:
shifts[(n,s)] = model.NewBoolVar('shift_n%is%i' % (n,s))
一名护士只能轮班:
for s in all_shifts:
model.Add(sum(shifts[(n,s)] for n in all_nurses) == 1)
我的约束:
# whether the slot (key) have any children in other slots
children = {0: [1],1: [],2: []}
# what nurses are considered the children (values) in which slot (key)
nurse_child_sched = {0:[],1:[0],2:[]}
# In this case if nurse 0 take slot 0,then she must take slot 1 too.
for s in all_shifts:
for n in all_nurses:
if (children[s]):
for child in children[s]:
if n in nurse_child_sched[child]:
model.Add((shifts[(n,s)] + shifts[(n,child)])==2)
print(f"{s}-parent_slot and {child}-child_slot were connected for nurse {n}")
class NursesPartialSolutionPrinter(cp_model.cpsolverSolutionCallback):
"""Print intermediate solutions."""
def __init__(self,shifts,num_nurses,num_shifts,sols):
cp_model.cpsolverSolutionCallback.__init__(self)
self._shifts = shifts
self._num_nurses = num_nurses
self._num_shifts = num_shifts
self._solutions = set(sols)
self._solution_count = 0
def on_solution_callback(self):
if self._solution_count in self._solutions:
print('Solution %i' % self._solution_count)
for n in range(self._num_nurses):
is_working = False
for s in range(self._num_shifts):
if self.Value(self._shifts[(n,s)]):
is_working = True
print(' Nurse %i works shift %i' % (n,s))
if not is_working:
print(' Nurse {} does not work'.format(n))
print()
self._solution_count += 1
def solution_count(self):
return self._solution_count
solver = cp_model.cpsolver()
solver.parameters.linearization_level = 0
a_few_solutions = range(5)
solution_printer = NursesPartialSolutionPrinter(shifts,a_few_solutions)
solver.SearchForAllSolutions(model,solution_printer)
最后,我得到以下结果:
Solution 0
Nurse 0 works shift 0
Nurse 0 works shift 1
Nurse 1 works shift 2
Nurse 2 does not work
Solution 1
Nurse 0 works shift 0
Nurse 0 works shift 1
Nurse 1 does not work
Nurse 2 works shift 2
Solution 2
Nurse 0 works shift 0
Nurse 0 works shift 1
Nurse 0 works shift 2
Nurse 1 does not work
Nurse 2 does not work
不过,按照我的逻辑,至少也必须有下面的解决方案。我意识到,我的约束表明模型将nurse_0 放在shift_0 上,但我只需要放置两个插槽之间的关系,以防nurse_0 放在第一班,否则没有约束。提前致谢。
Solution x
Nurse 1 works shift 0
Nurse 0 works shift 1
Nurse 0 works shift 2
Nurse 1 does not work
Nurse 2 does not work
解决方法
附注:
一名护士只能轮班:
for s in all_shifts:
model.Add(sum(shifts[(n,s)] for n in all_nurses) == 1)
这里你写了“每个班次只分配给一名护士”
如果你想表达“一个护士只能轮班”,你应该写:
for n in all_nurses:
model.Add(sum(shifts[(n,s)] for s in all_shifts) == 1)
注意:但在这种情况下,由于护士只工作一个班次,因此不可能进行儿童班次,所以我猜您的代码没问题,而不是注释...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。