Shift Assignment

Shift assignment

A how-to guide for specifying input and output schemas in shift assignment.

The shift assignment app is available in two modeling languages as a Mixed Integer Problem (MIP). You can also choose to make customizations to the model by instantiating the app first.

nextmv community clone -a python-ortools-shiftassignment
Copy
nextmv sdk init -t python-pyomo-shiftassignment
Copy

Once you have the code locally, you can customize the model, run it locally and deploy it to Nextmv Platform.

Input

The format for timestamps should be RFC3339, e.g.: "2023-01-01T00:00:00Z".

The input schema is a JSON payload defining the available workers and the required demand to satisfy for a shift scheduling problem. Nextmv's tools are designed to operate directly on business data (in JSON) to produce decisions that are actionable by software systems. This makes decisions more interpretable and easier to test. It also makes integration with data warehouses and business intelligence platforms significantly easier. An input contains the following components:

Field nameRequiredData typeSI UnitDescriptionExample
workersYesarray of workerNAWorkers to assign.See worker
shiftsYesarray of shiftNAAvailable shifts with some additional properties.See shift
rulesYesarray of ruleNADefines a set of rules to obey.See rule

Here you can find a sample .json with the input schema:

{
  "workers": [
    {
      "id": "Louis Hardy",
      "qualifications": ["welding"],
      "rules": "standard",
      "preferences": {
        "welder_monday-early": 1,
        "welder_monday-late": 1
      },
      "availability": [
        {
          "start_time": "2023-11-20T00:00:00+02:00",
          "end_time": "2023-11-21T00:00:00+02:00"
        },
        {
          "start_time": "2023-11-21T00:00:00+02:00",
          "end_time": "2023-11-22T00:00:00+02:00"
        }
      ]
    },
    {
      "id": "Jacob Cunningham",
      "qualifications": ["welding"],
      "rules": "standard",
      "preferences": {
        "welder_monday-early": 1,
        "normal_monday-early": 1
      },
      "availability": [
        {
          "start_time": "2023-11-20T00:00:00+02:00",
          "end_time": "2023-11-21T00:00:00+02:00"
        },
        {
          "start_time": "2023-11-21T00:00:00+02:00",
          "end_time": "2023-11-22T00:00:00+02:00"
        }
      ]
    },
    {
      "id": "Ray Heard",
      "qualifications": ["welding"],
      "rules": "standard",
      "preferences": {
        "welder_monday-early": 1,
        "normal_monday-early": 1
      },
      "availability": [
        {
          "start_time": "2023-11-20T00:00:00+02:00",
          "end_time": "2023-11-21T00:00:00+02:00"
        },
        {
          "start_time": "2023-11-21T00:00:00+02:00",
          "end_time": "2023-11-22T00:00:00+02:00"
        }
      ]
    },
    {
      "id": "Mark Leath",
      "qualifications": [],
      "rules": "standard",
      "preferences": {
        "normal_monday-late": 1
      },
      "availability": [
        {
          "start_time": "2023-11-20T00:00:00+02:00",
          "end_time": "2023-11-21T00:00:00+02:00"
        },
        {
          "start_time": "2023-11-21T00:00:00+02:00",
          "end_time": "2023-11-22T00:00:00+02:00"
        }
      ]
    },
    {
      "id": "Dylan Mccormack",
      "qualifications": [],
      "rules": "standard",
      "availability": [
        {
          "start_time": "2023-11-20T00:00:00+02:00",
          "end_time": "2023-11-21T00:00:00+02:00"
        },
        {
          "start_time": "2023-11-21T00:00:00+02:00",
          "end_time": "2023-11-22T00:00:00+02:00"
        }
      ]
    }
  ],
  "rules": [
    {
      "id": "standard",
      "min_rest_hours_between_shifts": 11
    }
  ],
  "shifts": [
    {
      "id": "welder_monday-early",
      "shift_id": "welder",
      "time_id": "monday-early",
      "start_time": "2023-11-20T06:00:00+02:00",
      "end_time": "2023-11-20T14:00:00+02:00",
      "qualification": "welding",
      "count": 1
    },
    {
      "id": "welder_monday-late",
      "shift_id": "welder",
      "time_id": "monday-late",
      "start_time": "2023-11-20T14:00:00+02:00",
      "end_time": "2023-11-20T22:00:00+02:00",
      "qualification": "welding",
      "count": 1
    },
    {
      "id": "normal_monday-early",
      "shift_id": "normal",
      "time_id": "monday-early",
      "start_time": "2023-11-20T06:00:00+02:00",
      "end_time": "2023-11-20T14:00:00+02:00",
      "qualification": "",
      "count": 2
    },
    {
      "id": "normal_monday-late",
      "shift_id": "normal",
      "time_id": "monday-late",
      "start_time": "2023-11-20T14:00:00+02:00",
      "end_time": "2023-11-20T22:00:00+02:00",
      "qualification": "",
      "count": 1
    }
  ]
}
Copy

Worker

A worker is used in the input schema.

Field nameRequiredData typeDescriptionExample
availabilityYesarray of availabilityThe availability times of the workerSee availability
idYesstringID for the worker.{"id": "1"}
rulesYesstringID of a rule to comply with (see rule).{"rules": ["foo", "bar"]}
qualificationsYesarray of stringA set of qualifications/skills a worker has.{"qualifications": ["foo", "bar"]}
preferencesYesmap of string to intDefines preferred shifts, a higher number means more important."preferences": {"shift1": "1"}

Availability

Availability is used in the worker schema.

Field nameRequiredData typeSI UnitDescriptionExample
start_timeYestimestampNAThe start of an availability time window for a worker.{"start_time": "2023-01-01T00:00:00Z"}
end_timeYestimestampNAThe end of an availability time window for a worker.{"end_time": "2023-01-01T00:00:00Z"}

Shift

Shift is used in the input schema.

Field nameRequiredData typeDescriptionExample
start_timeYestimestampThe start time of a shift.{"start": "2023-01-01T00:00:00Z"}
end_timeYestimestampThe end time of a shift.{"end": "2023-01-01T00:00:00Z"}
countYesintThe number of workers needed for the shift.{"count": 1}
shift_idYesstringID of the shift type.{"shift_id": "1"}
time_idYesstringID of the shift type and time combination.{"time_id": "1"}
qualificationYesstringThe qualification needed to work this shift.{"qualification": "1"}

Rule

Rule is used in the input schema.

Field nameRequiredData typeDescriptionExample
idYesstringID of the rule.{"id": "1"}
min_rest_hours_between_shiftsYesintegerDefines the number of hours a worker must rest between shifts.{"min_rest_hours_between_shifts": 1}

Output

The output schema defines the solution to the shift assignment problem in JSON format. The output schema contains the following components.

Field nameAlways presentData typeSI UnitDescriptionExample
solutionsYesarray of solutionNASolutions to the shift assignment problem.{"solutions": []}
statisticsYesstatisticsNASummary statistics of the solution.{"statistics": {"total_cost": 123}}
{
  "options": {
    "duration": 30,
    "input": "input.json",
    "output": "output.json",
    "provider": "SCIP"
  },
  "solution": {
    "assigned_shifts": [
      {
        "end_time": "2023-11-20T22:00:00+02:00",
        "shift_id": "welder_monday-late",
        "start_time": "2023-11-20T14:00:00+02:00",
        "worker_id": "Louis Hardy"
      },
      {
        "end_time": "2023-11-20T14:00:00+02:00",
        "shift_id": "welder_monday-early",
        "start_time": "2023-11-20T06:00:00+02:00",
        "worker_id": "Jacob Cunningham"
      },
      {
        "end_time": "2023-11-20T14:00:00+02:00",
        "shift_id": "normal_monday-early",
        "start_time": "2023-11-20T06:00:00+02:00",
        "worker_id": "Ray Heard"
      },
      {
        "end_time": "2023-11-20T22:00:00+02:00",
        "shift_id": "normal_monday-late",
        "start_time": "2023-11-20T14:00:00+02:00",
        "worker_id": "Mark Leath"
      },
      {
        "end_time": "2023-11-20T14:00:00+02:00",
        "shift_id": "normal_monday-early",
        "start_time": "2023-11-20T06:00:00+02:00",
        "worker_id": "Dylan Mccormack"
      }
    ]
  },
  "statistics": {
    "result": {
      "custom": {
        "active_workers": 5,
        "constraints": 44,
        "status": "optimal",
        "total_workers": 5,
        "variables": 20
      },
      "duration": 0.123,
      "value": 4
    },
    "run": {
      "duration": 0.123
    },
    "schema": "v1"
  }
}
Copy

Solution

Field nameAlways presentData typeSI UnitDescriptionExample
planned_shiftsYesarray of planned_shiftNASolution to the shift scheduling problem.{"planned_shifts": []}

Planned shift

Field nameAlways presentData typeSI UnitDescriptionExample
start_timeYestimestampNAStart time of the shift{"start_time": "2023-01-01T00:00:00Z"}
end_timeYestimestampNAEnd time of the shift{"end_time": "2023-01-01T00:00:00Z"}
idYesstringNAThe ID of shift, time and qualification combination.{"id": "1"}

Statistics

Field nameAlways presentData typeSI UnitDescriptionExample
resultNoresultNAFinal result of the solutions.See result
runYesrunNAInformation about the run.See run
schemaYesstringNASchema of the statistics.{"schema": "v1"}

Here you can find additional definitions used in the statistics schema:

  • result

    Field nameAlways presentData typeSI UnitDescriptionExample
    durationYesfloatsecondsTime duration to get to the final result.{"duration": 0.123}
    valueYesfloatNAValue of the final result.{"value": 0.123}
    customYesanyNACustom solver metrics.See custom
  • run

    Field nameAlways presentData typeSI UnitDescriptionExample
    durationYesfloatsecondsTime duration of the run.{"duration": 0.123}
  • custom

    Field nameAlways presentData typeSI UnitDescriptionExample
    constraintsYesintNANumber of constraints.{"constraints": 123}
    providerYesstringNASolver provider.{"provider": "SCIP"}
    statusYesstringNASolver status.{"status": "optimal"}
    variablesYesintNANumber of variables.{"variables": 123}

Run options

These are the default options that are available with shift assignment.

usage: main.py [options]

Options for main.py. Use command-line arguments (highest precedence) or
environment variables.

options:
  -h, --help            show this help message and exit
  -input INPUT, --input INPUT
                        [env var: INPUT] (default: ) (type: str): Path to
                        input file. Default is stdin.
  -output OUTPUT, --output OUTPUT
                        [env var: OUTPUT] (default: ) (type: str): Path to
                        output file. Default is stdout.
  -duration DURATION, --duration DURATION
                        [env var: DURATION] (default: 30) (type: int): Max
                        runtime duration (in seconds).
  -provider PROVIDER, --provider PROVIDER
                        [env var: PROVIDER] (default: SCIP) (type: str):
                        Solver provider.
Copy

Page last updated

Go to on-page nav menu