OR-TOOLS 调度以防止连续轮班
OR-TOOLS Scheduling to prevent consecutive shifts
我是新手,但有一些时间表求解器的工作代码。我唯一想不通的是如何确保员工不连续工作(service_blocks)。
我只想确定医生不会连续两班倒。看起来并不难,但我很烂。我尝试了很多变体,但似乎没有任何效果。 (我的尝试没有在下面显示。)只是寻求帮助。
如何阅读我的代码:
医生 = 雇员
Service_blocks = 班次
角色 = 基本上是他们工作的医院。
代码如下:
class DoctorPartialSolutionPrinter(cp_model.CpSolverSolutionCallback):
"""Print intermediate solutions."""
def __init__(self, roles, num_doctors, num_service_block, num_roles, sols):
cp_model.CpSolverSolutionCallback.__init__(self)
self._roles = roles
self._num_doctors = num_doctors
self._num_service_block = num_service_block
self._num_roles = num_roles
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 b in range(self._num_service_block):
print('----------Service Block %i -----------' % (b+1))
for d in range(self._num_doctors):
is_working = False
for r in range(self._num_roles):
if self.Value(self._roles[(d, b, r)]):
is_working = True
str1 = " works role: "
#print("N:" , n)
#print("S:", s)
print(doctor_list[d], str1, role_list[r] )
#print(' Doctor %i works role ' % ((n+1)), end = '')
#print(role_list[s-1])
#if not is_working:
#print(' Doctor {} does not work'.format(n+1))
print()
self._solution_count += 1
def solution_count(self):
return self._solution_count
def main():
# Data.
num_doctors = 27 # we should build this number from the doctor_list array
num_roles = 9 # I think this is really one less since the index is zero
num_service_block = 24
all_doctors = range(num_doctors)
all_roles = range(num_roles)
all_service_blocks = range(num_service_block)
# Creates the model.
model = cp_model.CpModel()
# Creates role variables.
roles = {}
for d in all_doctors:
for b in all_service_blocks:
for r in all_roles:
roles[(d, b, r)] = model.NewBoolVar('role_d%ib%ir%i' % (d, b, r))
# Each role is assigned to exactly one doctor in the schedule period.
for b in all_service_blocks:
for r in all_roles:
model.Add(sum(roles[(d, b, r)] for d in all_doctors) == 1)
# Each doctor works at most one role per service block.
for d in all_doctors:
for b in all_service_blocks:
model.Add(sum(roles[(d, b, r)] for r in all_roles) <= 1)
print((sum(roles[(d, b, r)] for r in all_roles)))
你可以使用 model.AddImplication(boolvar, boolvar)
:
for d in all_doctors:
for b in all_service_blocks[:-1]:
for r in all_roles:
for r1 in all_roles:
model.AddImplication(roles[(d, b, r)], roles[(d, b+1, r1)].Not())
我是新手,但有一些时间表求解器的工作代码。我唯一想不通的是如何确保员工不连续工作(service_blocks)。
我只想确定医生不会连续两班倒。看起来并不难,但我很烂。我尝试了很多变体,但似乎没有任何效果。 (我的尝试没有在下面显示。)只是寻求帮助。
如何阅读我的代码: 医生 = 雇员
Service_blocks = 班次
角色 = 基本上是他们工作的医院。
代码如下:
class DoctorPartialSolutionPrinter(cp_model.CpSolverSolutionCallback):
"""Print intermediate solutions."""
def __init__(self, roles, num_doctors, num_service_block, num_roles, sols):
cp_model.CpSolverSolutionCallback.__init__(self)
self._roles = roles
self._num_doctors = num_doctors
self._num_service_block = num_service_block
self._num_roles = num_roles
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 b in range(self._num_service_block):
print('----------Service Block %i -----------' % (b+1))
for d in range(self._num_doctors):
is_working = False
for r in range(self._num_roles):
if self.Value(self._roles[(d, b, r)]):
is_working = True
str1 = " works role: "
#print("N:" , n)
#print("S:", s)
print(doctor_list[d], str1, role_list[r] )
#print(' Doctor %i works role ' % ((n+1)), end = '')
#print(role_list[s-1])
#if not is_working:
#print(' Doctor {} does not work'.format(n+1))
print()
self._solution_count += 1
def solution_count(self):
return self._solution_count
def main():
# Data.
num_doctors = 27 # we should build this number from the doctor_list array
num_roles = 9 # I think this is really one less since the index is zero
num_service_block = 24
all_doctors = range(num_doctors)
all_roles = range(num_roles)
all_service_blocks = range(num_service_block)
# Creates the model.
model = cp_model.CpModel()
# Creates role variables.
roles = {}
for d in all_doctors:
for b in all_service_blocks:
for r in all_roles:
roles[(d, b, r)] = model.NewBoolVar('role_d%ib%ir%i' % (d, b, r))
# Each role is assigned to exactly one doctor in the schedule period.
for b in all_service_blocks:
for r in all_roles:
model.Add(sum(roles[(d, b, r)] for d in all_doctors) == 1)
# Each doctor works at most one role per service block.
for d in all_doctors:
for b in all_service_blocks:
model.Add(sum(roles[(d, b, r)] for r in all_roles) <= 1)
print((sum(roles[(d, b, r)] for r in all_roles)))
你可以使用 model.AddImplication(boolvar, boolvar)
:
for d in all_doctors:
for b in all_service_blocks[:-1]:
for r in all_roles:
for r1 in all_roles:
model.AddImplication(roles[(d, b, r)], roles[(d, b+1, r1)].Not())