Resource breaks¶
If you’re using this notebook in Google Colab, be sure to install PyJobShop first by executing
pip install pyjobshopin a cell.
This notebook demonstrates how to model resource breaks using PyJobShop. In real-world scheduling, machines and resources often have planned breaks or unavailable periods, for example, lunch breaks, weekends, or planned maintenance.
We’ll cover the following:
A basic example to model resource breaks
How to allow tasks to be interrupted by breaks
A common example where breaks can be used to model operator availability
Basic example¶
Let’s create a simple scheduling problem with breaks.
[1]:
from pyjobshop import Model
model = Model()
All resources in PyJobShop have a breaks argument which can be used to specify breaks. Here, we create one machine with a break between [4-5] that represents a lunch break.
[2]:
machine = model.add_machine(breaks=[(4, 5)])
Let’s consider two tasks that need to be processed, each with processing time of 3 hours:
[3]:
job = model.add_job()
for _ in range(2):
task = model.add_task(job)
processing_time = 3
model.add_mode(task, machine, processing_time)
[4]:
print(model.summary())
1 jobs
1 resources
└─ 1 machines
2 tasks
2 modes
0 constraints
objective
└─ weight_makespan=1
[5]:
result = model.solve(display=False)
print(result)
Solution results
================
objective: 8.00
lower bound: 8.00
status: Optimal
runtime: 0.01 seconds
[6]:
from pyjobshop.plot import plot_machine_gantt
plot_machine_gantt(result.best, model.data())
Allowing tasks to be interrupted by breaks¶
Notice how the tasks are scheduled to avoid breaks. By default, tasks cannot overlap with any breaks. To allow tasks to be interrupted by breaks, set allow_breaks=True. Let’s recreate the same problem with break interruptions enabled.
[7]:
model = Model()
machine = model.add_machine(breaks=[(4, 5)])
job = model.add_job()
for _ in range(2):
task = model.add_task(job, allow_breaks=True)
processing_time = 3
model.add_mode(task, machine, processing_time)
[8]:
result = model.solve(display=False)
print(result)
Solution results
================
objective: 7.00
lower bound: 7.00
status: Optimal
runtime: 0.00 seconds
[9]:
plot_machine_gantt(result.best, model.data())
Great, this indeed works as expected: the second task is started before the break, and continues after the break. As a result, the task takes 1 time unit longer (the break duration), but the total processing time is still the same. This information is also contained in the solution:
[10]:
result.best.tasks
[10]:
[TaskData(mode=0, resources=[0], start=0, end=3, idle=0, breaks=0, present=True),
TaskData(mode=1, resources=[0], start=3, end=7, idle=0, breaks=1, present=True)]
Operator availability¶
In many job shops, machines require operator supervision during setup but can process independently after setup. This example shows how to model such scenarios using synchronized tasks with operator breaks.
[11]:
model = Model()
We create two resources: a machine that can run continuously, and an operator with breaks representing non-working hours (0-8 and 17-24).
[12]:
machine = model.add_machine(name="machine")
operator = model.add_machine(breaks=[(0, 8), (17, 24)], name="operator")
Now we create two tasks: a long processing task (15 hours) for the machine, and a short setup task (1 hour) that requires operator supervision.
[13]:
job = model.add_job()
processing_task = model.add_task(job, name="processing")
model.add_mode(processing_task, machine, duration=15)
setup_task = model.add_task(job, name="setup")
model.add_mode(setup_task, operator, duration=1);
The key constraint is synchronization: both tasks must start simultaneously. This ensures processing can only begin when an operator is available for setup, but the machine can continue running after the operator finishes.
[14]:
# Both tasks must start simultaneously
model.add_start_before_start(processing_task, setup_task)
model.add_start_before_start(setup_task, processing_task);
Let’s solve and visualize the schedule:
[15]:
result = model.solve(display=False)
plot_machine_gantt(result.best, model.data(), plot_labels=True)
Perfect! The Gantt chart shows both tasks starting at time 8 when the operator becomes available. The setup task finishes quickly while the machine continues processing until time 23. This pattern is common in manufacturing where operators are needed for setup but machines can run autonomously during production.
Conclusion¶
This notebook showed how to model resource breaks in PyJobShop:
Use the
breaksparameter to define unavailable periods for resourcesSet
allow_breaks=Trueto let tasks be interrupted by breaks
These features help model real-world scheduling constraints like lunch breaks, shift patterns, and operator availability.