Overview
The priority field on jobs allows you to influence which jobs are more likely to be included in the final schedule when not all jobs can be served. This is particularly useful in overconstrained scenarios where you have more work than available resources.
Priority affects whether a job gets scheduled, not when it gets scheduled. Use time windows to control scheduling order.
How Priority Works
When the VRP solver evaluates solutions, unassigned jobs generate penalty scores. The penalty for each unserved job is calculated as:
penalty = priority × duration × priorityWeight
Higher penalties make the solver work harder to include those jobs in the schedule, effectively prioritizing them over jobs with lower penalties.
Key Concepts
Default Priority
If not specified, jobs default to priority 1.
Priority Multiplication
The priority value is multiplied by the job’s duration, meaning longer high-priority jobs have an even stronger influence on scheduling decisions.
Weight Configuration
The global priorityWeight parameter in the request weights controls how strongly priority influences the solution.
Basic Example
{
"jobs" : [
{
"name" : "critical-delivery" ,
"duration" : 600 ,
"priority" : 100 ,
"location" : {
"latitude" : 51.0543 ,
"longitude" : 3.7174
}
},
{
"name" : "standard-delivery" ,
"duration" : 600 ,
"priority" : 1 ,
"location" : {
"latitude" : 51.0456 ,
"longitude" : 3.7326
}
},
{
"name" : "low-priority" ,
"duration" : 600 ,
"priority" : 0 ,
"location" : {
"latitude" : 51.0389 ,
"longitude" : 3.7203
}
}
],
"resources" : [
{
"name" : "vehicle-1" ,
"shifts" : [
{
"from" : "2023-01-13T09:00:00.000Z" ,
"to" : "2023-01-13T17:00:00.000Z" ,
"start" : {
"latitude" : 51.0500 ,
"longitude" : 3.7200
}
}
]
}
],
"options" : {
"partialPlanning" : true
},
"weights" : {
"priorityWeight" : 100
}
}
Complete Job Example
Here’s a complete job example showing all available fields:
Complete Job with Priority
{
"jobs" : [
{
"name" : "critical-medical-delivery" ,
"priority" : 100 ,
"urgency" : 80 ,
"duration" : 1800 ,
"location" : {
"latitude" : 51.0543 ,
"longitude" : 3.7174
},
"tags" : [
{
"name" : "medical" ,
"hard" : true
},
{
"name" : "fragile" ,
"hard" : false ,
"weight" : 100
}
],
"windows" : [
{
"from" : "2023-01-13T09:00:00.000Z" ,
"to" : "2023-01-13T12:00:00.000Z"
},
{
"from" : "2023-01-13T14:00:00.000Z" ,
"to" : "2023-01-13T17:00:00.000Z"
}
],
"rankings" : [
{
"resource" : "driver-001" ,
"value" : 1
}
],
"disallowedResources" : [ "driver-trainee" ],
"hard" : true ,
"hardWeight" : 1000 ,
"padding" : 300 ,
"load" : [ 10 , 5 ],
"resumable" : false
}
]
}
The name field is the only required field for a job. All other fields, including priority, are optional.
Advanced Usage
Combining with Partial Planning
Priority works seamlessly with partial planning to handle overconstrained problems:
{
"jobs" : [
{
"name" : "emergency-repair" ,
"duration" : 7200 ,
"priority" : 100 ,
"location" : {
"latitude" : 51.05 ,
"longitude" : 3.72
}
},
{
"name" : "scheduled-maintenance-1" ,
"duration" : 3600 ,
"priority" : 20 ,
"location" : {
"latitude" : 51.06 ,
"longitude" : 3.73
}
},
{
"name" : "scheduled-maintenance-2" ,
"duration" : 3600 ,
"priority" : 20 ,
"location" : {
"latitude" : 51.04 ,
"longitude" : 3.71
}
},
{
"name" : "routine-check" ,
"duration" : 1800 ,
"priority" : 1 ,
"location" : {
"latitude" : 51.03 ,
"longitude" : 3.74
}
}
],
"resources" : [
{
"name" : "technician-1" ,
"shifts" : [
{
"from" : "2023-01-13T08:00:00.000Z" ,
"to" : "2023-01-13T16:00:00.000Z" ,
"start" : {
"latitude" : 51.05 ,
"longitude" : 3.72
},
"end" : {
"latitude" : 51.05 ,
"longitude" : 3.72
}
}
]
}
],
"options" : {
"partialPlanning" : true ,
"explain" : true
}
}
Priority Strategies
Critical Services
Customer Tiers
Revenue-Based
{
"jobs" : [
{
"name" : "emergency-1" ,
"priority" : 1000 ,
"duration" : 1800 ,
"location" : {
"latitude" : 51.05 ,
"longitude" : 3.72
}
},
{
"name" : "urgent-1" ,
"priority" : 100 ,
"duration" : 2400 ,
"location" : {
"latitude" : 51.06 ,
"longitude" : 3.73
}
},
{
"name" : "routine-1" ,
"priority" : 1 ,
"duration" : 3600 ,
"location" : {
"latitude" : 51.04 ,
"longitude" : 3.71
}
}
]
}
{
"jobs" : [
{
"name" : "vip-delivery" ,
"priority" : 50 ,
"duration" : 1800 ,
"location" : {
"latitude" : 51.05 ,
"longitude" : 3.72
},
"tags" : [
{
"name" : "vip"
}
]
},
{
"name" : "gold-delivery" ,
"priority" : 20 ,
"duration" : 1800 ,
"location" : {
"latitude" : 51.06 ,
"longitude" : 3.73
}
},
{
"name" : "standard-delivery" ,
"priority" : 1 ,
"duration" : 1800 ,
"location" : {
"latitude" : 51.04 ,
"longitude" : 3.71
}
}
]
}
{
"jobs" : [
{
"name" : "large-order" ,
"priority" : 75 ,
"duration" : 14400 ,
"location" : {
"latitude" : 51.05 ,
"longitude" : 3.72
}
},
{
"name" : "medium-order" ,
"priority" : 25 ,
"duration" : 7200 ,
"location" : {
"latitude" : 51.06 ,
"longitude" : 3.73
}
},
{
"name" : "small-order" ,
"priority" : 5 ,
"duration" : 3600 ,
"location" : {
"latitude" : 51.04 ,
"longitude" : 3.71
}
}
]
}
Configuration Guidelines
Priority Weight Tuning
The priorityWeight parameter controls how strongly priority influences the solution:
Priority has minimal impact. The solver focuses more on efficiency metrics like travel time and workload balance.
Priority significantly influences job selection while still considering other optimization goals.
Priority becomes dominant. High-priority jobs will almost always be scheduled before lower-priority ones.
Best Practices
Setting all jobs to the same high priority defeats the purpose. Use priority to create meaningful differentiation between job importance levels.
For jobs that must be completed, consider using hard constraints (like time windows) instead of relying solely on priority.
Understanding the Results
When using the explain option, you can see how priority affected unassigned jobs:
Response with Explanations
{
"solution" : {
"routes" : [
{
"resourceId" : "technician-1" ,
"shiftId" : "shift1" ,
"activities" : [
{
"type" : "start" ,
"location" : { "lat" : 51.05 , "lon" : 3.72 },
"time" : {
"arrival" : "2023-01-13T08:00:00Z" ,
"departure" : "2023-01-13T08:00:00Z"
}
},
{
"type" : "job" ,
"jobId" : "emergency-repair" ,
"location" : { "lat" : 51.05 , "lon" : 3.72 },
"time" : {
"arrival" : "2023-01-13T08:00:00Z" ,
"departure" : "2023-01-13T10:00:00Z"
}
},
{
"type" : "job" ,
"jobId" : "scheduled-maintenance-1" ,
"location" : { "lat" : 51.06 , "lon" : 3.73 },
"time" : {
"arrival" : "2023-01-13T10:30:00Z" ,
"departure" : "2023-01-13T11:30:00Z"
}
},
{
"type" : "end" ,
"location" : { "lat" : 51.05 , "lon" : 3.72 },
"time" : {
"arrival" : "2023-01-13T12:00:00Z"
}
}
]
}
],
"unassigned" : [
{
"jobId" : "routine-check" ,
"reasons" : [
{
"code" : "UNSERVED_JOBS" ,
"description" : "Job priority: 1, Duration: 1800s, Score: -180000"
}
]
}
]
}
}
Common Use Cases
1. Service Level Agreements
Ensure SLA-critical jobs are prioritized:
{
"resources" : [
{
"id" : "tech-1" ,
"name" : "Technician 1" ,
"shifts" : [{ "id" : "shift1" , "from" : "2023-01-13T08:00:00Z" , "to" : "2023-01-13T18:00:00Z" }]
}
],
"jobs" : [
{
"id" : "sla-critical-job" ,
"name" : "SLA Critical Job" ,
"priority" : 100 ,
"serviceDurationInSeconds" : 3600 ,
"location" : { "lat" : 51.05 , "lon" : 3.72 }
},
{
"id" : "standard-job" ,
"name" : "Standard Job" ,
"priority" : 10 ,
"serviceDurationInSeconds" : 3600 ,
"location" : { "lat" : 51.06 , "lon" : 3.73 }
},
{
"id" : "best-effort-job" ,
"name" : "Best Effort Job" ,
"priority" : 1 ,
"serviceDurationInSeconds" : 3600 ,
"location" : { "lat" : 51.04 , "lon" : 3.71 }
}
]
}
2. Emergency Services
Handle emergency requests alongside scheduled work:
{
"resources" : [
{
"id" : "tech-1" ,
"name" : "Emergency Technician" ,
"shifts" : [{ "id" : "shift1" , "from" : "2023-01-13T08:00:00Z" , "to" : "2023-01-13T18:00:00Z" }]
}
],
"jobs" : [
{
"id" : "emergency-response" ,
"name" : "Emergency Response" ,
"priority" : 1000 ,
"serviceDurationInSeconds" : 1800 ,
"urgency" : 100 ,
"location" : { "lat" : 51.05 , "lon" : 3.72 }
},
{
"id" : "urgent-repair" ,
"name" : "Urgent Repair" ,
"priority" : 50 ,
"serviceDurationInSeconds" : 3600 ,
"urgency" : 50 ,
"location" : { "lat" : 51.06 , "lon" : 3.73 }
},
{
"id" : "scheduled-maintenance" ,
"name" : "Scheduled Maintenance" ,
"priority" : 1 ,
"serviceDurationInSeconds" : 3600 ,
"location" : { "lat" : 51.04 , "lon" : 3.71 }
}
]
}
3. Maximize Revenue
Prioritize high-value opportunities:
{
"resources" : [
{
"id" : "installer-1" ,
"name" : "Installer 1" ,
"shifts" : [{ "id" : "shift1" , "from" : "2023-01-13T08:00:00Z" , "to" : "2023-01-13T18:00:00Z" }]
}
],
"jobs" : [
{
"id" : "high-value-installation" ,
"name" : "High Value Installation" ,
"priority" : 80 ,
"serviceDurationInSeconds" : 7200 ,
"location" : { "lat" : 51.05 , "lon" : 3.72 },
"tags" : [{ "name" : "revenue-8000" , "hard" : false }]
},
{
"id" : "medium-value-service" ,
"name" : "Medium Value Service" ,
"priority" : 35 ,
"serviceDurationInSeconds" : 3600 ,
"location" : { "lat" : 51.06 , "lon" : 3.73 },
"tags" : [{ "name" : "revenue-3500" , "hard" : false }]
},
{
"id" : "standard-service" ,
"name" : "Standard Service" ,
"priority" : 10 ,
"serviceDurationInSeconds" : 1800 ,
"location" : { "lat" : 51.04 , "lon" : 3.71 },
"tags" : [{ "name" : "revenue-1000" , "hard" : false }]
}
]
}
Partial Planning Allow solver to leave some jobs unassigned in overconstrained scenarios
Time Windows Control when jobs can be scheduled
Job Urgency Prioritize jobs to be scheduled earlier in the day
Constraints Understand all available constraints