Skip to content

Instantly share code, notes, and snippets.

@rblaze
Created March 10, 2023 22:47
Show Gist options
  • Save rblaze/26eab8cc9ce272247a3b3c2bbfae13de to your computer and use it in GitHub Desktop.
Save rblaze/26eab8cc9ce272247a3b3c2bbfae13de to your computer and use it in GitHub Desktop.
Schedule builder
from ortools.sat.python import cp_model
from ortools.sat.cp_model_pb2 import CpSolverStatus
num_lectors = 4
num_groups = 3
num_lessons_per_day = 3
num_days = 5
model = cp_model.CpModel()
vars = {}
for lector in range(num_lectors):
for group in range(num_groups):
for day in range(num_days):
for lesson in range(num_lessons_per_day):
vars[(lector, group, day, lesson)] = model.NewBoolVar(
f"l{lector}_g{group}_d{day}_l{lesson}"
)
for day in range(num_days):
for lesson in range(num_lessons_per_day):
for lector in range(num_lectors):
# Лектор не может читать две лекции в одно и то же время
model.AddAtMostOne(
[vars[(lector, group, day, lesson)] for group in range(num_groups)]
)
for group in range(num_groups):
# Одну лекцию может читать только один лектор
model.AddAtMostOne(
[vars[(lector, group, day, lesson)] for lector in range(num_lectors)]
)
# Лектор не может читать больше двух лекций в день
for lector in range(num_lectors):
model.Add(
sum(
[
vars[(lector, group, day, lesson)]
for group in range(num_groups)
for lesson in range(num_lessons_per_day)
]
)
<= 2
)
for group1 in range(num_groups):
for group2 in range(group1):
for lector in range(num_lectors):
# Каждой группе достаётся столько же лектора, сколько другим
model.Add(
sum(
[
vars[(lector, group1, day, lesson)]
for day in range(num_days)
for lesson in range(num_lessons_per_day)
]
)
== sum(
[
vars[(lector, group2, day, lesson)]
for day in range(num_days)
for lesson in range(num_lessons_per_day)
]
)
)
# Заполнить как можно больше уроков
model.Maximize(sum(vars.values()))
solver = cp_model.CpSolver()
status = solver.Solve(model)
print(f"result: {CpSolverStatus.Name(status)}")
if status in [cp_model.OPTIMAL, cp_model.FEASIBLE]:
for group in range(num_groups):
schedule = []
for day in range(num_days):
day_schedule = []
for lesson in range(num_lessons_per_day):
label = "."
for lector in range(num_lectors):
if solver.Value(vars[(lector, group, day, lesson)]):
label = f"{lector}"
break
day_schedule.append(label)
schedule.append(day_schedule)
print(f"group {group}: {schedule}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment