1. Analytic Results for the Basestock Policy

In this section, we establish a set of formulas to compute performance measures for the single-item basestock inventory system of \cref{sec:single-item-invent}.1 Like this we do not have to simulate to see how performance depends on the order-up-to level \(S\).

We introduce some notation: The period demands \(\{D_{i}\}_{i=1}^{\infty}\) are assumed to be iid rvs2 Why did we not need to make this assumption earlier? ; for notational ease we take \(D_{i} = 0\) for \(i\leq 0\). Write

\begin{align*} D(i, j] &= \sum_{k=i+1}^{j} D_k, & D[i, j] &= D_{i} + D(i, j], & D[i, j) &= D[i, j] - D_{j}, \end{align*}

and likewise for \(Q(i, j]\) for the total outstanding reorders.

We assume that the lead time \(\leadtime\) is constant and a multiple of the period duration. Define \(F_X(x) = \P{\sum_{i=1}^{\leadtime} D_{i} \leq x}\); write \(X\sim F_X\) for the lead time demand, \(G_X = 1 -F_X\) for the survivor function, and \(f_{X}\) for the pmf. Clearly, \(\E X = \leadtime \E D\). Since the period demands are iid rvs, all rvs \(\{D[k-\leadtime, k)\}_{k=\leadtime+1}^{\infty}\) have the same distribution \(F_X\).

We use the recursions of \cref{sec:single-item-invent} to derive expressions for the long-run performance measures. The first step is to relate the outstanding orders to the demand.

Under a basestock policy with order-up-to level \(S\), \(Q(1, k] = D[1, k)\) for all periods \(k\geq 1\).

Proof

Using the recursions for the inventory position under the basestock policy repeatedly,

\begin{align*} \IP_k &= \IP_{k-1}'+ Q_k = \IP_{k-1} -D_{k-1}+ Q_k \\ &= \IP_{k-1} -D[k-1, k) + Q(k-1, k] \\ &= \IP_1 - D[1, k) + Q(1, k]. \end{align*}

The proof is finished by noting that \(\IP_{k} = S\) for all \(k\geq 1\).

We can use this lemma to express \(I_{k}\) in terms of \(S\) and the lead time demand.

Under a basestock policy, if \(\IL_{1} = S\) and there are no outstanding orders of period \(k \leq 1\), then for all periods \(k\geq 1\),

\begin{align*} \IL_k&= S - D[k-\leadtime, k), & \IL_k'&= \IL_{k} - D_{k} = S - D[k-\leadtime, k]. \end{align*}
Proof

Using the recursion for the inventory level and the assumptions,

\begin{align*} \IL_{k} &= \IL_{k-1} -D_{k-1}+ Q_{k-\leadtime} \\ &= \IL_{k-1}- D[k-1, k) + Q(k-\leadtime-1, k-\leadtime] \\ &= \IL_{1}- D[1, k) + Q(1-\leadtime, k-\leadtime] \\ &\stackrel1= S - D[1, k) + Q(1, k-\leadtime] \\ &\stackrel2= S - D[k-\leadtime, k); \end{align*}

1 uses the assumptions, 2 follows from the above lemma and \(D[k-\leadtime, k) = D[1, k) - D[1, k-l)\).

This next theorem, which allows us to define the inventory level as an rv \(\IL\), follows directly from the above lemmas.

Theorem 1. 

The rvs \(\{\IL_{k}\}_{k=\leadtime+1}^{\infty}\) are identically3 But not necessarily independent. distributed as the rv

\begin{equation*} \IL = S - X. \end{equation*}
Proof

As observed earlier, each rv \(D[k-\leadtime, k) \sim X\). As \(S\) is constant, the rvs \(I_{k} = S - D[k-\leadtime, k) \sim S - X\) for all \(k\geq \leadtime+1\).

Now that we have characterized the distribution of \(\IL\) in terms of the control parameter \(S\) and the lead-time demand \(X\), we can find expressions for the performance measures. First, for the ready rate,

\begin{equation} \label{eq:5} \alpha \stackrel1= \P{I'\geq 0} \stackrel2= \P{I - D \geq 0} \stackrel3= \P{S-X - D\geq 0} = \P{X+D\leq S}, \end{equation}

where 1 follows from the definition of \(\alpha\), 2 from \(I' = I- D\), 3 from \(I=S-X\). Second, for the fill rate, by taking expectations in \cref{eq:c24}, we obtain

\begin{equation}\label{eq:ic3} \beta = \frac{\E{\min\{D, I^{+}\}}}{\E D}. \end{equation}

For the third performance measure, the cycle service level, I have not yet tried to find a simple expression in terms of expectations.

The mean inventory level is

\begin{equation*} \E{\IL} = \E{S-X} = S - \E X = S - \leadtime\E D. \end{equation*}

Next, noting that \(I^+ - I^- = I\), the average on-hand inventory can be expressed in terms of the average backlog:

\begin{equation}\label{eq:27} \E{\IL^+} = \E{I} + \E{I^-} = S - \leadtime \E D + \E{I^-}. \end{equation}

From the definition of the backlog,

\begin{equation}\label{eq:ia22} \E{\IL^-} = \E{[-I]^{+}} = \E{[X-S]^{+}} = \sum_{k=0}^\infty (k- S)^+f(k). \end{equation}

This summation runs to \(\infty\) if the support of \(D\) is unbounded. For numerical purposes, we rewrite it as follows.

The average backlog is equal to

\begin{equation*} \E{\IL^-} = \leadtime \E D - \sum_{j=0}^{S-1} G_X(j). \end{equation*}
Proof

Since \(\sum_{j=0}^\infty \1{j< k} = k\), we find from \cref{eq:ia22}

\begin{align*} \sum_{k=S}^\infty (k-S) f(k) &= \sum_{k=S}^\infty\sum_{j=0}^\infty \1{j < k-S}\, f(k) = \sum_{j=0}^\infty \sum_{k=S}^\infty \1{k > j +S}\, f(k)\\ &= \sum_{j=0}^\infty G_X(j+S) = \sum_{j=0}^\infty G_X(j) - \sum_{j=0}^{S-1} G_X(j). \end{align*}

Since \(\sum_{i=0}^\infty G_X(i) = \leadtime \E D\), the claim follows.

Recall from \cref{th:5} that \(I\), hence \(I^{+ }\) and \(I^{-}\), are functions of the reorder level \(S\). Therefore, the average inventory cost \(c(S) = h \E{I^{+}} + b \E{I^-}\) is also a function of \(S\).

Here we illustrate the Lighthouse Company example of \cref{sec:single-item-invent}. With the RV class from \cref{sec:prob_arithmetic}, our code stays nearly in one-to-one correspondence with the mathematical definitions above.

from functools import cache
import numpy as np

import random_variable as rv
from functions import Plus, Min

from lighthouse_case import D, K, N, l, h, b

The basestock policy follows directly once we note that it suffices to specify the rv \(X\); the other rvs then follow from \(X\). Note that the performance measures depend on the control parameter \(S\).

class Basestock:
    """Implements KPIs for a basestock inventory system."""

    def __init__(self, D, l, h, b):
        self.D = D
        self.l = l
        self.h = h
        self.b = b
        self.X = sum(self.D for _ in range(l)) if l > 0 else rv.RV({0: 1})

    @cache
    def IP(self, S):
        return S

    @cache
    def IL(self, S):
        return self.IP(S) - self.X

    @cache
    def Imin(self, S):
        return rv.apply_function(lambda x: Min(x), self.IL(S))

    @cache
    def Iplus(self, S):
        return rv.apply_function(lambda x: Plus(x), self.IL(S))

    def cost(self, S):
        return self.b * self.Imin(S).mean() + self.h * self.Iplus(S).mean()

    def alpha(self, S):
        return (self.IL(S) - self.D).sf(-1)

    def beta(self, S):
        m = rv.compose_function(lambda x, y: min(x, y), self.D, self.Iplus(S))
        return m.mean() / self.D.mean()

Here are some tests to verify the implementation and the preceding algebra.

S = 5

base = Basestock(D, l, h, b)

theta = l * D.mean()
print(np.isclose(base.IL(S).mean(), S - theta))
print(
    np.isclose(
        base.Imin(S).mean(), theta - sum(base.X.sf(j) for j in range(0, S))
    )
)
print(np.isclose(base.alpha(S), (base.X + D).cdf(S)))
True
True
True

The following shows how to use the code. We see that, as a function of \(S\), the service levels increase, but the cost first decreases and then increases.4 High service levels do not come for free.

for S in range(5, 12):
    print(f"{S=}: {base.alpha(S)=:.2f}, {base.beta(S)=:.2f}, {base.cost(S)=:.2f}")
S=5: base.alpha(S)=0.34, base.beta(S)=0.33, base.cost(S)=15.84
S=6: base.alpha(S)=0.47, base.beta(S)=0.47, base.cost(S)=9.42
S=7: base.alpha(S)=0.60, base.beta(S)=0.61, base.cost(S)=5.65
S=8: base.alpha(S)=0.72, base.beta(S)=0.74, base.cost(S)=4.08
S=9: base.alpha(S)=0.82, base.beta(S)=0.84, base.cost(S)=3.54
S=10: base.alpha(S)=0.89, base.beta(S)=0.91, base.cost(S)=3.63
S=11: base.alpha(S)=0.94, base.beta(S)=0.95, base.cost(S)=4.30
TF 1:

In a basestock model, the ready rate is given by \(\alpha = \P{I - D \geq 0}\). Claim: The next code implements this correctly.

class Basestock:
    def __init__(self, D, L, h, b):
        self.D = D
        self.L = L
        self.h = h
        self.b = b
        self.X = sum(self.D for _ in range(self.L))

    def IL(self, S):
        return S - self.X

    def alpha(self, S):
        return (self.IL(S) - self.D).sf(0)
Solution
Did you actually try? Maybe see the ‘hints’ above!:
Solution, for real

False. It should be (self.IL(S) - self.D).sf(-1), so \(-1\) instead of \(0\).

TF 2:

Claim: In a basestock model with lead time demand \(X\), the backlog is given by \(\E{[S-X]^+}\).

Solution
Did you actually try? Maybe see the ‘hints’ above!:
Solution, for real

True.

Exercise 3:

Suppose \(l=0\). What values do \(X\), \(\E\IL\), \(\E{\IL^{+}}\) and \(\E{\IL^{-}}\) take?

Solution
Did you actually try? Maybe see the ‘hints’ above!:
Solution, for real

If \(\leadtime=0\), then \(X=0\), hence \(f_0 = \P{X=0} = 1\). Consequently, \(\E I = S\), and \(\E{\IL^{-}} = 0\) from \cref{eq:ia22}. Then from \cref{eq:27} it follows that \(\E{\IL^{+}} = S\).

Exercise 4:

Why does the definition of \(\beta\) follow from \cref{eq:c24}?

Solution
Did you actually try? Maybe see the ‘hints’ above!:
Solution, for real

\(D_{k}\) and \(I_{k}\) are independent, but \(D_{k}\) and \(I_{k}'\) not.

Exercise 5:

The cost function \(S \mapsto c(S)\) is convex and coercive.A function $f$ is coercive if $\lim_{x\to \pm \infty} f(x) = \infty$. Prove that there exists an order-up-to level \(S^{*}\) that minimizes the average cost.

Hint

Use the following properties for convex functions.

  1. \(f\) convex, \(\alpha\geq 0\) \(\implies\) \(\alpha f\) convex.
  2. \(f, g\) convex \(\implies\) \(f+g\) convex.
  3. \(f\) convex, \(R(x) = -x\) \(\implies\) \(f\circ R\) convex.
Solution
Did you actually try? Maybe see the ‘hints’ above!:
Solution, for real

Fix \(i\). The function \(S\to [S-i]^{+ }\) is convex. Since a weighted sum of convex functions is still convex, \(\sum_{i=0}^{\infty} f(i) [S-i]^{+}\) is also convex. But \(\sum_{i=0}^{\infty} f(i) [S-i]^{+} = \E{[S-X]^{+}} = \E{I^{+}}\), and therefore \(h\E{I^{+}}\) is a convex function of \(S\). Similarly, \(S\to [i-S]^{+}\) is convex, and therefore \(\E{I^{-}}\) is convex. Consequently, \(c(S)\), being the sum of two convex functions, is convex. As \(\E{I^{+}} \to \infty\) when \(S\to\infty\), and \(\E{I^{-}} \to \infty\) when \(S\to-\infty\), \(c(\cdot)\) attains a minimum.

Exercise 6:

For a nonnegative discrete rv \(X\), use indicator functions to prove:

  1. \(\E X = \sum_{k=0}^\infty G(k)\),
  2. \(\sum_{i=0}^\infty i G(i) = \E{X^2}/2 - \E{X}/2\).
Hint

For (1) write \(\sum_{k=0}^\infty G(k) = \sum_{k=0}^\infty \sum_{m=k+1}^\infty \P{X=m}\), reverse the summations. Then note that \(\sum_{k=0}^\infty \1{k \begin{equation*} \sum_{i=0}^\infty i G(i) = \sum_{n=0}^\infty \P{X=n} \sum_{i=0}^\infty i \1{n\geq i+1}, \end{equation*}

and reverse the summations.

Solution
Did you actually try? Maybe see the ‘hints’ above!:
Solution, for real

For (1): observe first that \(\sum_{k=0}^\infty \1{m>k} = m\), since \(\1{m>k}=1\) if \(kk} = 0\) if \(k\geq m\). With this,

\begin{align*} \sum_{k=0}^\infty G(k) &= \sum_{k=0}^\infty \P{X>k} = \sum_{k=0}^\infty \sum_{m=k+1}^\infty \P{X=m} \\ & = \sum_{k=0}^\infty \sum_{m=0}^\infty \1{m>k} \P{X=m} = \sum_{m=0}^\infty \sum_{k=0}^\infty \1{m>k} \P{X=m} \\ &= \sum_{m=0}^\infty m\P{X=m} = \E X. \end{align*}

Since all summands are nonnegative, interchanging the summations is valid.

For (2):

\begin{align*} \sum_{i=0}^\infty i G(i) &= \sum_{i=0}^\infty i \sum_{n=i+1}^\infty \P{X=n} = \sum_{n=0}^\infty \P{X=n} \sum_{i=0}^\infty i \1{n\geq i+1} \\ &= \sum_{n=0}^\infty \P{X=n} \sum_{i=0}^{n-1}i = \sum_{n=0}^\infty \P{X=n} \frac{(n-1)n}{2} \\ &= \sum_{n=0}^\infty \frac{n^2}{2} \P{X=n} - \frac{\E X}{2} = \frac{\E{X^2}}{2} - \frac{\E X}{2}. \end{align*}

CC BY-SA 4.0 This work is licensed by the University of Groningen under a Creative Commons Attribution-ShareAlike 4.0 International License.