假设一个预定义的枢纽列表,每个枢纽都有一个特定的驱动程序需求,一组驱动程序以及驱动程序和枢纽之间的关系。在我的例子中,驱动程序的数量远远高于集线器的数量,即。400 vs 45个枢纽,每天的需求量约为250名司机。我设置了一个约束,即每个司机也必须有一天休息。然而,我没有得到问题的解决方案,为了进一步促进解决方案,我甚至设置每个驱动程序可以在任何集线器(driver_hubs_relationships)工作,但仍然没有得到解决方案。有什么想法吗
def create_schedule(drivers,
hubs,
hubs_and_demand,
driver_hubs_relationships):
drivers_list = copy.deepcopy(drivers)
hubs_list = copy.deepcopy(hubs)
hubs_list_and_demand = copy.deepcopy(hubs_and_demand)
driver_hubs_list_relationships = copy.deepcopy(driver_hubs_relationships)
model = cp_model.CpModel()
# Define an extra "hub" that represents a day off
hubs_list.append('OFF')
for e in drivers_list:
driver_hubs_list_relationships[e].append('OFF')
# Create variables total size len(drivers)*(1+len(hubs))*len(days)
schedule = {}
for e in drivers_list:
for d in days:
for r in hubs_list:
schedule[(e, d, r)] = model.NewBoolVar(f'schedule_{e}_{d}_{r}')
# Define a variable for each day representing the number of drivers having that day off
off_days = {d: model.NewIntVar(0, len(drivers_list), f'off_{d}') for d in days}
# Add constraints to link the off_days variable with the schedule variable
for d in days:
model.Add(off_days[d] == sum(schedule[(e, d, 'OFF')] for e in drivers_list))
# Add a constraint to distribute the off days evenly across the week
average_off_days = len(drivers_list) // len(days)
for d in days:
model.Add(off_days[d] >= average_off_days)
# Each driver must have one day off per week
for e in drivers_list:
model.Add(sum(schedule[(e, d, 'OFF')] for d in days) == 1)
# Each driver works at most one day at a specific hub
for e in drivers_list:
for d in days:
model.Add(sum(schedule[(e, d, r)] for r in hubs_list) == 1)
# Create variables for the number of drivers needed at each hub on each day
drivers_needed = {}
for d in days:
for r in hubs_list:
if r != 'OFF':
hub_demand = hubs_list_and_demand.loc[hubs_list_and_demand['hub'] == r, 'drivers_needed']
if len(hub_demand) > 0:
drivers_needed_at_hub = int(hub_demand.values[0])
else:
drivers_needed_at_hub = 0 # or some other default value
drivers_needed[(d, r)] = model.NewIntVar(drivers_needed_at_hub,
int(hubs_list_and_demand.max().values[1]),
f'drivers_needed_{d}_{r}')
# Each hub needs to have the required number of drivers each day
for d in days:
for r in hubs_list:
if r != 'OFF':
model.Add(10 * sum(schedule[(e, d, r)] for e in drivers_list) >=
9 * drivers_needed[(d, r)])
# Assign each driver to their specific hub
for e in drivers_list:
for r in hubs_list:
if r not in driver_hubs_list_relationships[e]:
for d in days:
model.Add(schedule[(e, d, r)] == 0)
# Solve and print schedule
solver = cp_model.CpSolver()
solver.parameters.max_time_in_seconds = 500.0
solver.parameters.log_search_progress = True
status = solver.Solve(model)
print(f"status code {status}")
if status == cp_model.OPTIMAL:
solution = {}
for e in drivers_list:
solution[e] = {}
for d in days:
for r in hubs_list:
if solver.Value(schedule[(e, d, r)]) == 1:
print(f"{e} works at {r} on {d}")
solution[e][d] = r
return solution
else:
return None
1条答案
按热度按时间k97glaaz1#
我认为你对你的休息日有矛盾/问题:
如果你有很多多余的司机,他们可能会有多天的休息,但你只允许他们1天休息。尝试将第二个约束设置为GTE
>=
。此外,从您提供的内容中,还不清楚为什么要按day索引days_off约束?如果你的模型是以满足需求为结构的,那么就不需要强制每天的休息天数是固定的。如果每天的“休息日司机”都是平等的,那就太奇怪了,这基本上就是你所强迫的。
添加:
另外,不清楚为什么要为
drivers_needed
创建一个变量。这是一个已知的(或至少是一个可计算的)数据值。这不是未知的,是吗?我没有遵循这组语句中的所有逻辑,但似乎你应该能够用一点数学计算出按天/按“枢纽”的需求,并将其作为模型的参数,而不是变量。