• No results found

The optimal inventory levels of the SKUs are calculated by means of Marginal Analysis (”Bang for Buck”). This section describes the greedy algorithm as described by Basten & Van Houtum (2014) and Wong et al (2007). Although the researchers apply the solution procedure to a two-echelon inventory model, the greedy heuristic can easily be applied to the three-echelon network (Basten & van Houtum, 2014). This has already been done by Ruan et al.(2012) and Lu (2012).

In the greedy procedure, stock units are added in an iterative way. During each iteration an improvement ratio is calculated. The unit of stock is added to the part and location with the highest improvement ratio. This is repeated until the target objective is met. The procedure is described in more detail below.

Let ei,n be an |I| × |N | matrix and S the base stock matrix, consisting of all current Sin with the same dimensions. In matrix ei,n a 1 is defined for SKU i ∈ I and location n ∈ N and a zero at all other positions.

For the greedy algorithm to obtain a feasible solution it is important that the fill rate of a part is increasing on its whole domain and concave. According to Basten & Houtum, this is the case if [Sin≥ maxdλinTin− 1e, 0]. Therefore, all base stock levels are set to this lower bound.

Then for each solution S, the following is calculated X

n∈N

objn − βn(S)+

(4.29)

During each iteration the following is calculated:

∆βin= X

n∈N

[βnobj− βn(S)]+− [βnobj− βn(S + ei,n)]+

(4.30)

Finally, the ratio Γin= ∆βin/chi is calculated and the SKU with the highest ratio is increased by one unit. This is repeated until the target objective is met.

Greedy Algorithm by Basten & Van Houtum (2014) Step 1. Sin:= max[dλinTin− 1e, 0] for all i ∈ I, n ∈ N

To illustrate the optimization method consider the following example: There are two warehouses and two SKUs. We first construct a matrix with dimensions 2 × 2. The cells in the matrix stand for the inventory levels, e.g. S12 is the inventory level for SKU 1 in warehouse 2. See figure 4.2. The target objective is to achieve an aggregate fill rate of 95% for warehouse 1 (β1obj = 0.95) and a 95% fill rate for warehouse 2 (β2obj= 0.95). The price of SKU 1 is$2 and of SKU 2 is $3. Suppose the base stock levels are as given in figure 4.3:

step 1 The aggregate fill rate per warehouse is calculated by assuming the base stock levels of figure 4.3. This aggregate fill rate per warehouse is denoted by β1 for warehouse 1 and β2 for warehouse 2.

Suppose that the calculated fill rates per warehouse are β1= 0.4 & β2= 0.5 step 2 Now calculate the following:

S = S

11

S

12

step 3 For each combination of SKU & warehouse we add 1 SKU and calculate both the aggregate fill rate and the sum of the difference between the objective fill rate and the fill rate, precisely as was done in step 1 and 2.

We will illustrate this step beginning with the addition of 1 SKU 1 for warehouse 1, leading to the matrix in figure 4.4 (compare with figure 4.3):

S = S

11

+ 1 S

12

The aggregate fill rate is calculated by assuming that the base stock levels are as given in figure 4.4.

Suppose the calculated fill rates are β1= 0.6 & β2= 0.5.

Then the sum of the difference between the objective fill rate and the calculated fill rate is obtained by:

1obj− β1) + (β2obj− β2) = (0.95 − 0.6) + (0.95 − 0.5) = 0.8..

Next, we return to the situation as in figure 4.3 and add 1 SKU 1 to warehouse 2. Leading to the following matrix:

The aggregate fill rate is calculated by assuming that the base stock levels are as given in figure 4.5.

Suppose the calculated fill rates are β1= 0.4 & β2= 0.8.

Again, the difference between the objective fill rate and calculated fill rate is calculated: (βobj1 − β1) + (β2obj− β2) = (0.95 − 0.4) + (0.95 − 0.8) =0.7.

This is also repeated for the other SKU-warehouse combinations, e.g. one SKU 2 is added to warehouse 1 and one SKU 2 is added to warehouse 2. Suppose that the difference between the objective fill rate and calculated fill rate when adding 1 SKU 2 to warehouse 1 is0.6and when adding 1 SKU 2 to warehouse 2 is0.9.

step 4 ∆βin (equation 4.30) is calculated for every SKU i and warehouse N. The colors indicate the correspondence to the calculations in step 2 and 3.

∆βin= X

∆β22=1−0.9= 0.1

step 5 Γinis calculated for every combination of SKU i and warehouse N:

Γin= ∆βin/chi, where ∆βinwas calculated in step 4.

Γ11= 0.2/2 = 0.10 Γ12= 0.3/2 = 0.15 Γ21= 0.4/3 = 0.13 Γ22= 0.1/3 = 0.03

step 6 The largest improvement ratio is 0.15. Therefore we add SKU 1 to warehouse 2, and end up with the base stock levels as depicted in figure 4.7

S = 1

3

2 3



Figure 4.6: Base stock matrix

These steps are repeated until the aggregate fill rates for every warehouse exceed their target objectives.

5 Case study

The model described in chapter 4 is applied to one product family, namely XYZ. As described earlier, the stocking strategy of the XYZ tools differs from the stocking strategy of the legacy tools. First, the demand rate for XYZ parts is very low and second, compared to the legacy tools the installed base of XYZ is small.

Because of the low demand rate, the spare part inventory system of XYZ is characterized by a two-echelon inventory system, instead of a three-two-echelon inventory system. In addition, parts sent to the inbetween hubs originate from one central warehouse and not from two (as is the case with the other product families). Figure 5.1 depicts the structure.

Figure 5.1: Two-echelon spare part inventory system for XYZ

Parts for the XYZ tools are stocked in several warehouses: EU, Israel, Hillsboro, Japan and Taiwan.

Some parts are also stocked in other small warehouses in the Asian-Pacific region. The XYZ family consists of 9 product series, however only for 5 product series parts are stocked. In the EU region (EU and Israel), all Taipan parts are stocked in Israel and all other parts are stocked in EU. In the APR region all Elite parts are stocked in Japan, and the other parts are stocked in Taiwan. Because of this structure, it is possible to simplify the echelon structure: EU and Israel are seen as one warehouse and all warehouses in the APR region are also seen as one warehouse. The structure is visualized in Figure 5.1. North America is the central warehouse. This warehouse captures all demand. In addition, two inbetween hubs, EU and APR, are constructed. The inbetween hubs capture the demand of their respective regions. It is important to note that a distinction is made between where the parts are stocked and where the demand streams originate from. In addition to the warehouses where the parts are stocked, other warehouses exist. These warehouses (such as Belfast and Singapore) do not stock parts for XYZ, they do however receive demand for XYZ.

5.1 Implementation in Python

The model described in the previous chapter has been incorporated in Python. In this section, the structure of the code will be discussed. In line with section 4.3 and 4.5 it consists of two parts: evaluation and optimization.

5.1.1 Evaluation

In the evaluation procedure the fill rates per warehouse, total inventory costs, expected inventory and expected backorders are calculated, given a specific base stock allocation, e.g. what is the fill rate of warehouse Y if we allocate 1 item X to warehouse Y. For the notation we refer to table 4.1.

Figure 5.2: Evaluation procedure as implemented in Python

Figure 5.2 shows the most important functions in the program and how they interact. The program can be divided in two blocks: one block (red) where the probability distributions of the inventory and backorders are calculated and another block (yellow) that uses these distributions to calculate the fill rates.

The program starts with base stock level matrix start S. Based on this matrix and the other input parameters, the expected inventory, expected backorders, total inventory costs, pipelinestock (note that pipelinestock is equal to demand accumulated during lead time in steady state) and the fill rates are calculated. The functions are fairly easy to understand, e.g. function inventory warehouse cw calculates the probability that warehouse Y has inventory X. These probabilities are used to calculate the expected backorder and inventory levels, which are subsequently used to calculate the costs.

The yellow block uses the probability distributions from the red block to calculate the fill rates. The functions fill rate cw, fill rate bh and fill rate lw calculate the fill rate per part per warehouse. These fill rates are used to calculate the aggregate fill rate per warehouse. Two functions are created to calculate the aggregate fill rate per warehouse; fill rates and fill rates p1.

Remember from equation 4.15 that the fill rate for every part is independent of the fill rates of the other parts. In addition, the fill rate of a certain warehouse depends on the stock levels of that warehouse and it’s parent warehouse (see equations 4.12 and 4.13). Therefore, instead of recalculating the fill rates of all the parts for all the warehouses all over again during every iteration, function fill rates p1 is created.

fill rates is only used at the start of the run and at the end of every iteration(when one part has been

allocated). fill rates p1 receives the part fill rates from fill rates and only changes the part fill rates of the warehouses for the part that is added.

Finally, the aggregate fill rate for every warehouse is calculated with the input from fill rates p1. Ag-gregate fill rate refers to the sum of the demand weighted average of every part in the warehouse (see equation 4.15).

5.1.2 Optimization

In the optimization procedure, the optimal base stock levels and reorder points are calculated. Figure 5.3 shows the most important functions used in the program.

As explained in section 4.5, stock units are added in an iterative way. During each iteration, one item is alternately added for every warehouse-item combination, i.e. there are two warehouses A and B and two parts Y and Z. At warehouse A, stock for Y is increased by 1, aggregate fill rates are calculated. Then, stock for Y is decreased by one again and stock for Z is increased by one, after which the aggregate fill rates are calculated. When all parts in warehouse A have been increased and decreased by one, the algorithm continues in the same way for warehouse B. Two functions are created for this; function greedy, which is input for function fill rates and greedy p1, which is input for function fill rates p1. Both functions add one item to every warehouse. Function greedy is used at the start of the run and at the end of every iteration(when one part has been allocated) and function greedy p1 in all other cases.

Next, the fill rates resulting from these base stock levels are used as input for function delta fill rate. In this function formula 4.13 from section 4.5 is implemented.

Finally, the ∆βin resulting from delta fill rate is used as input in gamma func. In gamma func the improvement ratio is calculated for every warehouse-item combination and the decision is made to which warehouse the item should be allocated.

Figure 5.3: Optimization procedure as implemented in Python