Introduction
Welcome to the adiutaByte API. The goal of the API is to provide an interface for generating plans for various fleet optimization problems. This API description is intended to help setting up your own code to access the adiutaByte API. Currently there are two API endpoints implemented. The first one is for submitting a problem description, for which an optimized plan is then calculated. The second endpoint is for retrieving this finalized plan.
The API uses token-based authentication to protect these endpoints, users are generated on demand. Feel free to contact us for such a personalized access.
Currently the API solely supports JSON formatted data with a schema that is used to validate the data. Non-valid requests are immediately rejected with an error message. In each section a downloadable corresponding JSON schema in the latest version is linked.
Tags
- Features that are planned and not yet implemented are marked with TBA (Example: timeEarliest TBA). These are in a conceptual phase and might still get changed or deleted.
- Some features might not yet work, depending on what application version the plan is being calculated on. Features that are not yet live for all requests are marked with the version they are first introduced on (Example: timeEarliest v1.0.0). To determine the used version, check
Deployment Status
.
Examples in this documentation will use all listed fields regardless of their introduced version, so please check availability before using them.
Restrictions
Certain values on input objects can restrict the general set of available solutions. These include time windows on tasks, workers or shifts, preferences of all kinds, categories, qualifications and many more. Due to the nature of optimization, not all of them can be kept nor is that even intended, as violating a constraint can often lead to vast improvements regarding another metric. Nevertheless there are some constraints the algorithm will keep at all costs, as they are deemed too important to be disregarded.
To differentiate the types of constraints, there will be an occasional Depends on column added to the parameter listing. It can contain a number of different text markers:
- "strict": A constraint that the algorithm either literally cannot violate or can do so but only in a worst-case scenario, for instance to keep another strict constraint. (Example:
qualification
) - An optimization parameter: The constraint depends on the optimization parameter setting. The higher the setting value, the more likely it is for the restriction to be kept. However, unless noted otherwise, it cannot reach the importance level of a strict constraint. (Example:
preferredWorkers
) - Nothing: The parameter either is not a constraint or its importance cannot be influenced via input data settings. (Example:
gender
ordesiredWorker
)
Contact us
If you notice issues or an error with the documentation, if you have questions regarding the API or its documentation or if you're having another related issue, please contact us.
Checking your requests for validity
To check your request json for validity you can download validation scripts here:
production | v1.7.0 | Validator Scripts |
develop | v1.7.0 | Validator Scripts |
experimental | v1.7.0 | Validator Scripts |
Post a new plan
HTTP-Endpoint
This endpoint is used to post a new problem description for obtaining an optimized plan based on it.
DEVEL | POST https://develop.compute-adiutabyte.de/description |
PROD | POST https://production.compute-adiutabyte.de/description |
Request
Example
{
"meta": {
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
},
"parameters": {
"preset": 1
},
"tasks": [
{
"date": "2019-12-03",
"duration": 65,
"taskID": 200,
"timeEarliest": "10:00",
"timeLatest": "12:00"
},
{
"date": "2019-12-03",
"duration": 25,
"taskID": 201,
"timeEarliest": "16:00",
"timeLatest": "17:00"
}
],
"workers": [
{
"workerID": 1,
"shiftDate": "2019-12-03",
"shiftEnd": "14:00",
"shiftStart": "06:00"
},
{
"workerID": 1,
"shiftDate": "2019-12-03",
"shiftEnd": "20:00",
"shiftStart": "15:00"
},
{
"workerID": 2,
"shiftDate": "2019-12-03",
"shiftEnd": "14:00",
"shiftStart": "06:00"
}
],
"locationSites": [
{
"locationSiteID": 1,
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
}
}
],
"client": {
"clientID": "{1234-5678-9123}"
},
"history": {
"tasks": [
{
"taskID": 0,
"clientID": 100,
"scheduling": [
{
"date": "2000-01-01"
}
]
}
],
"workers": [
{
"workerID": 0,
"gender": 1,
"qualification": 1,
"categories": [ 1,2 ]
}
]
},
"travelOverride": {
"sparse": [
{
"vehicleTypes": [0,2],
"sourceIDs": [12,13,1,12],
"targetIDs": [14,11,12,1],
"travelTime": [3,4,1,1],
"travelDistance": [2.83,1.5,2.01,3.12]
},
{
"vehicleTypes": [1],
"sourceIDs": [12,13,1,12],
"targetIDs": [14,11,12,1],
"travelTime": [3,4,1,1],
"travelDistance": [2.83,1.5,2.01,3.12]
}
],
"dense": [
{
"travelTime": [0,2,3,4,0,2,12,5,0],
"travelDistance": [0,1.123,2.123,3.456,0,4.5,2.123,10.11,4.9,0],
"vehicleTypes": [0,3]
},
{
"travelTime": [0,2,3,4,0,2,12,5,0],
"travelDistance": [0,1.123,2.123,3.456,0,4.5,2.123,10.11,4.9,0],
"vehicleTypes": [2]
}
]
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
client | client | Contains information about the client which sends this request. | |
meta | ✔ | meta | Meta information about what to consider in the optimization. |
parameters | ✔ | parameters | Parameters for the optimizer. |
tasks | ✔ | Array<Input Task> |
Array of Tasks to be planned by the optimizer. |
workers | ✔ | Array<Input Worker> |
Array of available Workers. |
locationSites | Array<LocationSite> |
Array of available location sites. | |
obstacles | Array<Obstacle> |
DEPRECATED | |
history | History |
History data. | |
travelOverride | Travel Override | Travel override data. |
Result
Example of an ID
AAAAAAAAABBBBBBBBBBBBBBBEEEEEEEEEEEEEEEEEDDDDDDDDDD
Posting a plan returns an ID to monitor the planning process and retrieve the solution.
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The plan was accepted but has been submitted at least once before and is either finished or still in calculation. |
201 | CREATED | The plan was accepted and is going to be processed by the optimization procedures. |
403 | FORBIDDEN | Your account is setup to use different clients. The clientID was not given or the clientID was not registered yet. |
409 | CONFLICT | The limit for the user or client has been exceeded. |
422 | UNPROCESSABLE ENTITY | The plan generated by the backend does not match the JSON-schema. Please check the API documentation carefully or contact us to correct this failure. |
500 | INTERNAL SERVER ERROR | Backend failure, please contact us. |
Client Information
Examples:
{
"clientID": "{1234-5678-9123}"
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Description |
---|---|---|---|
clientID | string | ✔ | Identifies a specific client. |
Restrictions
- Minimum length: 1.
Meta Information
Examples:
{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
}
{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCapacity": true,
"resCategory": true,
"resQualification": true,
"postProcessing": true,
"accuracyMode": 1.0,
"outputLanguage": 1,
"tightSchedule": true,
"minTravelTime": 5,
"integrateGermanBreakRegulations": true,
"enablePlanSplitting": false,
"allowUnassignedTasks": true,
"useInitialClustering": true,
"dontOptimizeResets": true,
"minConcurrentSolutions": 1,
"minTaskDuration": 10,
"useDensityClustering": false
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Description |
---|---|---|---|
dateFrom | string (date) | ✔ | Planning horizon start, usually the earliest date on any of the tasks. |
dateTo | string (date) | ✔ | Planning horizon end, usually the latest date on any of the tasks. |
resCapacity | boolean | Activate/Deactivate whether capacities should be considered in the optimization. (Default: false) | |
resCategory | boolean | Activate/Deactivate whether category types should be considered in the optimization. (Default: false) | |
resQualification | boolean | Activate/Deactivate whether qualifications should be considered in the optimization. (Default: false) | |
postProcessing | boolean | ✔ | Enables dynamic traffic for calculating travel times (e.g. rush hour). Recommended for use cases where such dynamic travel times actually make a difference, otherwise leave it at false or carefully evaluate outcomes. (Default: false) |
accuracyMode | number | Manages a solution refinement process. An accuracy > 0.0 can improve the solution significantly but will take longer to calculate, effects increase with higher accuracyMode. (Default: 1.0) | |
outputLanguage | integer (LanguageType) | Defines which language should be used in the output. (Default: German) | |
tightSchedule | boolean | (Default: false) If set to true, any buffer between tasks (time spent neither working, driving, nor on break) is avoided if possible. Tasks with a timePriority less than 3 can be moved to earlier than their time window if necessary. |
|
tourStartsOnShiftStart v3.6.0 | boolean | (Default: false) Per default, the worker tour starts not at their shiftStart but the first task carried out by the worker. This can have unintended effects for tightSchedule or costsPerMinute (work time cost application). A solution in which the worker's first task is not at their shiftStart is a hint by the optimizer to have the worker start their day later - this can be used for various applications. However, if the use case demands that a worker start at their given shiftStart , this flag can be set to true so that the algorithm always considers shiftStart as tour start, regardless of the first task. |
|
minTravelTime v3.15.0 | integer | A global lower limit to travel time, travel times below this will be raised. (Default: 0) | |
integrateDurationExtensions | boolean | DEPRECATED | |
integrateGermanBreakRegulations | boolean | Adds mandatory breaks to workers according to the German Working Time Act if set. See Known Bugs for an introduction how this is mathematically impossible to actually solve, there are data sets where finding a solution is impossible. In any case, this options places the algorithm under significant amounts of additional load and should only be used if the results are important. Using manual breaks (see Input Worker) is recommended whenever possible. (Default: false) | |
enablePlanSplitting | boolean | (Default: true) Enables splitting the plan into disjunct plan parts. This can reduce runtime or improve pre-optimization data adjustment if the sent data can be split into smaller, self-contained sub-parts. | |
allowUnassignedTasks | boolean | (Default: false) This option enables an unassignment behavior in the algorithm, meaning it will, if deemed necessary, refuse to assign subsets of tasks to any worker. Examples are scenarios where the only qualified workers are overloaded or there are no workers that can even carry out a task. In the output data this can be recognized by the task missing its assignment data, such as timeScheduled or travelTime . The differences to an assigned task are noted in the description for the Output Task. Additionally, the info section will notify of unassignment and, if possible, the reason for it. |
|
useInitialClustering | boolean | Use only clustering as a first optimization step instead of the default algorithms. Developer feature, use at your own risk! (Default: false) | |
dontOptimizeResets | boolean | (Default: false) Per default, travel from and to capacity reset locations is part of the optimization, after a reset the worker will often continue their tour closer to the reset location. Other tours might lead to or from reset locations to minimize travel from the task before reset to the reset location and vice versa from the reset location to the next task. While this behavior is no doubt beneficial for reducing travel time/ distance, it can lead to unwanted results in use cases where a high amount of clustering is intended, since from a pure time/distance point of view, it makes little sense to have a worker return to their cluster after a reset. For these cases the option dontOptimizeResets can be set to true so that travel to and from reset locations does not get considered in the optimization anymore. Of course, the travel will still get factored into scheduled times etc, but the algorithm will no longer consider these travels as part of the optimization. |
|
minConcurrentSolutions v3.2.0 | integer | Number of concurrently calculated solutions. Developer feature, use at your own risk! (Default: 1) | |
minTaskDuration v3.12.0 | integer | Minimum value for an Input Task's duration . Task durations with a lower value are being overwritten before the optimization; breaks, travel or capacity resets are not influenced in any way. Profit calculations (e.g. costsPerMinute ) use adjusted values. (Default: 0) |
|
useDensityClustering v3.19.0 | boolean | (Default: false) This option useses a location based density-clustering in order to restrict the possible solution space. In practice you can save yourself runtime and possibly have minor improvements of your solution quality. Be aware that this will only help if your plan is not greatly restricted by time windows or major dependencies between tasks. |
Notes
- The options
res*
describe which fields from the dataset should be taken into account. More precisely those are:resCapacity
:capacity
(Task),volume
(Task),weight
(Task),capacity
(Worker),capacityInitial
,capacityResetDuration
,capacityResetLocationSiteIDs
, [finalCapacityResetThreshold
],volume
(Worker),volumeInitial
,finalVolumeResetThreshold
,weight
(Worker),weightInitial
,finalWeightResetThreshold
resCategories
:categories
(Task),antiCategories
,exchangeableCategories
,twinCategories
,categories
(Worker),prefCategories
,desiredCategory
resQualification
:qualification
(Task),qualification
(Worker)
Optimization Parameters
Examples:
{}
{
"preset": 1
}
{
"preset": 1,
"fairDistribution": 4,
"localityClustering": 2,
"shortPaths": 7,
"timeliness": 5,
"workerPrefs": 5,
"workerReduction": 1,
"genderPref": 2,
"profitability": 3
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
All parameters (except preset
) are integer numbers $ 0 \leq x \leq 9 $. You only need to pass the ones you want to use, all others will be implicitly set to 0.
Parameter | Type | Required | Description |
---|---|---|---|
preset | integer | Sets the parameters to a predefined preset (details below). Additionally specified parameters will override the preset parameters. | |
fairDistribution | integer | Distribute the tasks fairly among the workers. | |
localityClustering | integer | Build local clusters for the workers to work within if possible. | |
shortPaths | integer | Optimize the plan towards short travel paths. | |
timeliness | integer | Optimize towards satisfying time windows. | |
travelTimeRelax | integer | DEPRECATED | |
workerPrefs | integer | Try to satisfy any tasks' worker preferences. | |
workerReduction | integer | Reduce the number of necessary workers. | |
workTimeRelax | integer | DEPRECATED | |
genderPref | integer | Try to satisfy any tasks' gender preferences. Setting this parameter to 9 will change the algorithm to consider prefGender a restriction rather than merely a preference. |
|
profitability | integer | Optimize towards high profitability. Requires costs set on workers. |
The following presets are currently available (parameters not listed are set to 0):
ID | Name | Parameter settings |
---|---|---|
0 | Eco orientied |
|
1 | Worker oriented |
|
2 | Customer oriented |
|
3 | Fleet oriented |
|
4 | Random | The values shortPaths , timeliness are set to a random value 1 to 9. The values fairDistribution , workerPrefs , workerReduction , genderPref , profitability are set to a random value 0 to 9. |
Input Task
Examples:
{
"taskID": 200,
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00"
}
{
"taskID": 200,
"externalID": "id123",
"clientID": 1,
"baseScheduleTime": "10:00",
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"forbTimeEarliest": "10:00",
"forbTimeLatest": "12:00",
"timePriority": 2,
"location": {
"lat": 50.878847,
"lng": 6.9647284
},
"locationSiteID": 1,
"finishLocation": {
"lat": 50.878847,
"lng": 6.9647284
},
"finishLocationSiteID": 1,
"rotatable": true,
"prefWorkers": [1,2],
"antiWorkers": [3,4],
"forbWorkers": [3,4],
"capacity": 40,
"weight": 40,
"volume": 40,
"qualification": 3,
"categories": [1],
"antiCategories": [2],
"exchangeableCategories": [4,5,6],
"twinCategories": [3],
"preassignedWorker": 2,
"preassignedOrder": -1,
"desiredWorker": 1,
"initassignedWorker": 1,
"initassignedOrder": 1,
"initassignedShiftID": 1,
"prefGender": 1,
"precedingTasks": [1, 2],
"predecessorTasks": [3],
"revenue": 1.25,
"travelTimeExtra": 2,
"group": 2,
"assignmentPriority": 2,
"ignoreHistory": true
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The input task is the incoming task description for the optimizer outlining the restrictions for the optimization.
Parameter | Required | Type | Description | Depends on |
---|---|---|---|---|
taskID | ✔ | integer | The ID of this task. Task IDs need to be unique for all tasks in the input data | |
externalID | string | A string to identify the task in the solution. Cannot be used for reference in the input data or the optimizer, it serves as a helping tool for integrations. | ||
clientID | integer | A unique id to identify a client to whom different tasks can be attributed. Only tasks with clientID are considered in History evaluation. |
||
baseScheduleTime | Time | A time for identifying History-Assignments. Assignments with identical clientID and similar baseScheduleTime are associated with each other. If no baseScheduleTime is set, timeEarliest gest used instead. If no history is used, this field can be ignored. |
||
date | ✔ | string (date) | The date for the day to be planned. | timeliness |
duration | ✔ | integer | The time in minutes it takes to complete this task. | strict |
timeEarliest | ✔ | Time | The earliest possible starting time of this task. | timeliness |
timeLatest | ✔ | Time | The latest time at which this task should be finished. | timeliness |
forbTimeEarliest | Time | The start of the forbidden time window. Tasks will not be carried out in the forbidden time window and will be scheduled either completely before or after it. | strict | |
forbTimeLatest | Time | The end of the forbidden time window. Tasks will not be carried out in the forbidden time window and will be scheduled either completely before or after it. | strict | |
timePriority | integer | The priority of the time window ranging from 0-5. (Default: 1)
|
strict on value 5 | |
location | GeoCoord | The geo coordinates where the task has to be performed. Not defining a location will allow the task to be performed anywhere. | ||
locationSiteID | integer | The ID of the LocationSite that will be used as location . |
||
finishLocation v3.9.0 | GeoCoord | The geo coordinates where the task will end. Moving between location and finishLocation occurs during the duration and does not count as travel (meaning the algorithm is not responsible for ensuring that it is actually possible to move between location and finishLocation in the time given). If not set, the task will finish where it started. |
||
finishLocationSiteID v3.9.0 | integer | The ID of the LocationSite that will be used as finishLocation . |
||
rotatable v3.9.0 | bool | If set to true, the algorithm can swap location and finishLocation (or corresponding LocationSite id) depending on what creates a better solution, similar to "rotating" the task in place. |
||
description | string | DEPRECATED | ||
prefWorkers | Array<integer> |
The IDs of preferred workers. | workerPrefs | |
antiWorkers | Array<integer> |
The IDs of workers to which an assignment is undesirable but not forbidden. | workerPrefs | |
forbWorkers | Array<integer> |
The IDs of forbidden workers. | strict | |
capacity | number | The capacity requirement of this task, which the assigned worker will need to provide. | strict | |
weight | number | The weight requirement of this task, which the assigned worker will need to provide. | strict | |
volume | number | The volume requirement of this task, which the assigned worker will need to provide. | strict | |
qualification | integer | The minimum qualification of the employee required to perform the task (e.g. years of experience). The algorithm tries to avoid high discrepancies between worker and task qualification. | strict | |
categories | Array<integer> |
A suitable worker has to fulfill all of these categories. | strict | |
antiCategories | Array<integer> |
Categories of other tasks which exclude joint performance with this task. | strict | |
exchangeableCategories | Array<integer> |
A suitable worker has to fulfill at least one of these categories. | strict | |
twinCategories | Array<integer> |
The assigned worker will need to perform at least two tasks with each of these categories. | strict | |
preassignedWorker | integer | The ID of the worker who has to take over this task. v3.6.1 This overrules any other strict restriction, for example, if the worker does not fulfil the qualification requirement, the task will still get assigned to them. | strict | |
preassignedOrder v3.13.0 | integer | Tasks with a value > 0 will be assigned to the start of the tour of the preassignedWorker , tasks with a value < 0 to the end. If multiple tasks preassigned to a worker have a preassignedOrder , the tasks will be sorted so that the preassignedOrder is increasing (tasks at the front of the tour and tasks at the end of the tour separately). An example can be found below. |
strict | |
desiredWorker | integer | The ID of the worker who is desired (strong preference, not influenced by workerPrefs) to take over this task. | ||
initassignedWorker | integer | The ID of the worker who will be initially assigned. This creates a higher likelihood of the task being assigned to this worker in the solution, especially if the initial assignment stems from a previous solution. | ||
initassignedOrder | integer | The order within the initially assigned worker's tour. Requires an initassignedWorker or a preassignedWorker . |
||
initassignedShiftID | integer | A shiftID to compliment either initassignedWorker or preassignedWorker in case the workerID is not unique. |
||
prefGender | GenderType | The assigned worker needs to have this gender. | strict | |
precedingTasks | Array<integer> |
Tasks in this list and this task will be performed by the same worker and all listed tasks will have to be finished before this task starts. | strict | |
predecessorTasks | Array<integer> |
The tasks of which one has to be performed right before this task by the same worker as this task. | strict | |
revenue | number | The revenue which will be achieved with this task. | ||
travelTimeExtra | integer | Fixed amount of time added to this task's travel time. | strict | |
group | integer | A group ID. Tasks with the same group ID get assigned to the same worker. | strict | |
assignmentPriority | integer | A priority for assignment (see allowUnassignedTasks ) ranging 0-5.
|
strict on value 5 | |
ignoreHistory v3.14.0 | boolean | (Default: false) If true, this task gets ignored in all history analysis. |
Restrictions
forbTimeEarliest
requiresforbTimeLatest
.forbTimeLatest
requiresforbTimeEarliest
.- Only one of
location
andlocationSiteID
is allowed. - Only one of
initassignedWorker
,preassignedWorker
anddesiredWorker
is allowed (Restriction removed inv3.13.0
). initassignedOrder
requiresinitassignedWorker
orpreassignedWorker
.initassignedShiftID
requiresinitassignedWorker
orpreassignedWorker
.- v3.9.0 Only one of
finishLocation
andfinishLocationSiteID
is allowed. - v3.9.0
finishLocation
requires eitherlocation
orlocationSiteID
. - v3.9.0
finishLocationSiteID
requires eitherlocation
orlocationSiteID
. - v3.9.0
rotatable
requires all of the below:- either
location
orlocationSiteID
- either
finishLocation
orfinishLocationSiteID
.
- either
- v3.13.0
preassignedOrder
requirespreassignedWorker
.
Notes
- Positive numbers for
capacity
,volume
orweight
represent loading tasks while negative numbers forcapacity
,volume
orweight
represent unloading tasks. Taken in sum over all tasks, it is not allowed to have more unloading capacity (/weight/volume) than loading. - The extension mentioned in
timePriority
cannot exceeddateFrom
ordateTo
.
Input Worker
Examples:
{
"workerID": 1,
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftDate": "2019-12-03"
}
{
"workerID": 1,
"shiftID": 10,
"externalID": "id123",
"startLocation":{
"lat": 50.878847,
"lng": 6.964728400000013
},
"startLocationSiteID": 4,
"endLocation":{
"lat": 50.878847,
"lng": 6.964728400000013
},
"endLocationSiteID": 5,
"shiftDate": "2019-12-03",
"shiftStart": "06:00",
"shiftEnd": "14:00",
"shiftPriority": 2,
"capacity": 20.5,
"capacityInitial": 10.1,
"capacityResetLocationSiteIDs": [1,2],
"capacityResetDuration": 10,
"maxResets": 2,
"volume": 12.5,
"volumeInitial": 5.5,
"weight": 2.5,
"weightInitial": 1.0,
"finalCapacityResetThreshold": 12.1,
"finalVolumeResetThreshold": 5.5,
"finalWeightResetThreshold": 1.5,
"qualification": 1,
"categories": [4,5],
"desiredCategory": 1,
"prefCategories": [6],
"breakStartEarliest": "12:21",
"breakEndLatest": "13:00",
"breakDuration": 10,
"vehicleType": 1,
"gender": 1,
"costsPerKM": 0.05,
"costsPerMinute": 1.23,
"costsInitial": 234.56,
"maxDesiredTotalDistance": 100.0,
"maxDesiredSingleDistance": 5.0,
"dontAlter": true,
"dontVary": true
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The worker has both optional and required parameters as marked in the following table.
Parameter | Required | Type | Description | Depends on |
---|---|---|---|---|
workerID | ✔ | integer | The ID of the worker. Multiple workers with identical ID are allowed, those represent multiple "shifts" of the same person. | |
shiftID | integer | A second ID in case there are multiple workers with the same workerID . This one needs to be unique among all workers with the same workerID that this worker has. It can be referenced whenever a unique reference to this worker object is required. |
||
externalID | string | A string to identify the worker in the solution. Cannot be used for reference in the input data or the optimizer, it serves as a helping tool for integrations. | ||
startLocation | GeoCoord | The location where the worker begins their working day. Leaving it empty means the worker starts on the location of their first task, this can be used in situations where workers start their day at home and any travel time to their first client does not count as working time. | strict | |
startLocationSiteID | integer | The ID of the LocationSite that will be used as startLocation . |
strict | |
endLocation | GeoCoord | The location where the worker finishes their working day. Leaving it empty means the worker will end their tour at their last task, this can be used in situations where travel time home does not count as working time. | strict | |
endLocationSiteID | integer | The ID of the LocationSite that will be used as endLocation . |
strict | |
shiftDate | ✔ | string (date) | The date of this shift. | |
shiftStart | ✔ | Time | The time this shift starts. | |
shiftEnd | ✔ | Time | The time this shift ends. | |
shiftPriority | integer | The priority to keep the defined shift start and end times ranging from 0-3: irrelevant, neutral, important, very important. The default value is 1. | ||
hoursPerWeek | integer | DEPRECATED | ||
capacity | number | The available capacity (positive value) of the worker or their vehicle. | strict | |
capacityInitial | number | The initially occupied capacity (positive value) on shift start of this worker or their vehicle. | ||
capacityResetLocationSiteIDs | Array<integer> |
If during the tour the worker capacity gets filled up and these reset LocationSite ids are set, the worker will travel to the best available LocationSite in the given list and unload all their stored capacity , weight and volume before traveling to the next task. |
strict | |
capacityResetDuration | integer | The time in minutes needed for a capacity reset (Default: 0). | strict | |
maxResets | integer | The maximum number of allowed capacity resets on this worker. | strict | |
volume | number | The available volume (positive value) of the worker or their vehicle. | strict | |
volumeInitial | number | The initially loaded volume (positive value) on shift start of this worker or their vehicle. | ||
weight | number | The weight (positive value) the worker or their vehicle is able to handle. | strict | |
weightInitial | number | The initially loaded weight (positive value) on shift start of this worker or their vehicle. | ||
finalCapacityResetThreshold | number | If at the end of the worker's tour the current capacity exceeds this threshold, a final reset is automatically added. | ||
finalVolumeResetThreshold | number | If at the end of the worker's tour the current weight exceeds this threshold, a final reset is automatically added. | ||
finalWeightResetThreshold | number | If at the end of the worker's tour the current volume exceeds this threshold, a final reset is automatically added. | ||
qualification | integer | The qualification of the worker. Workers can perform any task with equal or lower qualification requirement, the optimizer tried to not "overqualify" workers for tasks by keeping worker and task qualification close. | strict | |
categories | Array<integer> |
The categories the workers can take over. | strict | |
desiredCategory | integer | The worker has a strong preference towards tasks with this category. Categories specified in desiredCategory and prefCategories are automatically considered valid as if they're listed in categories . |
||
prefCategories | Array<integer> |
Tasks with any of these categories will be preferred by this worker. Categories specified in desiredCategory and prefCategories are automatically considered valid as if they're listed in categories . |
workerPrefs | |
breakStartEarliest | Time | The earliest start of the break a worker has to do. | strict, unless tightSchedule is set to true |
|
breakEndLatest | Time | The latest end of the break a worker has to do. | ||
breakDuration | integer | The duration in minutes of the break. | strict | |
vehicleType | VehicleType | The vehicle type used by this worker. | ||
gender | GenderType | The gender type of the worker. | ||
costsPerKM | number | The costs per km for this worker (e.g. fuel costs). | profitability | |
costsPerMinute | number | The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes). | profitability | |
costsInitial | number | Costs that occur if there is at least one task assigned to the worker. | profitability | |
maxDesiredTotalDistance | number | The maximum total travel distance per shift that a worker wants to perform. | ||
maxDesiredSingleDistance | number | The maximum travel distance for each individual travel that a worker wants to perform. | ||
dontVary | boolean | A worker with dontVary set to true is "fixed" for the optimizer, meaning they get assigned all tasks (and only those tasks) that have this worker set as preassignedWorker or initassignedWorker in the order of initassignedOrder . That also means that initassignedOrder is required for these tasks, as well as shiftID on the worker and initassignedShiftID on the task if the workerID is not unique. Travel times, resets, etc still get calculated on both worker and task and the worker and its tasks will be considered in Statistics and Info. |
strict | |
dontAlter | boolean | Workers with dontAlter set to true behave similarly to workers with dontVary . The only difference is that a dontVary -worker cannot get assigned more tasks than specified in the input data, a dontAlter -worker will be assigned all tasks that have this worker as initassignedWorker or preassignedWorker , but can also have other tasks assigned. While the preassigned/initassigned tasks will be in order of initassignedOrder , other tasks can be inserted before, between or after those tasks; if there is no initassignedOrder set, the task will be ignored. Every other behavior and requirement is exactly as in dontVary . |
strict |
Restrictions
- Only one of
startLocation
andstartLocationSiteID
are allowed - Only one of
endLocation
andendLocationSiteID
are allowed capacityInitial
requirescapacity
capacityResetLocationSiteIDs
requirescapacity
,weight
orvolume
capacityResetDuration
requirescapacityResetLocationSiteIDs
maxResets
requirescapacityResetLocationSiteIDs
volumeInitial
requiresvolume
weightInitial
requiresweight
finalCapacityResetThreshold
requirescapacity
andcapacityResetLocationSiteIDs
finalVolumeResetThreshold
requiresweight
andcapacityResetLocationSiteIDs
finalWeightResetThreshold
requiresvolume
andcapacityResetLocationSiteIDs
breakStartEarliest
requiresbreakEndLatest
,breakDuration
breakEndLatest
requiresbreakStartEarliest
,breakDuration
breakDuration
requiresbreakStartEarliest
,breakEndLatest
- Only one of
dontVary
anddontAlter
is allowed to be true
Location Site
Examples:
{
"locationSiteID": 200,
"location": {
"lat": 50.878847,
"lng": 6.964728400000013
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A location site is a GeoCoord which can be referenced by an id in various places:
Parameter | Type | Required | Description |
---|---|---|---|
locationSiteID | integer | ✔ | The ID of the location site. IDs need to be unique among all locationSite entries. |
location | GeoCoord | ✔ | The geo coordinates of the location site. |
Obstacle
DEPRECATED
History
Examples:
{
"tasks": [
{
"taskID": 0,
"clientID": 100,
"scheduling": [
{
"date": "2000-01-01"
}
]
}
],
"workers": [
{
"workerID": 0
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
tasks | ✔ | Array<History-Task> |
All tasks that are connected to Tasks in the optimization either by taskID or clientID . |
workers | ✔ | Array<History-Workers> |
Workers that are not included in the optimization but are referenced in History-Tasks, e.g. as assignedWorker . |
History-Task
Examples:
{
"taskID": 0,
"clientID": 100,
"scheduling": [
{
"date": "2000-01-01"
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
taskID | ✔ | integer | Task ID for referencing task in planning tasks. |
clientID | ✔ | integer | Client ID for referencing tasks in planning tasks. |
scheduling | ✔ | Array<History-Assignment> |
All considered historical assignments of this task. |
History-Assignment
Examples:
{
"date": "2000-01-01"
}
{
"date": "2000-01-01",
"baseScheduleTime": "00:00",
"baseWorker": 1,
"timeScheduled": "00:00",
"assignedWorker": 0,
"timeVariance": 0,
"timePriority": 0,
"timeScheduledAutomatically": "00:00",
"assignedWorkerAutomatically": 0,
"actualStartTime": "00:00",
"actualWorker": 0,
"prevTask": 0,
"prevActualTask": 0,
"prevTaskAutomatically": 0
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
date | ✔ | string (Date) | Date this assignment was on. |
baseScheduleTime | Time | A baseline orientation when the corresponding task was supposed to be scheduled. | |
baseWorker | integer | A baseline orientation for the worker to be assigned. | |
timeScheduled | Time | The time the corresponding task was scheduled (meaning the time the final plan had this task scheduled on, not to be confused with actualStartTime ) |
|
assignedWorker | integer | The worker the corresponding task was assigned to in the final planned version. | |
timeVariance | integer | The time variance the corresponding task was scheduled with at the time. | |
timePriority | integer | The timePriority the corresponding task was scheduled with at the time. |
|
timeScheduledAutomatically | Time | The time the corresponding task was scheduled on by the optimizer at the time. | |
assignedWorkerAutomatically | integer | The worker the corresponding task was assigned to by the optimizer at the time. | |
actualStartTime | Time | The time the task was actually started, for instance as determined by mobile tracking. | |
actualWorker | integer | The worker the task was actually carried out by, for instance as determined by mobile tracking. | |
prevTask | integer | The task that was assigned directly before this task at the time. (If that task is present in either history or planning tasks) | |
prevActualTask v3.20.0 | integer | The task that was carried out directly before this task at the time. (If that task is present in either history or planning tasks) | |
prevTask v3.20.0 | integer | The task that was assigned directly before this task by the optimizer at the time. (If that task is present in either history or planning tasks) |
History-Worker
Examples:
{
"workerID": 0
}
{
"workerID": 0,
"gender": 1,
"qualification": 1,
"categories": [ 1,2 ]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
workerID | ✔ | integer | ID of a worker that is not present in the input data. Has to be unique among all History-Workers. |
gender | GenderType | See Worker. | |
qualification | integer | See Worker. | |
categories | Array<integer> |
See Worker. |
Travel Override
{
"sparse": [
{
"vehicleTypes": [0,2],
"sourceIDs": [12,13,1,12],
"targetIDs": [14,11,12,1],
"travelTime": [3.1,0.4,1.0,1],
"travelDistance": [2.83,1.5,2.01,3.12]
},
{
"vehicleTypes": [1],
"sourceIDs": [12,13,1,12],
"targetIDs": [14,11,12,1],
"travelTime": [0.3,4.1,1.0,1],
"travelDistance": [2.83,1.5,2.01,3.12]
}
],
"dense": [
{
"travelTime": [0,0.2,3.1,4,0,2.1,12.01,5,0],
"travelDistance": [0,1.123,2.123,3.456,0,4.5,2.123,10.11,4.9,0],
"vehicleTypes": [0,3]
},
{
"travelTime": [0,2.1,3.0,4,0,2.01,0.12,5,0],
"travelDistance": [0,1.123,2.123,3.456,0,4.5,2.123,10.11,4.9,0],
"vehicleTypes": [2]
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Travel Override lets the user set custom values for travel between LocationSites. This can be useful if the values calculated by the optimizer are unsatisfactory or the use case is a non-street based optimziation (e.g. warehoue optimzation). The base schema consists of a single dense
and/or a single sparse
array, but at least one element:
Parameter | Required | Type | Description |
---|---|---|---|
dense | Array | Dense travel override data. | |
sparse | Array | Sparse travel override data. |
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
vehicleTypes | ✔ | Array<VehicleType> |
All vehicle types this override is relevant for. |
travelTime | Array<double> |
A row-concatenated matrix where $m(i,j) = travelTime($LocationSiteID i to LocationSiteID j$)$. | |
travelDistance | Array<number> |
A row-concatenated matrix where $m(i,j) = travelDistance($LocationSiteID i to LocationSiteID j$)$. |
Example: The travelTime
array [0,2,3,4,0,2,12,5,0]
translates to the following 3x3 matrix:
0 | 2 | 3 |
4 | 0 | 2 |
12 | 5 | 0 |
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
vehicleTypes | ✔ | Array<VehicleType> |
All vehicle types this override is relevant for. |
sourceIDs | ✔ | Array<integer> |
Start LocationSiteID. |
targetIDs | ✔ | Array<integer> |
End LocationSiteID. |
travelTime | Array<double> |
Travel time for the travel between source and target at the respective position in the array. | |
travelDistance | Array<number> |
Travel distance for the travel between source and target at the respective position in the array. |
Notes
- In the text above, LocationSiteID refers to
locationSiteID
. - Entries in
travelTime
andtravelDistance
are considered "not set" if they are either 0 or -1 and thus will not be used to override algorithm calculations. - Travel from or to LocationSiteIDs out of bounds (
dense
)/ Travel not specified in data (sparse
) will be considered exactly like unset data - Entries in
sparse
data will override entries indense
data.
Check status/retrieve a Plan
HTTP-Endpoint
This endpoint is used to get the status of a plan or retrieve the plan once the calculation has been finished.
DEVEL | GET https://develop.compute-adiutabyte.de/plan/<ID> |
PROD | GET https://production.compute-adiutabyte.de/plan/<ID> |
Request
In the header of the request the field Accept
must be set to application/json
. The <ID>
which was delivered as a result of the post request needs to be given in the URL.
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The plan will be delivered. |
404 | NOT FOUND | The requested ID does not exist. |
406 | NOT ACCEPTABLE | The given Accept parameter in the header could not be used. |
422 | UNPROCESSABLE ENTITY | The plan generated by the backend does not match the JSON-schema. Please contact us to correct this failure. |
423 | LOCKED | The plan is currently optimized. Try again later to check if the calculation has finished. |
500 | INTERNAL SERVER ERROR | An error occurred in the backend. Please contact us to check why this has happened. |
Result
Examples:
{
"requestID": "id2103",
"meta": {
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
},
"parameters": {
"preset": 1
},
"locationSites": [
{
"locationSiteID": 3,
"location": {
"lat": 50.3232323,
"lng": 7.23122212
}
}
],
"workers": [
{
"workerID": 1,
"shiftStart": "06:00",
"shiftEnd": "14:00",
"info": "text",
"shiftDate": "2019-12-03"
},
{
"workerID": 2,
"shiftStart": "05:00",
"shiftEnd": "16:00",
"shiftDate": "2019-12-03",
"info": "text",
}
],
"tasks": [
{
"taskID": 200,
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"timeScheduled": "11:01",
"travelTime": 3,
"travelDistance": 2.83061,
"assignedWorker": 2,
"info": "This task assignment causes negative arrival slack: -6"
},
{
"taskID": 200,
"date": "2019-12-03",
"duration": 65,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"info": "This task was unassigned"
}
],
"info": {
"text": "Alle Aufgaben wurden valide den Mitarbeitern zugewiesen!",
"balance": "4 Mitarbeiter sind eingeplant\n6,2 Aufgaben durchschnittlich (pro Mitarbeiter)\n1,2 Aufgaben Abweichung von der durchschnittlichen Aufgabenzahl (pro Mitarbeiter)\nAufgaben- und Reisezeiten in Summe: 886 Minuten\nSchichtzeiten in Summe: 1860 Minuten\nAuslastung (netto): 47,6%",
"dist": "146,8 km auf der Straße",
"pref": "12 Aufträge werden von einem gewünschten Mitarbeiter durchgeführt, bei 7 Aufträgen war dies leider nicht sinnvoll oder möglich",
"relax": "Aufträge:\n\nPrognostizierte kurze Verspätungen [5-30 Minuten] (4%):\n200, \n\nPrognostizierte Verspätungen [über 30 Minuten] (0%):\n\n\nDie anderen 24 Aufgaben (96%) werden pünktlich erreicht!\n\nSchichten:\nAlle Mitarbeiterschichten können eingehalten werden.",
"time": "170 Minuten auf der Straße\n42,5 Minuten auf der Straße durchschnittlich (pro Mitarbeiter)\n9,0 Minuten Reisezeitvarianz (pro Mitarbeiter)",
"feasible": false,
"constructionSites": [
{
"constructionSiteID": 666,
"startDate": "2020-07-23",
"endDate": "2020-07-25",
"startPoint": {
"lat": 48.17083,
"lng": 11.3292
},
"endPoint": {
"lat": 48.16774,
"lng": 11.33253
},
"info": "Waldstraße gesperrt 2020"
}
]
},
"statistics": {
"configuration": [
{
"label": "Short Path",
"value": 0.777778
}
],
"workload": [
{
"workerID": 1,
"values": [
0,0,0,0,0,0,0.97,1,0.5,0.17,0.07,0.5,0,0,0,0,0,0,0,0,0,0,0
]
}
],
"travelTimes": [
{
"workerID": 1,
"time": 51
}
],
"travelDistances": [
{
"workerID": 1,
"distance": 32.1
}
],
"taskTimes": [
{
"workerID": 1,
"time": 145
}
],
"taskBusyness": [
{
"workerID": 1,
"busyness": 0.3
}
],
"travelBusyness": [
{
"workerID": 1,
"busyness": 0.4
}
],
"workTimeDistribution": [
{
"type": "Working Time",
"time": 716
}
],
"preferredWorkers": [
{
"type": "matched",
"count": 12
},
{
"type": "unmatched",
"count": 7
}
],
"preferredGender": [
{
"type": "matched",
"count": 3
},
{
"type": "unmatched",
"count": 4
}
],
"desiredWorkers": [
{
"type": "matched",
"count": 9
},
{
"type": "unmatched",
"count": 13
}
],
"vehicleTypeDistances": [
{
"vehicleType": 0,
"distance": 9.123
},
{
"vehicleType": 3,
"distance": 4.2
}
],
"impact": [
{
"label": "Anticategories",
"value": 0.123
}
],
"unassignedTaskIDs": [1,2,3],
"unassignableTaskIDs": [1,2,3],
"routeLength": 146.841095,
"onTime": 96,
"planProfitability": 150.12
},
"backendVersion": {
"schema": "v0.49.9",
"version": "v2.25.12",
"rev": "abcde12"
},
"client": {
"clientID": "{1234-5678-9123}"
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The resulting plan mostly extends the Request by the fields marked "Extension" below:
Extension | Parameter | Required | Type | Description |
---|---|---|---|---|
➞ | requestID | string | A unique id to identify the plan. | |
client | client | Contains information about the client, which sent this request. | ||
meta | meta | Meta-information about what to consider in the optimization. | ||
parameters | parameters | Parameters for the optimization. | ||
tasks | ✔ | Array<Output Task> |
Array of output tasks. | |
workers | ✔ | Array<Output Worker> |
Array of available workers. | |
locationSites | Array<LocationSite> |
Array of available location sites. | ||
obstacles | Array<Obstacle> |
DEPRECATED | ||
➞ | statistics | ✔ | statistics | Some statistics about the plan. |
➞ | info | ✔ | info | Some textual information about the plan. |
➞ | backendVersion | ✔ | Backend Version | Used validation/ calculation version. |
Error Result
Example
{
"requestID": "id32013",
"error_msg": " |-| ERROR: Task #12 has itself assigned as preceding task. (129) |-| contact email: support@adiutabyte.de",
"version": "1.0.0",
"type": "error",
"errorID": 129,
"taskID": 12,
"backendVersion": {
"schema": "v0.49.9",
"version": "v2.25.12",
"rev": "abcde12"
},
"additionalErrors": [
{
"errorID": 129,
"error_msg": " |-| ERROR: Task #13 has itself assigned as preceding task. (129) |-| contact email: support@adiutabyte.de",
"taskID": 13
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
If your request contains errors which leads to unsatisfiable plans, you will receive a error response instead of a plan.
Parameter | Required | Type | Description |
---|---|---|---|
requestID | string | A unique id to identify the plan request. | |
error_msg | ✔ | string | Contains a textual description of the error. |
version | ✔ | string | Currently always set to "1.0.0". |
type | ✔ | string | Currently always set to "error". |
errorID | ✔ | integer | A unique ID for identifying the error cause. |
taskID | integer | If the error occurred by a specific task, its ID will be referenced. | |
taskExternalID v3.18.0 | string | The externalID corresponding to the taskID (if set). |
|
workerID | integer | If the error occurred by a specific worker, their ID will be referenced. | |
workerExternalID v3.18.0 | string | The externalID corresponding to the workerID (if set). |
|
backendVersion | ✔ | Backend Version | Used validation/ calculation version. |
additionalErrors v3.16.0 | Array<Object> |
During validation, errors do not necessarily terminate the program instantly. Instead they are collected and output in this list (the first validation error being output in the "main section" of the error result, each following in additionalErrors ). This is handy if there are multiple invalid tasks/workers/..., as all of these issues get caught during validation and output here. However, later entries in the additionalErrors list may be less reliable, since they could be based on an earlier failed validation and not be a problem with the input data (e.g. duplicated taskID s might lead to issues with precedingTasks ). |
The objects in additionalErrors
contain the following fields:
Parameter | Required | Type | Description |
---|---|---|---|
error_msg | ✔ | string | All fields exactly like in the "main" description above. |
errorID | ✔ | integer | |
taskID | integer | ||
taskExternalID v3.18.0 | string | ||
workerID | integer | ||
workerExternalID v3.18.0 | string |
The error_msg
gets translated based on language settings.
Type of error | errorID range |
---|---|
Internal errors (bugs). Please contact us so that we can fix the issue. |
|
Input object is missing required data or the given data is invalid for a required element. |
|
Input data fails validation (basic correctness or plausibility). Please check the error_msg for details! |
|
Error-ID
A list of errorID
values and explanations can be found here.
Backend Version
Examples:
{
"schema": "v0.0.0"
}
{
"schema": "v0.0.0",
"version": "v0.0.0",
"rev": "abde12"
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Description |
---|---|---|---|
schema | version | ✔ | The json schema version used for validating input and output. |
version | version | The backend version used for calculating the result. | |
rev | string | An internal key for the backed version used for calculating the result. |
Output Task
Examples:
{
... // see Input Task
"info": "text"
}
{
... // see Input Task
"timeScheduled": "12:10",
"travelTime": 3,
"travelDistance": 1.1,
"assignedWorker": 1,
"info": "text",
"profit": -1.2,
"finalassignedOrder": 4
}
{
... // see Input Task
"timeScheduled": "12:10",
"travelTime": 3,
"travelDistance": 1.1,
"assignedWorker": 1,
"assignedShiftID": 2,
"info": "text",
"profit": -1.2,
"performResetBeforeAtID": 3,
"rotated": true,
"finalassignedOrder": 4,
"travelTimeToReset": 10,
"travelDistanceToReset": 1.1
},
production | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) | ||
develop | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) | ||
experimental | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) |
The json schema for the Output Task extends the schema of the Input Task by all the fields marked "Extension" in the table below. If allowUnassignedTasks
was set to true, an "unassigned version" of the output task can be returned which is missing all assignment data.
Extension | Parameter | Required if assigned | Required if unassigned | Type | Description |
---|---|---|---|---|---|
All fields unchanged from Input-Task. | |||||
➞ | timeScheduled | ✔ | Time | The planned time to start this task by the assigned worker. | |
➞ | travelTime | ✔ | integer | The time in minutes needed to travel from the previous task to this task. If a reset is performed (performResetBeforeAtID is set), this includes the travel to a capacity reset location as well as the reset duration (capacityResetDuration ). Travel modifiers like minTravelTime and travelTimeExtra are also considered. |
|
➞ | travelDistance | ✔ | number | The distance in km needed to travel from the previous task to this task. The same rules as travelTime apply. |
|
➞ | assignedWorker | ✔ | integer | The ID (workerID ) of the assigned worker who will perform this task. |
|
➞ | assignedShiftID | integer | The shiftID to which the task is assigned to. |
||
➞ | finalassignedOrder | ✔ | integer | The order number within the assigned tour starting with number 1 . |
|
➞ | info | ✔ | ✔ | string | Additional information about the task. |
➞ | profit | ✔ | number | The profit the task creates ($revenue - costs$). | |
➞ | performResetBeforeAtID | integer | The id of the location site which will be visited to reset capacity /weight /volume before this task starts. |
||
➞ | travelTimeToReset v3.10.0 | integer | If a capacity reset is performed right before this task (performResetBeforeAtID is set), this value contains the travel time to the reset location. Subtracting this value and capacityResetDuration from travelTime nets the travel time from the reset location to this task. |
||
➞ | travelDistanceToReset v3.10.0 | integer | If a capacity reset is performed right before this task (performResetBeforeAtID is set), this value contains the travel distance to the reset location. Subtracting this value from travelDistance nets the travel distance from the reset location to this task. |
||
➞ | rotated v3.9.0 | boolean | If true, the rotation described in rotatable has occurred, meaning the task starts at its finishLocation and ends at its location . The field is only included if rotatable is set to true. |
Notes
- While not a formal requirement, the field
rotated
is always included in the response ifrotatable
is set to true.
Output Worker
Examples:
{
... // See Input Worker
"travelHomeTime": 2,
"travelHomeDistance": 1.123,
}
{
... // See Input Worker
"travelHomeTime": 2,
"travelHomeDistance": 1.123,
"breakStartEarliest": "10:00",
"breakEndLatest": "11:00",
"breakDuration": 30,
"breakScheduled": "12:10"
}
{
... // See Input Worker
"travelHomeTime": 2,
"travelHomeDistance": 1.123,
"info": "text",
"breakScheduled": "12:10"
}
{
... // See Input Worker
"travelHomeTime": 12,
"travelHomeDistance": 1.123,
"info": "text",
"breakScheduled": "12:10",
"performFinalResetAtID": 1,
"travelTimeToFinalReset": 10,
"travelDistanceToFinalReset": 1.1,
"tourStart": "12:10",
"tourEnd": "12:30",
"totalTravelTime": 10,
"totalTravelDistance": 11.123,
"totalTaskTime": 100
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The json schema for the Output Worker extends the schema of the Input Worker by all the fields marked "Extension" in the table below:
Extension | Parameter | Required | Type | Description |
---|---|---|---|---|
All fields unchanged from Input-Worker. | ||||
breakStartEarliest | Time | If integrateGermanBreakDurations is set to true and an automatic break is added, this value get filled in. |
||
breakEndLatest | Time | If integrateGermanBreakDurations is set to true and an automatic break is added, this value get filled in. |
||
breakDuration | integer | If integrateGermanBreakDurations is set to true and an automatic break is added, this value get filled in with the duration of the added break. |
||
➞ | breakScheduled | Time | The time a break was scheduled on this worker. | |
➞ | info | string | Some textual information about the worker, e.g. for delays. | |
➞ | travelHomeTime | ✔ | integer | Time in minutes needed to get to the end location from the last task. The same rules as for the Output-Task's travelTime apply. |
➞ | travelHomeDistance | ✔ | number | Distance in km between last task and the end location. The same rules as for the Output-Task's travelDistance apply. |
➞ | performFinalResetAtID | integer | The id of the LocationSite at which a capacity reset was performed after the last task and before returning to a depot. | |
➞ | travelTimeToFinalReset v3.10.0 | integer | If the worker performs a reset right before the end of their tour (performFinalResetAtID is set), this value contains the travel time to the reset location. Subtracting this value and capacityResetDuration from travelHomeTime nets the travel time from the reset location to the endLocation . |
|
➞ | travelDistanceToFinalReset v3.10.0 | number | If the worker performs a reset right before the end of their tour (performFinalResetAtID is set), this value contains the travel distance to the reset location. Subtracting this value from travelHomeDistance nets the travel distance from the reset location to the endLocation . |
|
➞ | tourStart v3.10.0 | Time | The actual time this worker starts their tour. The value is set only if the worker has a task assigned. If the worker has a task assigned and tourStartsOnShiftStart is set to true, it will always be equal to shiftStart . |
|
➞ | tourEnd v3.10.0 | Time | The actual time this worker ends their tour, including travel to its endLocation and any capacity resets. |
|
➞ | totalTravelTime v3.11.0 | ✔ | integer | The sum of all travel times of this worker. Does not include reset durations, neither from reset between tasks nor the final reset, travel to and from reset locations however is included. |
➞ | totalTravelDistance v3.11.0 | ✔ | number | The sum of all travel distances of this worker |
➞ | totalTaskTime v3.11.0 | ✔ | integer | The sum of all task durations on this worker. Does not include breaks or capacity reset duration. |
Statistics
Examples:
{
"configuration": [
{
"label": "Short Path",
"value": 0.777778
}
],
"workload": [
{
"workerID": 1,
"values": [
0,0,0,0,0,0,0.97,1,0.5,0.17,0.07,0.5,0,0,0,0,0,0,0,0,0,0,0
]
}
],
"travelTimes": [
{
"workerID": 1,
"time": 51
}
],
"travelDistances": [
{
"workerID": 1,
"distance": 32.1
}
],
"taskTimes": [
{
"workerID": 1,
"time": 145
}
],
"taskBusyness": [
{
"workerID": 1,
"busyness": 0.3
}
],
"travelBusyness": [
{
"workerID": 1,
"busyness": 0.4
}
],
"workTimeDistribution": [
{
"type": "Working Time",
"time": 716
}
],
"preferredWorkers": [
{
"type": "matched",
"count": 12
},
{
"type": "unmatched",
"count": 7
}
],
"preferredGender": [
{
"type": "matched",
"count": 3
},
{
"type": "unmatched",
"count": 4
}
],
"desiredWorkers": [
{
"type": "matched",
"count": 9
},
{
"type": "unmatched",
"count": 13
}
],
"vehicleTypeDistances": [
{
"vehicleType": 0,
"distance": 9.123
},
{
"vehicleType": 3,
"distance": 4.2
}
],
"impact": [
{
"label": "Anticategories",
"value": 0.123
}
],
"unassignedTaskIDs": [1,2,3],
"unassignableTaskIDs": [1,2,3],
"timeWindowViolationTaskIDs": [1,2,3],
"routeLength": 146.841095,
"onTime": 96,
"planProfitability": 150.12,
"history": {
"tasks": [
{
"taskID": 1,
"preassignedWorker": 1,
"timeEarliest": "12:00",
"timeLatest": "12:00",
"preferenceWeights": [
{
"workerID": 1,
"value": 0.123
}
],
"genderWeights": [
{
"gender": 1,
"value": 0.123
}
],
"prefGender": 1,
"desiredGroup": 1,
"timePriority": 1,
"initassignedWorker": 1,
"weakPredecessorTasks": [
1,
2,
3
],
"taskGaps": [
{
"taskID": 1,
"minGap": 1,
"maxGap": 1
},
{
"taskID": 1,
"minGap": -1,
"maxGap": -1
}
]
}
],
"workers": [
{
"workerID": 1,
"hasShortHistory": true
}
]
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The statistics
provide some general data for evaluating the result. v3.15.1 They are based on the adjusted data that the optimization is performed on. Differences to the tasks'/workers' input data are noted in their respective info
fields.
Parameter | Type | Required | Description |
---|---|---|---|
configuration | Array<Object<label: string, value: number>> |
✔ | The applied optimizer configurations mapped in ranges from $0.0$ to $1.0$. |
workload | Array<Object<workerID: integer, values: Array<number>>> |
✔ | The workload per worker for each hour of the day in ranges from $0.0$ to $1.0$ (worked 0 min to worked 60 min). |
travelTimes | Array<Object<workerID: integer, time: integer>> |
✔ | The total time in minutes each worker spends traveling. Capacity reset durations (but not the drive to and from a reset location) are excluded. |
travelDistances | Array<Object<workerID: integer, distance: number>> |
✔ | The distance in km each worker drives for this plan. |
taskTimes | Array<Object<workerID: integer, time: integer>> |
✔ | The time in minutes each worker spends on working on tasks (sum of durations). |
taskBusyness | Array<Object<workerID: integer, busyness: number>> |
✔ | Proportion of working time to shift time. |
travelBusyness | Array<Object<workerID: integer, busyness: number>> |
✔ | Proportion of travel time to shift time. Capacity reset durations (but not the drive to and from a reset location) are excluded. |
workTimeDistribution | Array<Object<type: string, time: integer>> |
✔ | The time in minutes spent on different actions summed up. Capacity resets are counted towards travel time. |
preferredWorkers | Array<Object<type: string, count: integer>> |
✔ | Sum of fulfilled (type: matched ) as well as unfulfilled (type: unmatched ) worker preferences. |
preferredGender | Array<Object<type: string, count: integer>> |
✔ | Sum of fulfilled (type: matched ) as well as unfulfilled (type: unmatched ) gender preferences. |
desiredWorkers | Array<Object<type: string, count: integer>> |
✔ | Sum of tasks assigned to desired workers (type: matched ) and sum of tasks assigned to another worker (type: unmatched ). |
vehicleTypeDistances | Array<Object<vehicleType: VehicleType, distance: number>> |
✔ | A number based summary of total distance for each VehicleType. |
impact | Array<Object<label: string, value: number>> |
✔ | Contains all restriction types and gives a percentage (0.0-1.0) evaluation of each restriction's final influence on the algorithmic optimization and plan result. This can be used to detect logical problems in the input data, i.e. too restrictive time windows, large travel times or a large amount of worker preferences that just cannot be fulfilled. However, please note that if a restriction is listed in impact with a value greater zero, it does not mean that there even is a way to erase its impact. For instance, travel values will always be featured unless the total amount of travel time is zero or the shortPaths option is set to zero. You can find all possible labels here. |
unassignedTaskIDs | Array<integer> |
taskIDs of all tasks that were not assigned during optimization. |
|
unassignableTaskIDs | Array<integer> |
taskIDs of all tasks that were not assigned during optimization because there is no assignment possible (meaning they would fail input validation if unassigned tasks were not allowed). |
|
timeWindowViolationTaskIDs | Array<integer> |
taskIDs of all tasks are not assigned within their given time window. |
|
routeLength | number | ✔ | The driven distance in km summed up over all workers. |
onTime | integer | ✔ | Percentage for tasks scheduled perfectly inside the desired time windows ($0$ to $100$). |
planProfitability | number | ✔ | The profitability this plan archives based on worker costs and task revenues. |
history v3.16.0 | Object | ✔ | Data analyzed from history . |
The history
entry contains the data from the history analysis:
Parameter | Type | Required | Description |
---|---|---|---|
workers | Array<Object> |
✔ | History analysis results for workers. |
tasks | Array<Object> |
✔ | Historical analysis results for tasks. |
Entries in workers
have the following fields:
Parameter | Type | Required | Description |
---|---|---|---|
workerID | integer | ✔ | ID to connect the worker to a worker in the workers array of the request. |
hasShortHistory | boolean | Is true if the worker "is new", meaning all their history data is very recent. |
Entries in tasks
have the following fields:
Parameter | Type | Required | Description |
---|---|---|---|
taskID | integer | ✔ | ID to connect the task to a task in the tasks array of the request. |
preassignedWorker | integer | The worker this task was preassigned to. | |
timeEarliest | Time | The historical timeEarliest . |
|
timeLatest | Time | The historical timeLatest . |
|
preferenceWeights | Array<Object<workerID: integer, value: number>> |
For each relevant worker, the preference of this task towards the worker. Higher number means higher preference. | |
genderWeights | Array<Object<gender: GenderType, value: number>> |
For each relevant GenderType, the preference of this task towards is gender. Higher number means higher preference. | |
prefGender | GenderType | The historical prefGender . |
|
desiredGroup | integer | Task of the same desiredGroup should be assigned to the same worker (similar to group but as a non-strict parameter). |
|
timePriority | integer | The historical timePriority . |
|
initassignedWorker | integer | The historical initassignedWorker . |
|
weakPredecessorTasks v3.20.0 | Array<integer> |
A historical predecessor to this task. | |
taskGaps | Array<Object<taskID: integer, minGap: signed integer, maxGap: signed integer>> |
Tasks listed here should be assigned from the task with a difference between their timeScheduled of at least minGap and at most maxGap . Negative values are allowed for both minGap and maxGap . |
Notes
- The array
configuration
contains the following fields. They are translated based on the language setting and are all required:
German label | English label |
---|---|
Kurze Wege | Short Path |
Arbeiterpräferenzen | Worker Preferences |
Faire Verteilung | Fair Distribution |
Clustering | Clustering |
Pünktlichkeit | Timeliness |
Weniger Arbeiter | Worker Reduction |
Reisezeit | Travel Time |
Arbeitszeit | Working Time |
Geschlechterpräferenzen | Gender Preferences |
Profitabilität | Profitability |
- The array
workTimeDistribution
contains the following fields. They are translated based on the language setting and are all required:
German type | English type |
---|---|
Arbeitszeit | Working Time |
Pausenzeit | Break Time |
Fahrzeit | Travel Time |
Schichtzeit | Shift Time |
Puffer | Buffer |
Info
Examples:
{
"text": "Alle Aufgaben wurden valide den Mitarbeitern zugewiesen!",
"balance": "4 Mitarbeiter sind eingeplant\n6,2 Aufgaben durchschnittlich (pro Mitarbeiter)\n1,2 Aufgaben Abweichung von der durchschnittlichen Aufgabenzahl (pro Mitarbeiter)\nAufgaben- und Reisezeiten in Summe: 886 Minuten\nSchichtzeiten in Summe: 1860 Minuten\nAuslastung (netto): 47,6%",
"dist": "146,8 km auf der Straße",
"pref": "12 Aufträge werden von einem gewünschten Mitarbeiter durchgeführt, bei 7 Aufträgen war dies leider nicht sinnvoll oder möglich",
"relax": "Aufträge:\n\nPrognostizierte kurze Verspätungen [5-30 Minuten] (4%):\n200, \n\nPrognostizierte Verspätungen [über 30 Minuten] (0%):\n\n\nDie anderen 24 Aufgaben (96%) werden pünktlich erreicht!\n\nSchichten:\nAlle Mitarbeiterschichten können eingehalten werden.",
"time": "170 Minuten auf der Straße\n42,5 Minuten auf der Straße durchschnittlich (pro Mitarbeiter)\n9,0 Minuten Reisezeitvarianz (pro Mitarbeiter)",
"feasible": false,
"constructionSites": [
{
"constructionSiteID": 666,
"startDate": "2020-07-23",
"endDate": "2020-07-25",
"startPoint": {
"lat": 48.17083,
"lng": 11.3292
},
"endPoint": {
"lat": 48.16774,
"lng": 11.33253
},
"info": "Waldstraße gesperrt 2020"
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The info
texts provide some textual context to the solution. v3.15.1 They are based on the adjusted data that the optimization is performed on. Differences to the tasks'/workers' input data are noted in their respective info
fields.
Parameter | Required | Type | Description |
---|---|---|---|
text | ✔ | string | Some general information about the plan. Contains warnings for some strict restrictions. |
balance | ✔ | string | Statistics about the workload of the workers and the distribution of tasks among them. |
dist | ✔ | string | Distance in km driven by the workers. |
pref | ✔ | string | Information about preferred workers matches. |
relax | ✔ | string | Information about delayed tasks grouped by delay amount: 5-30 minutes, 30+ minutes and information about exceeded worker shifts. |
time | ✔ | string | Total and average travel time. |
feasible | ✔ | boolean | Set to false if any strict restrictions (changed to this behavior in v3.15.1 ) are violated in the solution. |
constructionSites | Array<Construction Site> |
A list of construction sites in close proximity to the calculated routes. |
Notes
- All text in
text
,balance
,dist
,pref
,relax
,time
gets translated based on language setting.
Construction Site
Examples:
{
"constructionSiteID": 666,
"startDate": "2020-07-23",
"endDate": "2020-07-25",
"startPoint": {
"lat": 48.17083,
"lng": 11.3292
},
"endPoint": {
"lat": 48.16774,
"lng": 11.33253
},
"info": "Waldstraße gesperrt 2020"
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A construction site gets represented by a straight line between its startPoint
and endPoint
. These can be identical for small scale obstructions.
Parameter | Required | Type | Description |
---|---|---|---|
constructionSiteID | ✔ | integer | The ID of this construction site. IDs are unique among all construction sites. |
startPoint | ✔ | GeoCord | Start point of the construction site. |
endPoint | ✔ | GeoCoord | End point of the construction site. |
startDate | ✔ | string (date) | The first day of construction work at this site. |
endDate | ✔ | string (date) | The last day of construction work at this site. |
info | ✔ | string | Miscellaneous information. |
Additional Validation
Every request must adhere to the defined schemas or it cannot be processed. However, even if it does, there might still be issues with the contained data. For that reason, a content validation is performed after accepting the request, the details of which are listed below.
There are multiple times a validation is performed on the input data. If an issue is found, the corresponding error message will tell you exactly at which step the validation failed:
- Validation of raw input data, excluding data excluded by
resCapacity
,resCategory
,resQualification
. - Validation of input data after removing all unassignable tasks (this is only relevant is
allowUnassignedTasks
is set to true). - Validation of history adjusted data (this is only relevant if a
history
is included in the input data) - Validation after adjusting data (if
enablePlanSplitting
is true, the error message will tell you which subset of data had the issue).
If allowUnassignedTasks
is set to true, the first of these validations is allowed to fail some validations (the list below will tell you which). In this case the task is simply removed from calculation. You can determine these unassignable tasks from their info
section in the output or the array unassignableTasks
in statistics
.
List of all content requirements
errorID | allowed to fail | Requirement |
---|---|---|
121 | taskID must be unique among all tasks. |
|
123 | Task time windows must be large enough that duration fits inside. |
|
124 | ✔ | Task sets which have to be assigned to the same worker must have a worker that is not forbidden for any of them via any strict restriction. |
126 | For certain task chains which have a fixed order (e.g. predecessorTasks chains), if one task in the chain is assigned to a dontVary- or dontAlter-Worker, all of them must be. |
|
127 | Task time windows must be large enough that minTaskDuration fits inside (if set). |
|
1200 | The sum of all task capacities must not exceed the sum of all worker capacities. Workers with allowed capacity reset count as having unlimited capacity unless they have maxResets set. |
|
1201 | The sum of all task weights must not exceed the sum of all worker weight limits. Workers with allowed capacity reset count as having unlimited weight limit unless they have maxResets set. |
|
1202 | The sum of all task volumes must not exceed the sum of all worker volume limits. Workers with allowed capacity reset count as having unlimited volume limit unless they have maxResets set. |
|
1203 | A worker with the workerID of each task's initassignedWorker must exist (if set). |
|
1204 | If an initassignedOrder is set, initassignedWorker must be set as well. |
|
1205 | ✔ | Tasks must have a worker that is not forbidden via any strict restriction. Exempt are tasks with an assignment to a dontVary-Worker. |
1206 | Tasks must not have themselves as one of their precedingTasks . |
|
1207 | For each entry in precedingTasks , a task with that taskID must exist. |
|
1208 | Tasks must not have themselves as one of their predecessorTasks . |
|
1209 | capacityInitial must not be higher than capacity . |
|
1210 | weightInitial must not be higher than weight . |
|
1211 | volumeInitial must not be higher than volume . |
|
1212 | If capacityResetDuration is set, at least one capacityResetLocationSiteIDs must also be set. |
|
1213 | shiftEnd must not be before shiftStart . |
|
1214 | If breakEndLatest or breakDuration are set, breakStartEarliest must be set. |
|
1215 | If breakStartEarliest or breakDuration are set, breakEndLatest must be set. |
|
1216 | If breakStartEarliest or breakEndLatest are set, breakDuration must be set. |
|
1217 | The time between breakStartEarliest and breakEndLatest must be large enough to fit breakDuration . |
|
1218 | breakEndLatest must not be earlier than breakStartEarliest . |
|
1219 | breakStartEarliest must not be earlier than shiftStart , breakEndLatest must not be later than shiftEnd . |
|
1220 | Shifts of workers with the same workerID must not overlap. |
|
1221 | (Worker) Only one of startLocation and startLocationSiteID can be set. |
|
1222 | (Worker) Only one of endLocation and endLocationSiteID can be set. |
|
1223 | (Worker) A LocationSite with the locationSiteID equal to startLocationSiteID must exist (if set). |
|
1224 | (Worker) A LocationSite with the locationSiteID equal to endLocationSiteID must exist (if set). |
|
1225 | (Worker) For each entry in capacityResetLocationSiteIDs , a corresponding LocationSite with its locationSiteID equal to the entry must exist. |
|
1226 | (Task) Only one of location and locationSiteID can be set. |
|
1227 | (Task) A LocationSite with its locationSiteID equal to the task's locationSiteID must exist (if set). |
|
1230 | Multishift-Workers with dontVary or dontAlter set to true must have a shiftID . |
|
1231 | There must be at least as much positive capacity as negative. | |
1232 | There must be at least as much positive weight as negative. | |
1233 | There must be at least as much positive volume as negative. | |
1234 | It is not allowed for multiple task to have exactly one entry in predecessorTasks and have it be the same value. |
|
1235 | A task with set preassignedWorker and set initassignedWorker where one of the workers has dontVary or dontAlter set to true, must have preassignedWorker and initassignedWorker set in a way that they unambiguously refer to the same worker. |
|
1236 | A task assigned to a dontVary- or dontAlter-Worker via preassignedWorker or initassignedWorker must have an initassignedOrder . |
|
1237 | All tasks assigned to the same dontVary- or dontAlter-Worker via preassignedWorker or initassignedWorker must have a different initassignedOrder . |
|
1238 | For Multishift-Workers, shiftStart must not be equal to shiftEnd . |
|
1239 | Certain task chains which have a fixed order (e.g. predecessorTasks chains) and that are assigned to a dontVary- or dontAlter-Worker must have their chain order reflected in their initassignedOrder . |
|
1240 | If forbTimeEarliest is set, forbTimeLatest must be set. If forbTimeLatest is set, forbTimeEarliest must be set. |
|
1241 | forbTimeLatest must not be earlier than forbTimeEarliest . |
|
1242 | forbTimeEarliest and forbTimeLatest must be contained within the task's time window. |
|
1243 | The task must fit into its time window before and after the forbidden time window. | |
1244 | Only one of dontVary and dontAlter can be set to true. |
|
1245 | Dense travelOverride must not have less entries than required for the given amount of LocationSite s. |
|
1246 | shiftID must be unique for all workers with the same workerID . |
|
1247 | Tasks with preassignedWorker or initassignedWorker where at least one of the workers with that workerID has dontVary or dontAlter set to true, must have an initassignedShiftID . |
|
1248 removed in v3.20.8 | If timeliness is not set to zero, tasks with preassignedWorker and aninitassignedShiftID with the worker being a multishift-worker must have their task time window overlap with the worker's shift. |
|
1249 | (Worker) shiftStart , shiftEnd , breakStartEarliest and breakEndLatest must not be earlier than dateFrom at 00:00, shiftDate must not be later than dateTo . (Task) timeEarliest , timeLatest , forbTimeEarliest , forbTimeLatest must not be earlier than dateFrom at 00:00, date must not be later than dateTo . |
|
1250 | (Task) Only one of finishLocation and finishLocationSiteID can be set. |
|
1251 | (Task) A LocationSite with its locationSiteID equal to the task's finishLocationSiteID must exist (if set). |
|
1252 | (Task) If a finishLocationSite or finishLocationSiteID is set, a location or locationSiteID must also be set. |
|
1253 | (Task) finishLocation / finishLocationSiteID and location / locationSiteID must not be equal or refer the the same coordinate. |
|
1254 | If rotatable is set to true, one of finishLocation or finishLocationSiteID and one of location or locationSiteID must be set. |
|
1256 | v3.13.0 Tasks with preassignedOrder must have a preassignedWorker |
|
1257 | v3.13.0 Tasks with preassignedOrder which are preassigned to a multishift-worker must have an unambiguous assignment via initassignedShiftID |
|
1258 | v3.13.0 Tasks with preassignedOrder must not be part of another static task chain, e.g. via predecessorTasks . |
|
1259 | v3.13.0 Tasks assigned to the same worker must have different (or no) preassignedOrder . |
|
1260 | v3.18.1 If a task has a single entry in predecessorTasks , another task with that ID must exist. |
|
1503 | workerID s of history workers must not be used in workers of the workers array. |
|
1504 | workerID s of history workers must be unique among all history workers. |
|
1505 | taskID s of history tasks must be unique among all history tasks. |
|
1506 | All workers referenced in history tasks must exist either in the workers array or among the history workers. |
|
1507 | History assignments of the same task must be on different dates. | |
1508 | No history data must be equal or later than dateFrom . |
Examples
The following examples shall provide a starting point to build from when using the API for the first time. If you'd like to see one added, please contact us.
Posting/ Retrieving a plan
The example to the right provides a simple javascript template to post/get a request/response. Authentication details can be found here.
require('cross-fetch/polyfill');
const fetch = require('cross-fetch');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
// authentication
const userPool = new AmazonCognitoIdentity.CognitoUserPool({
UserPoolId: "[myUserPoolId]", // see authentication page
ClientId: "[myClientId]" // see authentication page
});
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
Username: "[myUserName]", // see login details of your adiutaByte account
Password: "[myPassword]"
});
const cognitoUser = new AmazonCognitoIdentity.CognitoUser({
Username: "[myUserName]", // see login details of your adiutaByte account
Pool: userPool
});
const token = await new Promise((resolve, reject) => cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
const thisToken = result.getIdToken().getJwtToken();
resolve(thisToken);
},
onFailure: function (err) {
console.log(err);
reject();
}
}));
// posting a request
const headers = {
'Content-Type': 'application/json',
'Authorization': token
};
const request = {
meta: {
dateFrom: "2019-12-03",
dateTo: "2019-12-03"
},
parameters: {},
tasks: [
{
date: "2019-12-03",
duration: 65,
taskID: 200,
timeEarliest: "10:00",
timeLatest: "12:00"
}
],
workers: [
{
workerID: 1,
shiftStart: "03:00",
shiftEnd: "12:00",
shiftDate: "2019-12-03"
}
]
};
const postOptions = {
method: 'post',
headers: new Headers(headers),
body: JSON.stringify(request)
};
const postURL = `https://[env].compute-adiutabyte.de/description`; // see endpoint section
const ID = await new Promise((resolve, reject) => fetch(postURL, postOptions)
.then(async res => {
if (res.ok) {
const data = await res.json();
console.log("Successfully posted request! ID:", data);
resolve(data);
}
else {
console.error("Error while posting request:", res.status);
reject();
}
}));
// get solution
let status = 423;
while (status === 423) {
const getURL = `https://[env].compute-adiutabyte.de/plan/${ID}`; // see endpoint section
const getOptions = {
method: 'get',
headers: new Headers(headers)
};
const solution = await new Promise((resolve, reject) => fetch(getURL, getOptions)
.then(async res => {
status = res.status;
resolve(res);
}));
if (status === 200) {
const solutionText = await solution.text();
console.log("Solution:", JSON.parse(solutionText));
break;
}
else if (status !== 423) {
console.error("Error while getting solution:", status);
break;
}
await new Promise(resolve => setTimeout(resolve, 5000));
}
Common plan for VRP/VRPTW
The following is an example of a common plan, solving a basic VRP with time windows. To include dynamic travel calculations, the option postProcessing
should almost always be set to true
.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Multiple shifts for workers
The field workerID
does not need to be unique, for when a worker has multiple working times in the same plan. The following json provides an example how this can look.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Using LocationSites instead of coordinates
LocationSites can be used to abbreviate coordinates, in some use cases they are actually required (capacityResetLocationSiteIDs
, travelOverride
). The file shows a way to use LocationSites instead of coordinates.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Single Tour Optimization
A special use case of the MixedPlanner is optimizing single tours, without switching tasks between them. This can be useful for re-optimizing slightly changed tours or tours determined by a used that only need to be "reshuffled" to an optimal order. The key entry here is the preassignedWorker
as it allows, if every task has one set, to keep the tours strictly separate.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Locked Workers
If only a subset and tasks and workers shall be optimized, it usually suffices to not include theses in your request. However, if those already calculated workers shall be included in info
/statistics
, there is a way to "lock" these workers for the algorithm (a common use case is re-optimizing a subsection of workers/tasks from a previous request - either to improve the solution or because changes have been made). There are two modes to do so, depending on whether or not it is allowed for locked workers to receive additional tasks:
If the locked workers shall not receive additional tasks, it needs to have the flag dontVary
set to true. Any task that is already assigned to this worker needs to have its workerID
as either initassignedID
or preassignedID
. In case there are multiple workers with the ID, the field initassignedShift
also needs to be set accordingly. Additionally it needs to be set at which position in the worker's tour the task should be positioned (initassignedOrder
). The request then looks like this:
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
If the locked worker is allowed to receive additional tasks but all already assigned tasks are not allowed to be moved off the worker or change order, the flag dontAlter
needs to be set to true instead of dontVary
. All other requirements stay the same, it should look something like this:
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Distance Matrix Usage/ Warehouse optimization
First available in version: v2.31.0
.
For various use cases (e.g. warehouse optimization) it may be desired to use custom travel data. The can be achieved with travelOverride
, where you can set custom distance matrices. This requires using LocationSites
for all coordinates as the matrices use the locationSiteID
to read the custom travel data. It is also probably a good idea to turn off postProcessing
to disable traffic/ population/ other dynamic travel adjustments.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Areal Tasks
First available in version: v3.9.0
.
Sometimes a task should not be represented by a single location but as a 2-dimensional line with a start and an end coordinate. Applications are for example street cleaning services where both ends of the street constitute begin/end location of the task. This can be modeled by setting the location, where the task completes, as finishLocation
. If the task can be started at either end, the flag rotatable
needs to be set to true.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Pickup and Delivery
PD Types of plans can be easily modeled with the task property precedingTasks
. The delivery task needs to have the taskID
of the pickup task set among its precedingTasks
and it will be performed by the same worker after the pickup. The is usually combined with the pickup task having a duration
of zero minutes. Multiple delivery tasks can draw from the same pickup, though this is not recommended if it can be avoided (the algorithm usually produces much better results with one pickup per delivery task).
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
If vehicles have a maximum number of pickups they can perform before delivering (a maximum vehicle capacity so to speak), the value capacity
needs to be set to that value (resCapacity
needs to be true as well). Each pickup task then should have a positive capacity
value (loading) while deliveries should have a negative capacity
value (unloading). This ensures that at no point the vehicle can have loaded more than the given maximum value.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Predefined tour start/ tour end
First available in version: v3.13.0
.
If you want to predefine a tour start or end for a worker, you can use the preassignedOrder
. Examples for use cases are:
* A worker has to prepare before their tour, this preparation is represented by a task and should be done first, before anything else.
* The plan is being recalculated but the worker has already done the first n tasks. The recalculation should not change any of those, only the later tasks.
* After their tour, the worker has to drive their vehicle to a maintenance station and end their tour there.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Common data types
Integers/Numbers
Examples:
{
"integer_u32": 12,
"integer_s32": -12,
"number_u32" : 7.184535,
"number_s32" : -7.184535,
"number_u64" : 7.184535,
"number_s64" : -7.184535,
"fraction" : 0.2
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The following ranges get used for values of type integer/ number:
ID | Name | Range |
---|---|---|
integer_u32 | integer | $0 \leq x \leq 2147483647$ |
integer_s32 | integer | $-2147483648 \leq x \leq 2147483647$ |
number_u32 | number | $0 \leq x \leq 3.4e+38$ |
number_s32 | number | $-3.4e+38 \leq x \leq 3.4e+38$ |
number_u64 | number | $0 \leq x \leq 1.7e+308$ |
number_s64 | number | $-1.7e+308 \leq x \leq 1.7e+308$ |
fraction | number | $0 \leq x \leq 1$ |
Please refer to the respective linked json schema to determine which type of integer/number gets used.
GeoCoord
Examples:
{
"lat": 50.780241,
"lng": 7.184535
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Domain | Description |
---|---|---|---|---|
lat |
number | ✔ | $-90 \leq x \leq 90$ | The latitude of the coordinate |
lng |
number | ✔ | $-180 \leq x \leq 180$ | The longitude of the coordinate |
Date
Examples:
"2018-01-10"
"2019-12-03"
"2020-05-23"
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A string consisting of three parts following the pattern "YYYY-MM-DD"
:
"YYYY"
: year AD, $ 2010 \leq x \leq 2099 $"MM"
: month, $ 1 \leq x \leq 12 $"DD"
: day, $ 1 \leq x \leq 31 $
Time
Examples:
"06:59"
"15:59"
"1230:33"
"-39:12"
"03:01"
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A string of either format "hh:mm"
or "-hh:mm"
:
"hh"
: hours, $ 0 \leq x \leq 10^{10} -1 $"mm"
: minutes, $ 0 \leq x \leq 59 $ with exactly 2 digits
All times are interpreted in 24-hour notation and relative to midnight ("00:00"
) of a certain defined date. Those dates are:
date
for any Time values in Input Task and Output Task.shiftDate
for any Time values in Input Worker and Output Worker.
This means that the following times applied to the respective date (in Date format) are equivalent:
"2021-05-21"
at"07:25"
"2021-05-20"
at"31:25"
"2021-05-19"
at"55:25"
"2021-05-22"
at"-16:35"
"2021-05-23"
at"-40:35"
Input data containing only identical dates and no time of format "-hh:mm"
will not result in output data containing times of format "-hh:mm"
.
VehicleType
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 4$.
VehicleTypeID | Description |
---|---|
0 | Car |
1 | Bicycle |
2 | Pedestrian |
3 | Truck |
4 | Public Transport Approximation |
GenderType
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 3$.
GenderTypeID | Description |
---|---|
0 | Not provided |
1 | Male |
2 | Female |
3 | Other |
LanguageType
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 1$.
LanguageTypeID | Description |
---|---|
0 | German |
1 | English |
Weekday
Introduced in: v3.4.0
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 6$.
value | Description |
---|---|
0 | Sunday |
1 | Monday |
2 | Tuesday |
3 | Wednesday |
4 | Thursday |
5 | Friday |
6 | Saturday |
Conventions
- All number values of times (task durations, travel times, ...) use the unit minutes.
- All distances (travel distances, ...) use the unit kilometer.
- Days start at 00:00 and end at 23:59.
Deployment Status
MixedPlanner Version | API Schema Validation Version | |
---|---|---|
production | v3.20.17 | v1.7.0 |
develop | v3.20.17 | v1.7.0 |
experimental | v3.20.17 | v1.7.0 |
Getting the deployed version
Introduced in: v3.10.0
Aside from checking this page, you can also get the deployed versions via a GET request.
HTTP-Endpoint
DEVEL | GET https://develop.compute-adiutabyte.de/version |
PROD | GET https://production.compute-adiutabyte.de/version |
Result
{
"version": "v3.9.15",
"schema": "v0.78.0",
"meta-data": "v15",
"api-scripts": "v1.5.0"
}
Parameter | Type | Description |
---|---|---|
version | version | The backend version used for calculating results. |
schema | version | The json schema version used for validating input and output. |
meta_data | version | The meta data version used to determine client specific behavior. |
api_scripts | version | The api script version. |
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The version data will be delivered. |
500 | INTERNAL SERVER ERROR | An error occurred in the backend. Please contact us to check why this has happened. |
Deprecation Warnings
The following features are deprecated and will be removed in a future version. Requests using these features will still get accepted in plan requests but do not influence calculations in any way.
v2.0.0
- In Input Task:
description
- In Output Task:
description
- In Input Worker:
hoursPerWeek
- In Output Worker:
hoursPerWeek
v3.0.0
- In Common Types: Obstacle
- In Meta Information:
integrateDurationExtensions
- always set totrue
- In Optimization Parameters:
workTimeRelax
- In Optimization Parameters:
travelTimeRelax
- In Request:
obstacles
- In Result:
obstacles
- If the array is included in the request, it will still be sent back in the response.
Changelog
2024-02-05
- In History Assignment: Added
prevActualWorker
with tagv3.20.0
. - In History Assignment: Added
prevWorkerAutomatically
with tagv3.20.0
. - In Statistics: Added
weakPredecessorTasks
to task objects inhistory
with tagv3.20.0
.
2024-02-01
- In Meta Information: Added
useDensityClustering
with tagv3.19.0
.
2024-01-31
- In Additional Validation: Added validation 1260 with tag
v3.18.1
.
2024-01-23
- In Error Result: Added
workerExternalID
with tagv3.18.0
. - In Error Result: Added
taskExternalID
with tagv3.18.0
.
2024-01-07
- Added section Checking your requests for validity.
2023-11-11
- In Error Result: Added
additionalErrors
with tagv3.17.0
.
2023-11-09
- In Statistics: Added
history
with tagv3.16.0
.
2023-10-26
- In Statistics: Updated description with tag
v3.15.1
. - In Info: Updated description with tag
v3.15.1
.
2023-10-24
- In Meta Information: Renamed
travelTimeMin
tominTravelTime
with tagv3.15.0
.- This renaming is backwards compatible, meaning the old field name will still work but will not be used anymore in any official documentation.
- In Input Task: Added
ignoreHistory
with tagv3.14.0
. - In Info: Updated description of
feasible
with tagv3.14.1
. - In Known Bugs: Updated fix version of "Rare Error 99" to
v3.13.1
.
2023-10-18
- In Additional Validation: Added validations 1503-1508.
2023-10-16
- In Input Task: Updated restrictions with tag
v3.13.0
.
2023-10-12
- In Input Task: Added
preassignedOrder
with tagv3.13.0
. - In Additional Validation: Added entries 1256-1259 with tag
v3.13.0
.
2023-10-07
- Added section Additional Validation.
2023-09-12
- In Meta Information: Added
minTaskDuration
with tagv3.12.0
.
2023-08-29
- In Examples: Added Posting/Retrieving a plan.
- Some minor restructuring.
2023-08-16
- In Output Worker: Added
totalTravelTime
with tagv3.11.0
. - In Output Worker: Added
totalTravelDistance
with tagv3.11.0
. - In Output Worker: Added
totalTaskTime
with tagv3.11.0
.
2023-08-09
- In Deployment Status: Added
Getting the deployed version
with tagv3.10.0
.
2023-08-02
2023-07-20
2023-06-20
- In Output Task: Added
travelTimeToReset
with tagv3.10.0
. - In Output Task: Added
travelDistanceToReset
with tagv3.10.0
. - In Output Worker: Added
travelTimeToFinalReset
with tagv3.10.0
. - In Output Worker: Added
travelDistanceToFinalReset
with tagv3.10.0
. - In Output Worker: Added
tourStart
with tagv3.10.0
. - In Output Worker: Added
tourEnd
with tagv3.10.0
. - In Info: Changed description of
feasible
with tagv3.9.4
/v3.15.1
. - In Known Bugs: Added maxResets are not being considered.
- In Known Bugs: Added Capacity thresholds are exceeded in certain cases when using maxResets.
2023-05-25
2023-05-17
2023-05-16
- In Examples: Renamed "Common plan for VRP" to "Common plan for VRP/VRPTW".
- In Known Bugs: Added Rare Error 99.
2023-05-12
- Added Examples.
- In Error Result: Added section "Error-ID".
2023-05-08
- In Optimization Types: Renamed
Unassigned Task
toInput Task
. - In Optimization Types: Renamed
Assigned Task
toOutput Task
. - In Optimization Types: Renamed
Unassigned Worker
toInput Worker
. - In Optimization Types: Renamed
Assigned Worker
toOutput Worker
.
2023-05-06
- In Unassigned Task: Added
finishLocation
with tagv3.9.0
. - In Unassigned Task: Added
finishLocationSiteID
with tagv3.9.0
. - In Unassigned Task: Added
rotatable
with tagv3.9.0
. - In Assigned Task: Added
finishLocation
with tagv3.9.0
. - In Assigned Task: Added
finishLocationSiteID
with tagv3.9.0
. - In Assigned Task: Added
rotatable
with tagv3.9.0
. - In Assigned Task: Added
rotated
with tagv3.9.0
.
2023-05-03
- In Error Result: Updated error code ranges with tag
v3.8.21
.
2023-04-22
- Added Deployment Status.
2023-04-03
- In Conventions: Added convention.
- In Unassigned Task: Added note regarding
timePriority
.
2023-03-14
- Created standalone MixedPlanner documentation.
2023-03-13
- In Meta Information: Added
tourStartsOnShiftStart
with tagv3.6.0
. - In Unassigned Task: Changed description of
preassignedWorker
with tagv3.6.1
.