Optimising warehouse distribution logistics

December 4, 2019

Lack of knowledge of optimisation techniques can be a large burden, especially in logistics. Companies are often ignorant that they can do better, so miss out on saving time, money and effort. A friend of mine has been working as a logistic manager at a large international distribution centre, and described some of the work he was doing. It turns out that a significant amount of work that the company was doing could be automated with mathematical optimisation.


Data for a dummy problem: Input Data

3 output files: Pre-processed dataShipping scheduleSchedule summary

The code developed for this problem can be found here.

The problem

My friend was working at a distribution centre attached to a factory. The various products made at the factory would have to be tested (each with different testing durations) then shipped out to the various markets around the world. Products are made in various quantities at different times during the month, and there is previous excess product from previous months that can be shipped. Part of my friend’s job was to make sure that the products were getting out in the most efficient way possible using the 25 and 60 m^3 containers available with a 4 week planning horizon. Each market would be allocated the minimal amount of containers determined by the products that were sent to them. E.g. a market that required 140 m^3 would be allocated one 25 m^3 and two 60 m^3 containers. Further, the workers in the warehouse could pack a maximum of 5 containers each day. The scale for our dummy problem is 22 products and 14 markets, with 46 individual orders from those markets (e.g. France orders 50 units of product 3 is an order). All of a given product is not necessarily created in one go.

Really this boils down simply to the problem: We have products being made at various times that need to be tested then shipped to various international markets in the most efficient way possible.

It turns out that the company was getting people to solve this problem manually for every planning cycle, every 4 weeks. Not only would this take hours to do, but it would also not be optimal. It’s also important to note that decisions for the production of products and allocation of containers is done independently, whereas considering them together would allow for much more time and money saving by optimising the entire supply line.

Mathematical model

In order to automate this process, we’ll need to model the problem and then solve for the optimal solution. Once we do that, it’s a matter of adding it to the data pipeline so the optimal solution will pop out automatically. This problem very naturally lends itself to modelling it as an ILP (integer linear program) — the variables are integers, we pick a linear objective function, and the constraints are linear equations and inequalities as we will see.

The parameters

The first thing we have to do is to define the parameters as set out in the problem. There are all the things we are given to start off with.

  • $P$ = {products}
  • $M$ = {markets}
  • $T$ = {1,2,$\dots$,28}
  • $C$ = {types of containers}

  • $L$ = maximum containers that can be sent each day

  • $d_{ij}$ = demand of product $i\in P$ at market $j\in M$

  • $s_{it}$ = new supply of product $i\in P$ at day $t\in T$

  • $c_{jk}$ = number of type $k\in C$ containers allocated to market $j\in M$

  • $a_k$ = capacity of container $k\in C$

  • $v_i$ = volume of 1 unit of product $i\in P$

The decision variables

We want to calculate the best decision to make, which will take the form as the values of some variables. We want to know when to send containers to each market, and what products that go into those containers.

  • $x_{jtk}$ = the number of containers of type $k\in C$ sent to market $j\in M$ on day $t\in T$
  • $z_{ijt}$ = the number of units of product $i\in P$ sent to market $j\in M$ on day $t\in T$

Although it is not a decision, it is useful to have a variable that tells us how much stock we have in the warehouse at the end of each day.

  • $y_{it}$ = the number of units of product $i\in P$ stored at the end of day $t\in T$

This also lets us include a parameter for any amount of stock that we start off with (left over from previous months).

  • $y_{i0}$ = the number of units of product $i\in P$ at the start of the period

The objective function

We need some metric that we’re going to optimise for. Some way to measure what the ‘best’ or ‘most efficient’ solution is. Let’s interpret efficiency by saying that we want stock going out as quickly as possible. The faster we send out stock, the less we’ll have to store in the warehouse, so that’s what we’re going to use as our function.

We’ll be able to calculate how much stock we have at the end of each day, and then we can sum that up across all the days to give us an efficiency score. The less we have in total across all the days, the better the solution. In mathematical notation, this is $$\min \sum_{i\in P}\sum_{t\in T} y_{it}$$

However, it may be helpful to not minimise the amount of units of stock we store, but the volume of stock that we store. This is a simple modification. $$\min \sum_{i\in P}\sum_{t\in T}v_iy_{it}$$

A very similar modification can be made if we want to instead minimise the value of the items stored in the warehouse, if we know the value for each unit of product. It’s up to the warehouse manager to decide which particular function he wants to optimise.

The constraints

Here we transform the rules of the problem into algebraic statements. We think of the rules as geometric boundaries in space that we cannot cross. Once all the boundaries are established, we can find the optimal solution in those boundaries.

Firstly, we define the domains for each of the variables. We want the number of each type of container sent to a market on a given day $(x_{jtk})$, the number of units of each product stored at the end of each day $(y_{it})$, and the number of units of each product shipped to each market on a given day $(z_{ijt})$ to all be counting numbers. We don’t want them to be negative, and it doesn’t make sense to send half a container. \begin{align} x_{jtk} &\in \mathbb{N} && \forall j\in M,\ \forall t\in T,\ \forall k\in C\newline y_{it} &\in \mathbb{N} && \forall i\in P,\ \forall t\in T\newline z_{ijt} &\in \mathbb{N} && \forall i\in P,\ \forall j\in M,\ \forall t\in T \end{align}

We want to make sure the demand for each product at each market is met by the end of the 4 week period.

\begin{equation} \sum_{t\in T}z_{ijt} = d_{ij},\qquad \forall i\in P,\ \forall j\in M \end{equation}

We want the number of each type of container we allocate to each market to be sent. \begin{equation} \sum_{t\in T}x_{tjk} = c_{jk},\qquad \forall j\in M,\ \forall k\in C \end{equation}

The most amount of containers that can be sent in a day is the container limit.

\begin{equation} \sum_{j\in M}\sum_{k\in C}x_{jtk}\le L,\qquad \forall t\in T \end{equation}

We don’t want containers being sent on weekends, because we won’t have workers then. \begin{equation} \sum_{j\in M}\sum_{k\in C}x_{jtk} = 0,\qquad \forall t\in\text{{6,7,13,14,20,21,27,28}} \end{equation}

The amount of items we send to a market on a given day must fit in the containers that we send them.

\begin{equation} \sum_{i\in P}v_iz_{ijt}\le \sum{k\in C}a_k x_{jtk},\qquad \forall j\in M,\ \forall t\in T \end{equation}

Lastly, the amount of a product we can send on a given day is the total amount stored from the previous day with the addition of any new products that have finished their testing. Any that is not shipped must be stored at the end of that day.

\begin{equation} y_{it} = y_{it-1} + s_{it} - \sum_{j\in M}z_{ijt},\qquad \forall i\in P,\ \forall t\in T \end{equation}

Solving the model

After coding this up, non-industrial solvers on a basic computer can solve this problem in under 20 seconds. A huge boost to efficiency, time and money. Keep in mind that the solution found with these solvers is provably optimal. There is no finding a solution better than this based on the model.