I've a set of student and task which I wish to assign. How can I add an objective function so that I get a balance number of task assigned to each student?
Subsequently, I will also add some constraints to restrict certain student(s) from receiving certain task hence I would like to balance out the task per student as much as I could.
For example the codes below, I have 5 student and 13 tasks, some student would have received 2 task or 3 task which is the most optimal. The objective function I could think of is using the max number task - min number of task but I am unable to form the logic using the or-tool syntax.
Thanks in advance!
students = [0,1,2,3,4]
tasks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
model = cp_model.CpModel()
max_task = math.ceil(len(tasks)/len(students))
x = {}
for student in students:
for task in tasks:
x[(student ,task)] = model.NewBoolVar(f'student_{student}_task_{task}')
# add constraint: each task must be assigned to exactly one student
for task in tasks:
model.Add(sum(x[student ,task] for student in students) == 1)
for student in students:
model.Add(sum(x[(student,task)] for task in tasks) > 0)
model.Add(sum(x[(student,task)] for task in tasks) <= max_task)
# add a objective function here
solver = cp_model.CpSolver()
status = solver.Solve(model)
print(status)
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
for worker, task in x:
if solver.Value(x[(student,task)])==1:
print(f'Student {student} is assigned to Task {task}')
else:
print("No solution found.")
You can have a look at the balance_group example.
It uses this trick to minimize the spread