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

CodeDescription
Resource AvailabilityA task should not be planned to a resource outside its availability
Resource CapacityA resource should not assigned at the same time to more than one task.
Order PriorityThe 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