{
  "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"
        }
      ]
    }
  ]
}

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
        }
      ]
    }
  ]
}
hard
boolean
default:"true"
When false, the time window becomes a soft constraint that can be violated with a penalty
weight
integer
default:"1"
Penalty weight for violating the soft time window. Higher values make violations less likely.

Combining Hard and Soft Windows

{
  "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

{
  "options": {
    "snapUnit": 900  // 15-minute appointment slots
  }
}
Perfect for service businesses that book in standard time slots.

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
    }
  ]
}
1

First Job at Location

Full duration applies: 600 seconds (10 minutes)
2

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

{
  "weights": {
    "waitTimeWeight": 100  // Strong penalty
  }
}
Best for: Delivery services where drivers should stay productive

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
    }
  }
}

Performance Tips

Time Feature Performance Impact:
  1. Multiple Windows: Each additional window increases complexity
  2. Soft Constraints: More flexible but requires more computation
  3. Small snapUnit: More precision = more possible solutions
  4. Resumable Jobs: Adds complexity to break scheduling
For best performance, use only the time features you actually need.