Vehicle shifts¶
FastVRP supports several time and duration constraints to control when vehicles operate and for how long. You can set the earliest and latest time a vehicle can start its shift, as well as the latest time it must end. Additionally, you can define a standard shift duration and allow overtime beyond that limit. Let's look at a few examples.
A regular shift¶
Consider a vehicle starting from a depot in Utrecht that serves two tasks in Rotterdam and Amsterdam, each requiring 1 hour of service. The vehicle's shift can start from 8:00, and must end by 18:00, with a nominal duration of 8 hours.
{
"locations": [
{
"id": "loc-Rotterdam",
"latitude": 51.9255,
"longitude": 4.4786
},
{
"id": "loc-Amsterdam",
"latitude": 52.3676,
"longitude": 4.9041
},
{
"id": "loc-Utrecht",
"latitude": 52.0907,
"longitude": 5.1214
}
],
"tasks": [
{
"id": "task-Rotterdam",
"location": "loc-Rotterdam",
"service_duration": "PT3600S"
},
{
"id": "task-Amsterdam",
"location": "loc-Amsterdam",
"service_duration": "PT3600S"
}
],
"depots": [
{
"id": "depot-Utrecht",
"location": "loc-Utrecht"
}
],
"vehicle_types": [
{
"id": "vehicle_type",
"start_depot": "depot-Utrecht",
"end_depot": "depot-Utrecht",
"num_available": 1,
"shift": {
"earliest_start": "2025-01-01T08:00:00",
"latest_end": "2025-01-01T18:00:00",
"duration": "PT28800S"
}
}
],
"options": {
"stop": {
"seconds": 1,
"type": "max_runtime"
}
}
}
A single vehicle handles both tasks since the total route duration of nearly 5 hours fits within the 8-hour shift.
The route summary in the solution shows the following:
{
"total_cost": "4.72",
"distance_cost": "0.00",
"duration_cost": "4.72",
"fixed_vehicle_cost": "0.00",
"distance": 182445,
"duration": "PT16991S",
"travel_duration": "PT9791S",
"service_duration": "PT7200S",
"wait_duration": "P0D",
"start_time": "2025-01-01T08:00:00",
"end_time": "2025-01-01T12:43:11",
"num_tasks": 2,
"num_activities": 4,
"slack_duration": "PT19009S",
"load_duration": "P0D",
"overtime": "P0D"
}
The route summary shows when the route starts and ends, as well as a breakdown of costs and durations.
Tip
The slack_duration field indicates how much later the vehicle could depart without violating any constraints or increasing the route duration. This is useful for dispatchers who want flexibility in scheduling departure times.
Shift overtime¶
Sometimes, a vehicle may need to work longer than its regular shift.
FastVRP supports overtime through max_overtime on the shift and per_hour_overtime on the vehicle costs to penalise exceeding the nominal shift duration.
Let's use the same two tasks from the previous example, but with a tighter shift. The nominal duration is now 3 hours, which is not enough to serve both tasks. By allowing up to 2 hours of overtime, the vehicle can still complete the route. Overtime costs an additional 5.00 per hour on top of the regular hourly rate of 1.00.
{
"locations": [
{
"id": "loc-Rotterdam",
"latitude": 51.9255,
"longitude": 4.4786
},
{
"id": "loc-Amsterdam",
"latitude": 52.3676,
"longitude": 4.9041
},
{
"id": "loc-Utrecht",
"latitude": 52.0907,
"longitude": 5.1214
}
],
"tasks": [
{
"id": "task-Rotterdam",
"location": "loc-Rotterdam",
"service_duration": "PT3600S"
},
{
"id": "task-Amsterdam",
"location": "loc-Amsterdam",
"service_duration": "PT3600S"
}
],
"depots": [
{
"id": "depot-Utrecht",
"location": "loc-Utrecht"
}
],
"vehicle_types": [
{
"id": "vehicle_type",
"start_depot": "depot-Utrecht",
"end_depot": "depot-Utrecht",
"num_available": 1,
"shift": {
"earliest_start": "2025-01-01T08:00:00",
"latest_end": "2025-01-01T18:00:00",
"duration": "PT10800S",
"max_overtime": "PT7200S"
},
"costs": {
"per_hour": "1.00",
"per_hour_overtime": "5.00"
}
}
],
"options": {
"stop": {
"seconds": 1,
"type": "max_runtime"
}
}
}
The route takes nearly 5 hours in total, exceeding the 3-hour nominal duration. The vehicle uses overtime to complete the shift:
{
"total_cost": "13.32",
"distance_cost": "0.00",
"duration_cost": "13.32",
"fixed_vehicle_cost": "0.00",
"distance": 182445,
"duration": "PT16991S",
"travel_duration": "PT9791S",
"service_duration": "PT7200S",
"wait_duration": "P0D",
"start_time": "2025-01-01T08:00:00",
"end_time": "2025-01-01T12:43:11",
"num_tasks": 2,
"num_activities": 4,
"slack_duration": "PT19009S",
"load_duration": "P0D",
"overtime": "PT6191S"
}
The overtime of about 1 hour and 43 minutes shows how much the route exceeded the nominal duration.
Each hour of overtime incurs an additional cost of 5.00 on top of the regular hourly rate of 1.00, so the total cost has increased by about 8.60.
Tip
See the Cost optimisation tutorial to learn more about modelling costs with FastVRP.
Conclusion¶
In this tutorial you learned about modelling vehicle shift constraints with FastVRP, including how to control when vehicles operate and how to use overtime to provide flexibility at additional cost. These constraints help you build realistic schedules that reflect your actual working conditions.