Advanced Time & Scheduling Features
Beyond basic time windows, the VRP solver offers sophisticated time management capabilities for complex scheduling scenarios. This guide covers advanced features including multiple time windows, soft constraints, wait time optimization, and more.
Multiple Time Windows
Jobs can have multiple valid time slots, giving the solver flexibility to choose the most efficient option:
{
"jobs" : [
{
"name" : "flexible-delivery" ,
"location" : { "latitude" : 52.520 , "longitude" : 13.405 },
"duration" : 900 ,
"windows" : [
{
"from" : "2024-03-15T09:00:00Z" ,
"to" : "2024-03-15T12:00:00Z"
},
{
"from" : "2024-03-15T14:00:00Z" ,
"to" : "2024-03-15T17:00:00Z"
}
]
}
]
}
Multiple time windows are ideal for customers who offer morning OR afternoon availability. The solver automatically selects the window that optimizes the overall route.
Soft Time Windows
Allow time window violations with penalties instead of hard constraints:
{
"jobs" : [
{
"name" : "preferred-morning-delivery" ,
"location" : { "latitude" : 52.520 , "longitude" : 13.405 },
"duration" : 600 ,
"windows" : [
{
"from" : "2024-03-15T09:00:00Z" ,
"to" : "2024-03-15T12:00:00Z" ,
"hard" : false ,
"weight" : 100
}
]
}
]
}
When false, the time window becomes a soft constraint that can be violated with a penalty
Penalty weight for violating the soft time window. Higher values make violations less likely.
Combining Hard and Soft Windows
Customer Preference
Business Hours
{
"windows" : [
{
"from" : "2024-03-15T09:00:00Z" ,
"to" : "2024-03-15T11:00:00Z" ,
"hard" : false ,
"weight" : 50 // Preferred window
},
{
"from" : "2024-03-15T08:00:00Z" ,
"to" : "2024-03-15T18:00:00Z" ,
"hard" : true ,
"weight" : 1 // Absolute constraint
}
]
}
Time Snapping (snapUnit)
Round arrival times to specific intervals for cleaner schedules:
{
"options" : {
"snapUnit" : 300 // 5 minutes in seconds
}
}
How snapUnit works:
Arrival times are rounded UP to the nearest snapUnit
Example: With snapUnit: 300 (5 minutes)
Arrival at 9:02 → Snapped to 9:05
Arrival at 9:05 → Stays at 9:05
Arrival at 9:07 → Snapped to 9:10
Use Cases for snapUnit
Appointment Scheduling
Dock Scheduling
Public Transport
{
"options" : {
"snapUnit" : 900 // 15-minute appointment slots
}
}
Perfect for service businesses that book in standard time slots. {
"options" : {
"snapUnit" : 1800 // 30-minute dock slots
}
}
Warehouse receiving with fixed unloading windows. {
"options" : {
"snapUnit" : 60 // 1-minute precision
}
}
Precise timing for connections and transfers.
Job Padding
Add buffer time before and after jobs:
{
"jobs" : [
{
"name" : "complex-installation" ,
"location" : { "latitude" : 52.520 , "longitude" : 13.405 },
"duration" : 3600 ,
"padding" : 300 , // 5 minutes before and after
"windows" : [{
"from" : "2024-03-15T09:00:00Z" ,
"to" : "2024-03-15T17:00:00Z"
}]
}
]
}
Padding is applied AFTER snap unit calculations. If arrival is snapped to 9:00 and padding is 300 seconds, the actual arrival becomes 9:05.
Duration Squash
Reduce service time for consecutive jobs at the same location:
{
"jobs" : [
{
"name" : "apartment-delivery-1" ,
"location" : { "latitude" : 52.520 , "longitude" : 13.405 },
"duration" : 600 ,
"durationSquash" : 120 // Only 2 minutes for subsequent deliveries
},
{
"name" : "apartment-delivery-2" ,
"location" : { "latitude" : 52.520 , "longitude" : 13.405 }, // Same location
"duration" : 600 ,
"durationSquash" : 120
}
]
}
First Job at Location
Full duration applies: 600 seconds (10 minutes)
Subsequent Jobs
If travel time < 1 minute, duration becomes durationSquash: 120 seconds (2 minutes)
Resumable Jobs
Allow breaks to interrupt long service jobs:
{
"jobs" : [
{
"name" : "major-repair" ,
"location" : { "latitude" : 52.520 , "longitude" : 13.405 },
"duration" : 14400 , // 4 hours
"resumable" : true ,
"windows" : [{
"from" : "2024-03-15T08:00:00Z" ,
"to" : "2024-03-15T17:00:00Z"
}]
}
],
"resources" : [{
"name" : "technician-1" ,
"shifts" : [{
"from" : "2024-03-15T08:00:00Z" ,
"to" : "2024-03-15T17:00:00Z" ,
"breaks" : [{
"type" : "WINDOWED" ,
"duration" : 3600 , // 1-hour lunch
"from" : "2024-03-15T12:00:00Z" ,
"to" : "2024-03-15T13:00:00Z"
}]
}]
}]
}
With resumable: true, the 4-hour job can be split:
8:00-12:00: Work 4 hours
12:00-13:00: Lunch break
13:00-13:00: Resume and complete
Wait Time Optimization
Control how the solver handles waiting time at locations:
{
"options" : {
"weights" : {
"waitTimeWeight" : 10 // Penalize waiting
}
}
}
Wait Time Scenarios
Minimize Waiting
Allow Strategic Waiting
Balanced Approach
{
"weights" : {
"waitTimeWeight" : 100 // Strong penalty
}
}
Best for: Delivery services where drivers should stay productive {
"weights" : {
"waitTimeWeight" : 0 // No penalty
}
}
Best for: Routes where early arrival is acceptable {
"weights" : {
"waitTimeWeight" : 10 // Moderate penalty
}
}
Best for: Mixed scenarios with some flexibility
Overtime Management
Handle shift extensions with soft or hard constraints:
{
"resources" : [{
"name" : "driver-1" ,
"shifts" : [{
"from" : "2024-03-15T08:00:00Z" ,
"to" : "2024-03-15T17:00:00Z" ,
"overtimeEnd" : "2024-03-15T19:00:00Z" // Can work until 7 PM
}]
}],
"options" : {
"weights" : {
"overtimeWeight" : 50 // Penalty per minute of overtime
}
}
}
Overtime Behavior:
Regular shift: 8:00-17:00 (no penalty)
Overtime zone: 17:00-19:00 (penalized but allowed)
After overtimeEnd: Not allowed (hard constraint)
Multi-Day ASAP Scheduling
Optimize job scheduling across multiple days:
{
"jobs" : [
{
"name" : "flexible-task" ,
"duration" : 3600 ,
"windows" : [
{ "from" : "2024-03-15T08:00:00Z" , "to" : "2024-03-15T17:00:00Z" },
{ "from" : "2024-03-16T08:00:00Z" , "to" : "2024-03-16T17:00:00Z" },
{ "from" : "2024-03-17T08:00:00Z" , "to" : "2024-03-17T17:00:00Z" }
]
}
],
"options" : {
"weights" : {
"asapWeight" : 100 // Schedule as early as possible
}
}
}
ASAP scheduling automatically assigns jobs to the earliest feasible day, helping complete work sooner and improving customer satisfaction.
Complex Example: Field Service
Combining multiple time features for realistic field service:
{
"jobs" : [
{
"name" : "urgent-repair" ,
"location" : { "latitude" : 52.520 , "longitude" : 13.405 },
"duration" : 7200 , // 2 hours
"padding" : 300 , // 5-minute prep time
"windows" : [{
"from" : "2024-03-15T08:00:00Z" ,
"to" : "2024-03-15T12:00:00Z" ,
"hard" : true // Morning appointment
}],
"urgency" : 100 // High priority
},
{
"name" : "routine-maintenance" ,
"location" : { "latitude" : 52.523 , "longitude" : 13.401 },
"duration" : 3600 ,
"resumable" : true , // Can be interrupted
"windows" : [
{
"from" : "2024-03-15T08:00:00Z" ,
"to" : "2024-03-15T17:00:00Z" ,
"hard" : false ,
"weight" : 10 // Flexible timing
}
]
},
{
"name" : "installation-apt-1" ,
"location" : { "latitude" : 52.525 , "longitude" : 13.403 },
"duration" : 1800 ,
"durationSquash" : 600 , // Quick if multiple in building
"windows" : [{
"from" : "2024-03-15T14:00:00Z" ,
"to" : "2024-03-15T16:00:00Z"
}]
}
],
"resources" : [{
"name" : "technician-1" ,
"shifts" : [{
"from" : "2024-03-15T08:00:00Z" ,
"to" : "2024-03-15T17:00:00Z" ,
"overtimeEnd" : "2024-03-15T19:00:00Z" ,
"breaks" : [{
"type" : "WINDOWED" ,
"duration" : 2700 , // 45-minute lunch
"from" : "2024-03-15T11:30:00Z" ,
"to" : "2024-03-15T13:30:00Z"
}]
}]
}],
"options" : {
"snapUnit" : 900 , // 15-minute slots
"weights" : {
"waitTimeWeight" : 20 ,
"overtimeWeight" : 100 ,
"urgencyWeight" : 50 ,
"asapWeight" : 10
}
}
}
Time Feature Performance Impact:
Multiple Windows : Each additional window increases complexity
Soft Constraints : More flexible but requires more computation
Small snapUnit : More precision = more possible solutions
Resumable Jobs : Adds complexity to break scheduling
For best performance, use only the time features you actually need.