{
  "resources": [
    {
      "id": "driver-1",
      "name": "Driver 1",
      "shifts": [
        {
          "id": "shift1",
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T17:00:00Z"
        }
      ]
    }
  ],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}

Resource Management

Resources represent the vehicles, drivers, or teams that execute your routes. This guide covers advanced resource configuration including multi-shift scheduling, workload balancing, period constraints, and geographic restrictions.

Basic Resource Configuration

Every resource requires at minimum a name and shift definition:

{
  "resources": [
    {
      "id": "driver-1",
      "name": "Driver 1",
      "shifts": [
        {
          "id": "shift1",
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T17:00:00Z"
        }
      ]
    }
  ],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}

Essential Resource Properties

name
string
required

Unique identifier for the resource

shifts
array
required

Working periods when the resource is available

capacity
array[integer]

Loading capacity in multiple dimensions (e.g., [weight, volume])

tags
array[Tag]

Skills, certifications, or capabilities

regions
array[string]

Geographic areas where resource can operate

Multi-Shift Resources

Resources can work multiple shifts per day or across different days:

{
  "resources": [
    {
      "id": "driver-flexible",
      "name": "Flexible Driver",
      "shifts": [
        {
          "id": "shift1",
          "start": {
            "location": {"lat": 52.520, "lon": 13.405},
            "time": "2024-03-15T06:00:00Z"
          },
          "end": {
            "location": {"lat": 52.520, "lon": 13.405},
            "time": "2024-03-15T10:00:00Z"
          }
        },
        {
          "id": "shift2",
          "start": {
            "location": {"lat": 52.520, "lon": 13.405},
            "time": "2024-03-15T14:00:00Z"
          },
          "end": {
            "location": {"lat": 52.525, "lon": 13.410},
            "time": "2024-03-15T18:00:00Z"
          }
        },
        {
          "id": "shift3",
          "start": {
            "location": {"lat": 52.525, "lon": 13.410},
            "time": "2024-03-16T08:00:00Z"
          },
          "end": {
            "location": {"lat": 52.520, "lon": 13.405},
            "time": "2024-03-16T17:00:00Z"
          }
        }
      ]
    }
  ],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}

Each shift can have different start/end locations. This is useful for drivers who:

  • Start from home in the morning
  • End at a depot
  • Continue from previous day’s end location

Shift Properties

from
datetime
required

Shift start time (ISO 8601 format)

to
datetime
required

Shift end time

start
Location

Starting location for this shift (defaults to first job location)

end
Location

Ending location for this shift (defaults to last job location)

overtimeEnd
datetime

Latest possible end time with overtime penalty

breaks
array[Break]

Scheduled breaks during the shift

Period Constraints

Control resource utilization over time periods (day, week, month):

{
  "resources": [
    {
      "id": "driver-1",
      "name": "Driver 1",
      "periodRules": [
        {
          "type": "MAX_WORK_TIME",
          "period": "DAY",
          "value": 28800  // 8 hours max per day
        },
        {
          "type": "MAX_DRIVE_TIME",
          "period": "WEEK",
          "value": 144000  // 40 hours max per week
        },
        {
          "type": "MIN_SERVICE_TIME",
          "period": "DAY",
          "value": 14400  // Minimum 4 hours productive work
        }
      ],
      "shifts": [
        {
          "id": "shift1",
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T17:00:00Z"
        }
      ]
    }
  ],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}

Available Period Rules

{
  "type": "MAX_WORK_TIME",
  "period": "DAY",
  "value": 32400  // 9 hours
}

Total time from shift start to end, including breaks

Period Types:

  • DAY: Rolling 24-hour period
  • WEEK: Rolling 7-day period
  • MONTH: Rolling 30-day period

Workload Balancing

Distribute work fairly across resources:

Fair Workload Per Resource

Balance total work time across all resources:

{
  "options": {
    "weights": {
      "fairWorkloadPerResource": 50
    }
  }
}

How it works:

  • Calculates average workload across all resources
  • Penalizes deviations from the average
  • Higher weight = stronger preference for balance
// With fairWorkloadPerResource: 100
{
  "resource1": "6 hours work",
  "resource2": "6.5 hours work",
  "resource3": "5.5 hours work"
}

Fair Workload Per Trip

Balance work within individual trips/routes:

{
  "options": {
    "weights": {
      "fairWorkloadPerTrip": 30
    }
  }
}

Use cases:

  • Ensure lunch breaks fall at reasonable times
  • Prevent very short or very long individual routes
  • Balance morning vs afternoon workloads

Geographic Restrictions

Region-Based Assignment

Limit resources to specific geographic areas:

{
  "resources": [
    {
      "id": "north-team",
      "name": "North Team",
      "regions": ["region-north", "region-central"],
      "shifts": [
        {
          "id": "shift1",
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T17:00:00Z"
        }
      ]
    },
    {
      "id": "south-team",
      "name": "South Team", 
      "regions": ["region-south", "region-central"],
      "shifts": [
        {
          "id": "shift1",
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T17:00:00Z"
        }
      ]
    }
  ],
  "jobs": [
    {
      "id": "delivery-1",
      "name": "Delivery 1",
      "location": {"lat": 52.520, "lon": 13.405},
      "region": "region-north"
    }
  ]
}

Jobs with regions can ONLY be assigned to resources that include that region in their regions list.

Distance-Based Restrictions

Limit how far resources travel from their base:

{
  "resources": [
    {
      "id": "local-driver",
      "name": "Local Driver",
      "shifts": [{
        "id": "shift1",
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T17:00:00Z",
        "maxDistance": 50000  // 50km radius from start
      }]
    }
  ],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ]
}

Skill and Tag Management

Match resource capabilities with job requirements:

{
  "resources": [
    {
      "id": "certified-technician",
      "name": "Certified Technician",
      "tags": [
        {"name": "electrical", "hard": true},
        {"name": "plumbing", "hard": true},
        {"name": "senior", "hard": false}
      ],
      "shifts": [
        {
          "id": "shift1",
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T17:00:00Z"
        }
      ]
    }
  ],
  "jobs": [
    {
      "id": "electrical-repair",
      "name": "Electrical Repair",
      "tags": [
        {"name": "electrical", "hard": true}  // Must match
      ]
    }
  ]
}

Tag Matching Rules

1

Hard Tags Must Match

If a job has a hard tag, only resources with that tag can be assigned

2

Soft Tags Preferred

Soft tags create preference but aren’t required

3

Weight Controls Strength

Higher weight values make soft preferences stronger

Preferred Resources

Allow soft preferences for specific resource assignments:

{
  "resources": [
    {
      "id": "senior-tech-1",
      "name": "Senior Technician 1",
      "shifts": [{"id": "shift1", "from": "2024-03-15T08:00:00Z", "to": "2024-03-15T17:00:00Z"}]
    },
    {
      "id": "senior-tech-2",
      "name": "Senior Technician 2",
      "shifts": [{"id": "shift1", "from": "2024-03-15T08:00:00Z", "to": "2024-03-15T17:00:00Z"}]
    }
  ],
  "jobs": [
    {
      "id": "vip-customer-service",
      "name": "VIP Customer Service",
      "preferredResources": ["senior-tech-1", "senior-tech-2"],
      "allowedResources": ["senior-tech-1", "senior-tech-2", "tech-3", "tech-4"]
    }
  ],
  "options": {
    "weights": {
      "preferredResourceWeight": 100
    }
  }
}

Resource Assignment Priority:

  1. allowedResources - Hard constraint (if specified)
  2. preferredResources - Soft preference with penalty
  3. Tag matching - Based on hard/soft tags
  4. General pool - Any available resource

Complex Example: Field Service Team

Here’s a comprehensive example combining multiple resource features:

{
  "resources": [
    {
      "id": "senior-tech-north",
      "name": "Senior Technician North",
      "category": "TECHNICIAN",
      "tags": [
        {"name": "electrical", "hard": true},
        {"name": "plumbing", "hard": true},
        {"name": "senior", "hard": true}
      ],
      "regions": ["north", "central"],
      "capacity": [50],  // Tool weight limit
      "shifts": [
        {
          "id": "morning-shift",
          "start": {
            "location": {"lat": 52.540, "lon": 13.420},
            "time": "2024-03-15T07:00:00Z"
          },
          "end": {
            "location": {"lat": 52.540, "lon": 13.420},
            "time": "2024-03-15T12:00:00Z"
          }
        },
        {
          "id": "afternoon-shift",
          "start": {
            "location": {"lat": 52.540, "lon": 13.420},
            "time": "2024-03-15T13:00:00Z"
          },
          "end": {
            "location": {"lat": 52.540, "lon": 13.420},
            "time": "2024-03-15T17:00:00Z"
          },
          "overtimeEnd": "2024-03-15T19:00:00Z"
        }
      ],
      "periodRules": [
        {
          "type": "MAX_WORK_TIME",
          "period": "DAY",
          "value": 36000  // 10 hours max
        },
        {
          "type": "MAX_DRIVE_TIME",
          "period": "WEEK",
          "value": 108000  // 30 hours driving per week
        }
      ]
    },
    {
      "id": "junior-tech-south",
      "name": "Junior Technician South",
      "category": "TECHNICIAN",
      "tags": [
        {"name": "electrical", "hard": true},
        {"name": "junior", "hard": true}
      ],
      "regions": ["south", "central"],
      "capacity": [30],
      "shifts": [
        {
          "id": "full-day",
          "start": {
            "location": {"lat": 52.540, "lon": 13.420},
            "time": "2024-03-15T08:00:00Z"
          },
          "end": {
            "location": {"lat": 52.540, "lon": 13.420},
            "time": "2024-03-15T17:00:00Z"
          },
          "breaks": [
            {
              "type": "FIXED",
              "from": "2024-03-15T12:00:00Z",
              "to": "2024-03-15T13:00:00Z"
            }
          ]
        }
      ]
    },
    {
      "id": "contractor-flex",
      "name": "Flexible Contractor",
      "category": "CONTRACTOR",
      "tags": [
        {"name": "electrical", "hard": true},
        {"name": "contractor", "hard": true}
      ],
      "regions": ["north", "south", "central"],
      "capacity": [40],
      "shifts": [
        {
          "id": "contractor-shift",
          "from": "2024-03-15T10:00:00Z",
          "to": "2024-03-15T18:00:00Z"
        }
      ],
      "hourlyCost": 75  // Higher cost for contractors
    }
  ],
  "jobs": [
    {
      "id": "job1",
      "name": "Example Job"
    }
  ],
  "options": {
    "weights": {
      "fairWorkloadPerResource": 50,
      "preferredResourceWeight": 100,
      "overtimeWeight": 200
    }
  }
}

Performance Optimization

Resource Pool Size

Performance Impact of Resource Features:

  • More resources = more routing possibilities
  • Complex constraints = longer solve times
  • Many tags/regions = increased matching complexity

Recommendations:

  • Keep active resource pool under 100 for real-time solving
  • Use shift patterns to reduce combinations
  • Limit tag variations to necessary distinctions

Best Practices

1

Start Simple

Begin with basic resource definitions and add constraints incrementally

2

Use Appropriate Constraints

  • Hard constraints for legal/safety requirements
  • Soft constraints for preferences
  • Period rules for compliance
3

Test Resource Utilization

Monitor these metrics:

  • Average utilization per resource
  • Overtime frequency
  • Unassigned jobs due to resource constraints
4

Balance Flexibility and Control

Too many restrictions can make problems infeasible

Troubleshooting

Common Issues