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,
        duration_cost=pyvrp.PiecewiseLinearFunction(slope=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 Enterprise v0.18.0a0
License expires on 2027-10-08 (UTC).

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

    Iters    Time |      Current OK    Candidate OK         Best OK
H    4397      5s |     267576.0  Y     331890.0  Y     263170.0  Y
H    8972     10s |     261092.0  Y     301170.0  Y     261046.0  Y
    13636     15s |     261092.0  Y     354956.0  Y     261046.0  Y

Search terminated in 16.43s after 15000 iterations.
Best-found solution has cost 261046.0.

Solution results
================
    # routes: 5
     # trips: 5
   # clients: 48
 # shipments: 0
   objective: 261046.0
    distance: 117923
    duration: 143123
# iterations: 15000
    run-time: 16.43 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,
        duration_cost=pyvrp.PiecewiseLinearFunction(slope=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 Enterprise v0.18.0a0
License expires on 2027-10-08 (UTC).

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

    Iters    Time |      Current OK    Candidate OK         Best OK
H    2978      5s |     247030.0  Y     258360.0  Y     239341.0  Y
     6104     10s |     246236.0  Y     246236.0  Y     239341.0  Y
     9170     15s |     246236.0  Y     275840.0  Y     239341.0  Y
H   12347     20s |     237616.0  Y     255608.0  Y     237616.0  Y

Search terminated in 24.02s after 15000 iterations.
Best-found solution has cost 237616.0.

Solution results
================
    # routes: 4
     # trips: 4
   # clients: 48
 # shipments: 0
   objective: 237616.0
    distance: 109808
    duration: 127808
# iterations: 15000
    run-time: 24.02 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.