Google OR-Tools предоставляет пример примера кода , демонстрирующий, как решить проблему с расписанием медсестер. Я пытаюсь адаптировать его для решения сценария планирования интервью, при котором один кандидат будет присутствовать на двух встречах. Каждое собрание имеет следующее требование:
- На каждом собрании должно быть 2 участника
Требование к решению (1) довольно простое:
meetings = ["phone_screen", "in_person"]
users = ["alice", "bob", "carl", "donna"]
days = ["Mon", "Tue", "Wed"]
times = ["morning", "afternoon"]
model = cp_model.CpModel()
# Build a boolean variable for every possible meeting time attendee
data = {}
for meeting in meetings:
for day in days:
for time in times:
for user in users:
id = 'meeting={},day={},time={},user={}'.format(meeting, day, time, user)
data[(meeting, day, time, user)] = model.NewBoolVar(id)
## Requirement 1: Ensure 2 attendees for each time slot
for meeting in meetings:
for day in days:
for time in times:
per_time_data = []
for user in users:
per_time_data.append(data[(meeting, day, time, user)])
model.Add(sum(per_time_data) == 2)
# Solve and print solutions
solver = cp_model.CpSolver()
solver.Solve(model)
for day in days:
for time in times:
for meeting in meetings:
string = '{} {}\t| {}\t| '.format(day, time, meeting)
for user in users:
if solver.Value(data[(meeting, day, time, user)]) == 1:
string += user + '\t'
print(string)
Это работает как положено, распечатывая единственное решение, в котором в каждом слоте собраний (в основном) случайный выбор из 2 участников:
Mon morning | phone_screen | bob carl
Mon morning | in_person | alice bob
Mon afternoon | phone_screen | alice bob
Mon afternoon | in_person | alice bob
Tue morning | phone_screen | alice bob
Tue morning | in_person | alice bob
Tue afternoon | phone_screen | alice bob
Tue afternoon | in_person | alice bob
Wed morning | phone_screen | alice bob
Wed morning | in_person | alice bob
Wed afternoon | phone_screen | alice bob
Wed afternoon | in_person | alice bob
Но это не совсем то, что я хочу. Кандидат на собеседование должен присутствовать только на двух общих собраниях (одно phone_screen
и одно in_person
), тогда как вышеупомянутое «решение» показывает 12. Я хочу закончить примерно так:
Mon morning | phone_screen | bob carl
Mon afternoon | in_person | alice bob
Поэтому Требование (2):
Каждый тип собрания должен происходить только один раз
Требование решения (2) по какой-то причине сложнее, даже если кажется, что я должен следовать очень похожей стратегии.
## Requirement 2: Ensure only 1 of each type of meeting exists
for meeting in meetings:
per_meeting_data = []
for user in users:
for day in days:
for time in times:
per_meeting_data.append(data[(meeting, day, time, user)])
# Ensure the number of attendees for this meeting type on all days is 2
model.Add(sum(per_meeting_data) == 2)
Добавление приведенного выше кода приводит к сбою в качестве решения INFEASIBLE
. Куда я иду не так?