Workforce planning optimization using Python and ErlangC

Learn how to find the optimal number of positions needed to manage incoming traffic

Rodrigo Arenas
Towards Data Science

--

Photo by Lisanto on Unsplash

Finding the number of positions to use in a queue system has been a study case for a long time now; it has applications in several fields and industries, for example, finding the optimal number of call centers agents, deciding the number of bankers in a support station, network traffic analysis and so on.

There are several methods to analyze this problem; in this article, we will look at how to solve it using Erlang C with Python's Pyworkforce package.

1. Queue System

In the most fundamental Erlang C method, we represent the system as a queue with the following assumptions:

  • There is incoming traffic with a constant rate; the arrivals follow a Poisson process
  • There is a fixed capacity in the system; usually, only one transaction gets handled by a resource at the time
  • There is a fixed number of available positions in a time interval
  • When all the positions have a total capacity, there is an infinite queue length where the requests wait for a position to be free.
  • An exponential distribution describes the holding times in the queue
  • There is no dropout from the queue.

A queue system with these characteristics may look like this:

Queue System. Image by the author.

In this representation, we can see several measures that will help us to describe the system; here there are their definitions and how we are going to call them from now on:

  • Transactions: Number of incoming requests
  • Resource: The element that handles a transaction
  • Arrival rate: The number of incoming transactions in a time interval
  • Average speed of answer (ASA): Average time that a transaction waits in the queue to be attended by a resource
  • Average handle time (AHT): Average time that takes to a single resource to attend a transaction

Other variables are in the diagram, but that is important for the model, those are:

  • Shrinkage: Expected percentage of time that a server is not available, for example, due to breaks, scheduled training, etc.
  • Occupancy: Percentage of time that a resource is handling a transaction
  • Service level: Percentage of transactions that arrives at a resource before a target ASA

The way as Erlang C find the number of resources in this system is by finding the probability that a transaction waits in queue, opposed to immediately being attended, it takes a target ASA and service level and uses the others variables as the system parameters, if you want to know more about the details of Erlang formulation, you can see others resources at the end of the article.

2. Python Example

As an example, we will find the number of agents needed in a call center to handle incoming traffic of calls.

Under the given convention, the resources would be the agent's stations, and the transactions would be the calls under this scenario.

Let's assume that in a time interval of 30 minutes, there is an average of 100 incoming calls, the AHT is 3 minutes, and the expected shrinkage is 30%.

As the call center administrators, we want the average time that a transaction waits in the queue to be 20 seconds and achieve a service level of 80%. We also want to ensure that the maximum occupancy of the agents is not greater than 85%.

To solve this problem, we will use Pyworkforce, a python package for workforce management, schedule, and optimization problems, so let's install it. Using a virtual env is advised.

pip install pyworkforce 

The use of this package is very straightforward; we import ErlangC and initialize the class with the given parameters, then we use the method "required_positions" to find the minimum number of resources to handle the transactions. Take into account that the class expects all the time variables to be in minutes:

The output of this code should look like this:

What this dictionary gives us is:

raw_positions: Number of positions found assuming shrinkage = 0

positions: Number of positions found taking the shrinkage provided by the user

service_level: The expected percentage of transactions that don't wait in the queue longer than the target ASA

occupancy: The expected occupancy that the system is going to have

waiting_probability: The probability that a transaction waits in queue

Note: The example modeled the system in a time interval of 30 minutes. The Erlan C assumptions may apply; if you want to extend the time interval, you may use the Erlang C several times with the parameters of each interval.

3. Running multiples Erlang C

If you want to try different parameters simultaneously, pyworkforce comes with a MultiErlangC class, which allows you to define a set of parameters to iterate over.

First, create a grid of parameters; it must be a dict, and each parameters options must be in an iterable, as a list.

Then MultiErlangC is going to use the ErlangC method with all possible combinations of the parameters provided.

For example, if the grid has three options of transactions values and two shrinkage options, there will be six different models.

If you have a vast grid, you can also use the parameter "n_jobs" to control the concurrently running jobs, "-1" means using all the available CPUs in the computer.

For this example, lets only try three different options of service levels:

The output is a list of each scenario with the same results as the individual Erlang C method:

If you like the output in a tabular format, you can use pandas, for example:

Tabular MultiErlangC. Image by the author.

4. Final Notes:

Pyworkforce is a package to make more accessible the workforce management optimization problem; there are other subproblems besides sizing, such as shift scheduling and rostering. To see more on this, you can check the project on Github from which I'm the author. Any suggestions or contribution to the package is very welcome: https://github.com/rodrigo-arenas/pyworkforce

5. References

[1] Pyworkforce package: https://pypi.org/project/pyworkforce/

[2] Erlang C formula: https://en.wikipedia.org/wiki/Erlang_(unit)

--

--

Data Scientist and open-source contributor working on machine learning, and optimization; for all my projects, check: https://rodrigo-arenas.github.io/portfolio