Task Sequencing
Sequencing tasks in time according to the available resources: A task sequencing problem can be solved for work defined according to two hierarchies: orders and tasks.
If only orders are provided, they will be scheduled as if they are the lowest level detail that needs to be handled by the sequencing model. If however, orders are defined that contain tasks, these tasks are considered the lowest level detail of work that needs to be sequenced. The order level is then only used to incorporate priorities.
Introduction
We illustrate the task sequencing problem with a very simple example. Two orders – both requiring a hammer and a technician – need to be scheduled. We provide two technicians as resources, but only a single hammer: the two tasks can only be scheduled one after the other.
We show the planning request and the solution for this toy example hereafter:
curl --request POST --url https://api.solvice.io/solve?seconds=1 -H "Authorization: <<apiKey>>" \
--data '
{
"solver": "TASK",
"resources": [
{
"type": "plannable",
"name": "technician",
"supply" : [
{
"name" : "Alex"
},
{
"name" : "Sam"
}
]
},
{
"type": "capacitated",
"name" : "hammer",
"supply": 1
}
],
"orders": [
{
"name": "order0",
"priority" : 10,
"duration" : "PT30M",
"resourceRequirements": {
"technician": 1,
"hammer" : 1
}
},
{
"name": "order1",
"priority" : 10,
"duration" : "PT30M",
"resourceRequirements": {
"technician": 1,
"hammer" : 1
}
}
]
}
{
"solution": [
{
"task": "Order: order0",
"from": "2022-02-18T22:00:00",
"to": "2022-02-18T22:30:00",
"capacitated": {
"hammer": 1
},
"plannable": {
"technician": [
"Alex"
]
}
},
{
"task": "Order: order1",
"from": "2022-02-18T22:30:00",
"to": "2022-02-18T23:00:00",
"capacitated": {
"hammer": 1
},
"plannable": {
"technician": [
"Alex"
]
}
}
],
"period": {
"from": "2022-02-18T22:00:00",
"to": "2022-02-20T06:00:00"
}
}
Play around with the API explorer
Check out the explorer API Reference and select the body for the TASK request.
Input
We will now describe in more detail the different components which compose a task sequencing planning request. A request of the task sequencing model is defined by providing the orders (and/or tasks) that need to be planned and the resources that are available to assign to those. Optionally, one can also include the planning period.
Order
An Order is an executable piece of work that can take a pre-determined amount of time, and that needs to be handled with a certain priority. It can contain multiple tasks.
If tasks are provided, they are sequenced rather than the order itself. An order can have a resourceRequirement.
Property | Type | Description | Required/Optional |
---|---|---|---|
name | String | The unique name of the order | Required |
priority | Integer | The priority with which the order needs to be scheduled | Required |
duration | Duration | The duration of the order (in multiples of 30 minutes) | Optional |
tasks | Array of Tasks | An array of tasks | Optional |
resourceRequirements | ResourceRequirements | A combination of resources that is required to perform the order | Optional |
dueDate | DateTime | The ISO 8610 date time indicating when this order (it's last taks if tasks are provided) should be completed. | optional |
Task
A task is the lowest-level detail for work that needs to be scheduled that can be provided in the model. If provided, it is always defined under the higher hierarchy of an order. Futher, we define tasks using a duration (pre-determined amount of time to finish the task), a resourceRequirement and (optionally) an availability.
If resourceRequirements are defined both on the level of the order, as well as on the level of the task, the requirements add up. One can therefore define shared resource requirements (e.g. a team of technicians) for the order and then add specific requirements (e.g. tooling) per task.
Availabilities are used to restrict the times at which a task can be scheduled. If none is provided, the task is assumed to be plannable throughout the complete planning period.
Name | Type | Description | Required/Optional |
---|---|---|---|
name | String | The unique name of the task | Required |
duration | Duration | The duration of the task (in multiples of 30 minutes) | Optional |
availability | Array of DateTimeWindows | The availability of a task can be defined by providing an array of DateTimeWindows | Optional |
resourceRequirements | ResourceRequirement | A combination of resources that is required to perform the order. | Optional |
DateTimeWindows
The availability of a resource or a task is defined by providing an array of DateTimeWindows. These windows define the time periods at which this resource or task can be planned. It is fully characterized by a from and a to date time.
Name | Type | Description |
---|---|---|
from | DateTime | The ISO 8610 date time indicating the start of the availability |
to | DateTime | The ISO 8610 date time indicating the (exclusive) end of the availability |
ResourceRequirement
For the work that is incorporated in the model (from either orders or tasks), a resource requirement can be defined. A resource requirement is an object that maps a resource type to a requirement. The resource requirement is therefore always constructed from key - value pairs, where the key defines the resource type, and the value can be specified using three different constructs:
- how many of these resources are required.
- a specific name for the resource that is required.
- an object that incorporates how many resources, which resources are allowed and what (additional) skills they require.
{
"hammer": 2,
"location": "location0",
"operator": {
"value" : 2,
"skill" : ["electrician", "heavy tool"]
}
}
This object can then include:
Name | Type | Description |
---|---|---|
value | Integer | Number of such resources required |
skill | Array of Strings | The required skills for these resources |
allowedResources | Array of Strings | The allowed resources that can be assigned to this task/order |
Resource
There are 2 types of Resources:
- a Plannable Resource: demands that a resource is explicitly assigned to a task.
- a Capacitated Resource: only requires available capacity of a resource. Specific assignment is not necessary.
For example, take the assignment problem of a task "hammer a nail" that requires a technician and a hammer to execute that task.
Usually, we don't need to know that for task "hammer a nail", you need a specific hammer with serial number SNxxx.
You just need to know that there are ample hammers available for all tasks that require a hammer to be performed at the same time. E.g. there are 4 hammers available and you will take 1.
For a technician however, it might be required that the schedule points out who will execute that task.
Will it be John, Alex or Lee?
Therefore, a hammer can be considered a Capacitated Resource, while a technician is a Plannable Resource in this example.
We illustrate both with an example and show the properties we can use to define them:
Capacitated Resource
An example of the structure of a Capacitated Resource:
{
"type": "capacitated",
"name": "hammer",
"supply": 4,
"availability":
[
{
"from": "2021-02-06T09:00:00",
"to": "2021-02-06T18:00:00"
}
]
}
Name | Type | Description | Required/Optional |
---|---|---|---|
name | String | The name of the resource | Required |
type | "capacitated" | A type indicating that this is a capacitated resource and assignments will not be 'made on a named basis'. | Required |
supply | Integer | The number of resources of this type available | Required |
availability | Array of DateTimeWindows | The availability of this resource can be defined by providing an array of DateTimeWindows | Optional |
Plannable Resource
An example of the structure of a Plannable Resource:
{
"type": "plannable",
"name": "technician",
"supply": [
{
"name": "John",
"skill": ["a","b"],
"availability": [ {
"from": "2021-02-06T09:00:00",
"to": "2021-02-06T18:00:00"
}]
}
]
}
Name | Type | Description | Required/Optional |
---|---|---|---|
name | String | The name of the resource | Required |
type | "plannable" | A type indicating that this is a plannable resource and assignments will be 'made on a named basis'. | Required |
supply | Array of NamedResources | An array that lists the resources of this type that can be planned 'on a named basis' | Required |
availability | Array of DateTimeWindows | The availability of this resource type can be defined by providing an array of DateTimeWindows | Optional |
NamedResources
In orde to provide the supply for a plannable resource type: one should define the NameResources, using their name, their list of skills and (optionally) their availability:
Name | Type | Description | Requied/Optional |
---|---|---|---|
name | String | The name of this specific resource | Required |
skill | Array of Strings | The skills for this resource | Optional |
availability | Array of DateTimeWindows | The availability of this specific resource can be defined by providing an array of DateTimeWindows | Optional |
Period
If a planning period is not provided in a task sequencing request, it defaults to a period starting today at 22h (UTC), until 06h in the morning the day after tomorrow (also UTC).
Name | Type | Description |
---|---|---|
from | DateTime | The ISO 8601 date time indicating the start of the planning period |
to | DateTime | The ISO 8601 date time indicating the end (exclusive) of the planning period |
Constraints
Code | Description |
---|---|
Resource Availability | A task should not be planned to a resource outside its availability |
Resource Capacity | A resource should not assigned at the same time to more than one task. |
Order Priority | The priority of the orders that are assigned is maximized. |
Output
The output of our task sequencing API shows us when an order (or a task) has been sequenced and which resources are assigned to it. The example below shows a task that has had both a plannable resource (i.e. the technician "John") and a capacitated resource assigned to it.
"solution": [
{
"task": "Operation Order0.000",
"from": "2022-02-17T23:00:00",
"to": "2022-02-17T23:30:00",
"capacitated": {
"hammer": 1
},
"plannable": {
"technician": [
"John"
]
}
}
]
The solution is composed of an array of taskassignments:
Name | Type | Description |
---|---|---|
task | String | The name of the planned task |
from | DateTime | The ISO 8601 date time indicating the planned start of task |
end | DateTime | The ISO 8601 date time indicating the planned end of task |
capacitated | A map of Key-Value pairs | For each capacitated resource type, the assigned number of resources for this task is returned |
plannable | A map of Key-Value pairs | For each plannable resource type, an array is returned that contains the name of the assigned name resources |
Updated about 2 years ago