Created
March 10, 2023 22:47
-
-
Save rblaze/26eab8cc9ce272247a3b3c2bbfae13de to your computer and use it in GitHub Desktop.
Schedule builder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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