How can I create an assignment for tasks based on room, day, and time without any overlaps? The tasks also have specific consecutive time requirements.
Sample variable
tasks = ['task1': 4, 'task2: 2, 'task3': 3,'task4': 1, 'task5': 2, 'task6': 2,'task7': 4, 'task8': 4, 'task9: 1','task10': 1, 'task11': 4, 'task12: 2, 'task13': 3,'task14': 1, 'task15': 2] #task with interval
room = ['room1', 'room2']
day = ['Monday', 'Tuesday'] #the sized of the day is the range of the time meaning it is 12
time = ['7:00', '8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']
it is open for other kind of approach. because my code is not working.
from ortools.sat.python import cp_model
def solve_task_scheduling(tasks, rooms, days, time_slots, day_time_range):
model = cp_model.CpModel()
num_tasks = len(tasks)
num_rooms = len(rooms)
num_days = len(days)
num_time_slots = len(time_slots)
start_times = [model.NewIntVar(0, sum(day_time_range) - tasks[task], f'start_{task}') for task in tasks]
end_times = [model.NewIntVar(tasks[task], sum(day_time_range), f'end_{task}') for task in tasks]
room_assignments = [model.NewIntVar(0, num_rooms - 1, f'room_{task}') for task in tasks]
day_assignments = [model.NewIntVar(0, num_days - 1, f'day_{task}') for task in tasks]
time_slot_assignments = [model.NewIntVar(0, num_time_slots - 1, f'time_{task}') for task in tasks]
for i, task in enumerate(tasks):
model.Add(end_times[i] - start_times[i] == tasks[task])
for i in range(num_tasks):
for j in range(i+1, num_tasks):
model.AddBoolOr([
room_assignments[i] != room_assignments[j],
day_assignments[i] != day_assignments[j],
time_slot_assignments[i] + tasks[tasks[i]] <= time_slot_assignments[j],
time_slot_assignments[j] + tasks[tasks[j]] <= time_slot_assignments[i]
])
objective_var = model.NewIntVar(0, sum(day_time_range) * num_tasks, 'objective')
model.AddMaxEquality(objective_var, end_times)
model.Minimize(objective_var)
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status == cp_model.OPTIMAL:
result = {}
for i, task in enumerate(tasks):
room = rooms[room_assignments[i].Value()]
day = days[day_assignments[i].Value()]
start_time_index = time_slot_assignments[i].Value()
end_time_index = start_time_index + tasks[task]
time_slot = time_slots[start_time_index:end_time_index]
result[task] = {'Room': room, 'Day': day, 'Time': time_slot}
return result
else:
return None
this is the inputs
# Sample input
tasks = {
'task1': 4, 'task2': 2, 'task3': 3, 'task4': 1, 'task5': 2,
'task6': 2, 'task7': 4, 'task8': 4, 'task9': 1, 'task10': 1,
'task11': 4, 'task12': 2, 'task13': 3, 'task14': 1, 'task15': 2
}
rooms = ['room1', 'room2']
days = ['Monday', 'Tuesday']
time_slots = ['7:00-8:00', '8:00-9:00', '9:00-10:00', '10:00-11:00', '11:00-12:00',
'12:00-13:00', '13:00-14:00', '14:00-15:00', '15:00-16:00', '16:00-17:00',
'17:00-18:00', '18:00-19:00']
day_time_range = [12, 12] # Monday and Tuesday both have a time range of 12 hours
result = solve_task_scheduling(tasks, rooms, days, time_slots, day_time_range)
to pritn the result
if result:
for task, details in result.items():
print(f"{task} - {details['Room']}, {details['Day']}, {details['Time']}")
the output look like this:
task1 - room1, monday, ['7:00', '8:00', '9:00', '10:00']
task2 - room1, monday, ['11:00', '12:00']
task3 - room1, monday, ['13:00', '14:00', '15:00']
task4 - room1, monday, ['16:00']
task5 - room1, monday, ['16:00', '17:00', '18:00']
task6 - room1, Tuesday, ['7:00', '8:00']
task7 - room1, Tuesday, ['9:00', '10:00','11:00', '12:00']
task8 - room1, Tuesday, ['13:00', '14:00', '15:00', '16:00']
task9 - room1, Tuesday, ['17:00']
task10 - room1, Tuesday, ['18:00']
task11 - room2, monday, ['7:00', '8:00', '9:00', '10:00']
task12 - room2, monday, ['11:00', '12:00']
task13 - room2, monday, ['13:00', '14:00', '15:00']
task14 - room2, monday, ['16:00']
task15 - room2, monday, ['16:00', '17:00', '18:00']
but not exactly look like this