Break planning

In this notebook we will explore hours-of-service break planning, under EU and US regulations. PyVRP Enterprise comes preconfigured for these settings, which makes modelling and regulatory compliance easy to achieve.

[1]:
import pyvrp
import pyvrp.constants
import pyvrp.plotting
import pyvrp.stop

We will use a simple dataset containing 48 Belgian clients. The instance has one depot and ten vehicles.

[2]:
data = pyvrp.read("data/belgium-n49-k10-ghent.vrp")
pyvrp.plotting.plot_coordinates(data)
../_images/notebooks_break_planning_3_0.png

EU regulations

EU regulations on drive and rest periods are governed by directives EC 561/2006 (drive time regulations) and Directive 2002/15/EC (work time regulations). In practice, these directives require a break of at least 45 minutes after 4.5 hours of drive time, and a break of at least 30 minutes after six hours, or 45 minutes after nine hours, of work time. There are additionally optional rules about splitting these breaks.

Note

PyVRP Enterprise already supports the drive time breaks, that is, 45 minutes of break time after 4.5 hours of drive time. The work time breaks are being implemented, with support for those coming in early Q3 2026.

PyVRP Enterprise comes with a break configuration for EU break regulations. This configuration is available via pyvrp.constants.EU_BREAKS, and can be passed to the vehicle type to enable EU-style break planning.

Let’s have a look at how this works in practice, by modifying the Belgium instance to require EU-style breaks.

[3]:
new_vehicle_types = [
    vt.replace(breaks=pyvrp.constants.EU_BREAKS, unit_duration_cost=1)
    for vt in data.vehicle_types()
]

result = pyvrp.solve(
    data.replace(vehicle_types=new_vehicle_types),
    pyvrp.stop.MaxIterations(15_000),
    display=True,
)

pyvrp.plotting.plot_timeline(result.best)
PyVRP v0.18.0a0

Solving an instance with:
    1 depot
    48 clients
    0 shipments
    10 vehicles (1 vehicle type)

    Iters    Time |      Current OK    Candidate OK         Best OK
H    2307      5s |       291286  Y       325998  Y       266650  Y
     4719     10s |       273860  Y       305908  Y       266650  Y
H    7195     15s |       266982  Y       274854  Y       265930  Y
H    9621     20s |       264558  Y       276596  Y       264542  Y
H   12176     25s |       264320  Y       347610  Y       264320  Y
    14808     30s |       264320  Y       294426  Y       264320  Y

Search terminated in 30.38s after 15000 iterations.
Best-found solution has cost 264320.

Solution results
================
    # routes: 5
     # trips: 5
   # clients: 48
 # shipments: 0
   objective: 264320
    distance: 118210
    duration: 146110
# iterations: 15000
    run-time: 30.38 seconds
../_images/notebooks_break_planning_6_1.png

US regulations

US regulations on hours-of-service of drivers are governed by the FMCSA’s Code of Federal Regulations, particularly 49 CFR Part 395. These regulations require a break of at least 30 minutes after 8 hours of drive time.

Like with EU regulations, PyVRP Enterprise also comes with a break configuration for US break regulations. This configuration is available via pyvrp.constants.US_BREAKS, and can be passed to the vehicle type to enable US-style break planning.

Let’s have a look at how this works in practice, by modifying the Belgium instance to require US-style breaks.

[4]:
new_vehicle_types = [
    vt.replace(breaks=pyvrp.constants.US_BREAKS, unit_duration_cost=1)
    for vt in data.vehicle_types()
]

result = pyvrp.solve(
    data.replace(vehicle_types=new_vehicle_types),
    pyvrp.stop.MaxIterations(15_000),
    display=True,
)

pyvrp.plotting.plot_timeline(result.best)
PyVRP v0.18.0a0

Solving an instance with:
    1 depot
    48 clients
    0 shipments
    10 vehicles (1 vehicle type)

    Iters    Time |      Current OK    Candidate OK         Best OK
H    1623      5s |       249034  Y       267178  Y       240006  Y
H    3391     10s |       237616  Y       237616  Y       237616  Y
     5203     15s |       237616  Y       265594  Y       237616  Y
     7049     20s |       237616  Y       240068  Y       237616  Y
     8903     25s |       237616  Y       262794  Y       237616  Y
    10739     30s |       237616  Y       237616  Y       237616  Y
    12583     35s |       237616  Y       253100  Y       237616  Y
    14433     40s |       237616  Y       266418  Y       237616  Y

Search terminated in 41.49s after 15000 iterations.
Best-found solution has cost 237616.

Solution results
================
    # routes: 4
     # trips: 4
   # clients: 48
 # shipments: 0
   objective: 237616
    distance: 109808
    duration: 127808
# iterations: 15000
    run-time: 41.49 seconds
../_images/notebooks_break_planning_9_1.png

Conclusion

In this tutorial you learned about modelling hours-of-service breaks with PyVRP Enterprise, in EU and US regulatory environments.