14  安全在庫

需要 \(D\) がある確率分布に従うと仮定する.リードタイムを \(L > 0\) とし,既知の定数とする.発注費用を \(K\),単位あたりの保管費用を \(h\) とする.在庫量が連続的に観測され,いつでも発注が可能であるとする連続観測の場合を考える.

リードタイム \(L = 0\),需要 \(d\) が一定の場合,この問題は EOQ モデルに帰着する.在庫量が \(0\) のとき,発注量 \(Q^* = \sqrt{2K d / h}\) を発注すればよい.しかし,リードタイム \(L > 0\),需要 \(D\) が確率分布に従う場合,最適発注量を決定することは容易ではない.

\((r, Q)\) 方策が用いられるとする.在庫量が発注点 \(r\) 以下になったときに,発注量 \(Q\) を発注する.この場合,与えられたサービスレベルを満たすように,発注点 \(r\) と発注量 \(Q\) を決定することが目的である.

例 14.1 (思考実験) 毎日の需要 \(D\) が連続一様分布 \(U(200, 300)\) に従うと仮定する.毎日の平均需要は \(\mu = 250\) である.以下の問題を考えよ.

  1. 二日間の需要が従う分布を求めよ.
  2. 初期在庫量は \(500\) であるとき,二日間後に欠品が発生する確率を求めよ.
  3. 100% のサービスレベルを達成するために必要な初期在庫量を求めよ.

次の図は,在庫量の時間的変化を示す.灰色の領域は,需要の範囲を示す.赤い領域は,在庫量が0以下になったときの欠品を示す.黒い線は平均需要に基づく在庫量の変化を示す.

コード
import scipy.stats as stats
import numpy as np
import matplotlib.pyplot as plt

# Parameters
d_mean = 250  # Mean demand rate
d_max = 300  # Max demand rate
d_min = 200  # Min demand rate
Q = 500  # Order quantity
T = Q / d_mean  # Average cycle length

# Simulate over multiple cycles to show repeated pattern
n_cycles = 0.9999
t = np.linspace(0, n_cycles * T, 1000)

# Inventory levels: linear depletion over time
inventory_mean = Q - d_mean * (t % T)
inventory_mean[0] = 500
inventory_max = Q - d_max * (t % T)
inventory_min = Q - d_min * (t % T)

# Plotting
plt.plot(t, inventory_mean, label="Mean Demand", color="black", linewidth=2)
plt.fill_between(
    t, inventory_min, inventory_max, color="gray", alpha=0.5, label="Demand Range"
)

# Highlight when inventory drops below 0 (shortage)
plt.fill_between(
    t,
    inventory_max,
    0,
    where=(inventory_max < 0),
    color="red",
    alpha=0.3,
    label="Shortage",
)


plt.xlim(0, 2)


# Aesthetics
plt.axhline(0, color="gray", linewidth=1)
plt.xlabel("Time", fontsize=14)
plt.ylabel("Inventory Level", fontsize=14)
plt.tight_layout()
plt.show()

在庫量の時間的変化(需要が一様分布に従う場合)

14.1 近似解法

この問題の定式化および厳密解法は,ここでは説明しない.Snyder と Shen (2019) の「Fundamentals of Supply Chain Theory」などの文献を参照されたい.以下は \((r, Q)\) の近似解法を紹介する.

単位期間あたりの需要を \(D\) とし,\(D\) は正規分布 \(N(\mu, \sigma^2)\) に従うと仮定する.

14.1.1 発注量 \(Q\)

\(D\) の平均需要 \(\mu\) をEOQモデルの需要率とみなすと,発注量 \(Q\) の近似解は次のように求めることができる(Camm ほか 2022)

\[ Q = \sqrt{\frac{2K \mu}{h}} \]

例 14.2 単位期間あたりの需要 \(D\) が正規分布 \(N(100, 20^2)\) に従うと仮定する.発注費用 \(K = 200\),単位あたりの保管費用 \(h = 5\) のとき,EOQ 公式に基づいて発注量 \(Q\) を求めよ.

\[ Q = \sqrt{\frac{2K \mu}{h}} = \sqrt{\frac{2 \cdot 200 \cdot 100}{5}} \approx 89.44 \]

Python では,以下のように計算できる.

コード
import math

K = 200
h = 5
mu = 100
Q = math.sqrt((2 * K * mu) / h)
print(f"order quantity: {Q:.2f}")
order quantity: 89.44

14.1.2 発注点 \(r\)

リードタイム期間中に発生する需要は \(D_L \sim N(\mu_L, \sigma_L^2)\) とし,正規分布の再生性により,

\[ \mu_L = \mu L, \quad \sigma_L^2 = \sigma^2 L \]

になる.すなわち,リードタイム期間中の平均需要は \(\mu_L = \mu L\),標準偏差は \(\sigma_L = \sigma \sqrt{L}\) である.

ノート正規分布の再生性

\(X_1, X_2, \ldots, X_n\) が独立に同一の正規分布 \(N(\mu, \sigma^2)\) に従うならば,\(Y = X_1 + X_2 + \cdots + X_n\) は正規分布 \(N(n\mu, n\sigma^2)\) に従う.

例 14.3 単位期間あたりの需要 \(D\) が正規分布 \(N(100, 20^2)\) に従うと仮定する.リードタイム \(L = 4\) のとき,リードタイム期間中の平均需要 \(\mu_L\) と標準偏差 \(\sigma_L\) を求めよ.

\[ \mu_L = \mu L = 100 \cdot 4 = 400 \]

\[ \sigma_L = \sigma \sqrt{L} = 20 \sqrt{4} = 40 \]

これにより,リードタイム期間中の需要 \(D_L\) は正規分布 \(N(400, 40^2)\) に従うことがわかる.

発注点 \(r\) を決めるためには,サービスレベル(service level)を考える.ここでは,サービスレベルを,リードタイム期間中に需要を満たす確率と定義する.サービスレベルを \(\alpha\) とし,\(0 < \alpha < 1\) とする.

与えられたサービスレベル \(\alpha\) に対して,\(D_L\) が発注点 \(r\) 以下になる確率(欠品が発生しない確率,つまり,サービスレベル)が \(\alpha\) になるように発注点 \(r\) を決定する.

\[ \mathbb{P}(D_L \leq r) = \alpha \]

もし,発注点 \(r = \mu_L\) とすると,

\[ \mathbb{P}(D_L \leq \mu_L) = \mathbb{P}\left(\frac{D_L - \mu_L}{\sigma_L} \leq 0\right) = \Phi(0) = 0.5 \]

が得られる.すなわち,50% の確率で欠品が発生することになる.したがって,サービスレベル \(\alpha > 0.5\) の場合,発注点 \(r\) は平均需要 \(\mu_L\) より大きくなる必要がある.

発注点が平均需要を上回る部分,すなわち,\(r - \mu_L\)安全在庫(safety stock)と呼び,\(s\) と表す.

\[ s = r - \mu_L \]

この式を変形すると,発注点 \(r\) は次のように表される.

\[ r = \mu_L + s \]

従って,サービスレベル \(P(D_L \leq r) = \alpha\) は次のように表される.

\[ \mathbb{P}(D_L \leq \mu_L + s) = \alpha \]

与えられたサービスレベル \(\alpha\) に対して,安全在庫 \(s \geq 0\) を求める.

\[\begin{align} \mathbb{P}(D_L - \mu_L \leq s) &= \alpha \\ \mathbb{P}\left(\frac{D_L - \mu_L}{\sigma_L} \leq \frac{s}{\sigma_L}\right) &= \alpha \\ \Phi\left(\frac{s}{\sigma_L}\right) &= \alpha \\ \frac{s}{\sigma_L} &= \Phi^{-1}(\alpha) \\ s &= \sigma_L \Phi^{-1}(\alpha) \\ s &= \sigma \sqrt{L} \Phi^{-1}(\alpha) \end{align}\]

ここで,\(\Phi(\cdot)\) は標準正規分布の累積分布関数であり,\(\Phi^{-1}(\alpha)\) はその逆関数である.したがって,発注点 \(r\) は次のように表される.

\[ r = \mu_L + s = \mu L + \sigma \sqrt{L} \Phi^{-1}(\alpha) \]

\(\Phi^{-1}(\alpha)\) は標準正規分布表,Excel,Python などを用いて求めることができる.

例 14.4 単位期間あたりの需要 \(D\) が正規分布 \(N(100, 20^2)\) に従うと仮定する.リードタイム \(L = 4\),発注点 \(r = 500\) のとき,安全在庫 \(s\) とサービスレベル \(\alpha\) を求めよ.

リードタイム期間中の平均需要は \(\mu_L = 400\) である.したがって,安全在庫 \(s\) は次のように求められる. \[ s = r - \mu_L = 500 - 400 = 100 \]

サービスレベル \(\alpha\) は次のように求められる.

\[ \alpha = \mathbb{P}(D_L \leq r) = \Phi\left(\frac{r - \mu_L}{\sigma_L}\right) = \Phi\left(\frac{100}{40}\right) = \Phi(2.5) \approx 0.99379 \]

発注点 \(r = 500\) のとき,安全在庫 \(s\) は100,サービスレベル \(\alpha\) は約 99.379% である.

例 14.5 リードタイム \(L = 4\),平均需要 \(\mu = 100\),需要の標準偏差 \(\sigma = 20\),サービスレベル \(\alpha = 0.95\) のとき,発注点 \(r\) と安全在庫 \(s\) を求める.

リードタイム期間中の平均需要と標準偏差は次のように計算される.

\[\begin{align} \mu_L &= \mu L = 100 \cdot 4 = 400 \\ \sigma_L &= \sigma \sqrt{L} = 20 \sqrt{4} = 40 \\ \end{align}\]

標準正規分布表から \(\Phi^{-1}(0.95) \approx 1.64485\) を得る.これを用いて安全在庫 \(s\) と発注点 \(r\) を求める.

\[\begin{align} s &= \sigma_L \Phi^{-1}(0.95) \approx 40 \cdot 1.64485 \approx 65.79 \\ r &= \mu_L + s \approx 400 + 65.79 \approx 465.79 \end{align}\]

したがって,発注点 \(r\) は約465.79,必要な安全在庫 \(s\) は約65.79となる.

Python では,以下のように計算できる.

コード
from scipy.stats import norm

L = 4
mu = 100
sigma = 20
alpha = 0.95

mu_L = mu * L
sigma_L = sigma * (L ** 0.5)

s = sigma_L * norm.ppf(alpha)
r = mu_L + s

print(f"reorder point: {r:.2f},  safety stock: {s:.2f}")
reorder point: 465.79,  safety stock: 65.79

14.2 欠品費用を考慮する場合*

欠品費用を考慮する場合,バックオーダーを考慮した EOQ モデルを用いて,発注量 \(Q\) は次のように求めることができる(Hillier と Lieberman 2025)

\[ Q = \sqrt{\frac{2K \mu}{h}} \sqrt{\frac{p+h}{p}} \]

\(p\) は単位あたりの欠品費用である.

14.3 文献案内

14.4 練習問題

練習 14.1 (Safety Stock for USB Flash Drives) ある家電量販店では USB メモリを販売している.この商品の目標サービスレベルは 95% である.1 回の発注にかかる固定費用は 12 ドル,USB メモリの仕入れ単価は 1 個あたり 6 ドルである.また,1 個あたりの年間保管費用は 1.2 ドルとする.発注から納品までのリードタイムは 1 週間である.この店舗における 1 週間あたりの需要は,平均 154,標準偏差 25 の正規分布に従うと仮定する.以下の問いに答えよ.

  1. EOQ 公式を用いて,最適発注量の近似値を求めよ.
  2. 上記の最適発注量を用いる場合の発注点を求めよ.

練習 14.2 ある会社は,A商品を販売している.\((r, Q)\) 方策に基づいて在庫管理を行っている.毎日の需要 \(D\) は正規分布 \(N(150, 30^2)\) に従う.商品を発注するための固定費用は \(K = 300\),単位あたりの保管費用は \(h = 4\),購入単価は \(c = 20\) である.リードタイムは \(L = 4\) 日である.この会社は,90% のサービスレベルを目標としている.このとき,発注量 \(Q\),発注点 \(r\),必要な安全在庫 \(s\) を求めよ.

解答 14.1. 発注量 \(Q\) は次のように求められる.

\[ Q = \sqrt{\frac{2K \mu}{h}} = \sqrt{\frac{2 \cdot 300 \cdot 150}{4}} = 150 \]

リードタイム期間中の平均需要と標準偏差は次のように計算される.

\[ \mu_L = \mu L = 150 \cdot 4 = 600 \]

\[ \sigma_L = \sigma \sqrt{L} = 30 \sqrt{4} = 60 \]

標準正規分布表から \(\Phi^{-1}(0.9) \approx 1.28155\) を得る.これを用いて安全在庫 \(s\) と発注点 \(r\) を求める.

\[ s = \sigma_L \Phi^{-1}(0.9) \approx 60 \cdot 1.28155 \approx 76.89 \]

\[ r = \mu_L + s \approx 600 + 76.89 \approx 676.89 \]

したがって,発注量 \(Q\) は150,発注点 \(r\) は約676.89,必要な安全在庫 \(s\) は約76.89となる.

コード
import math
from scipy.stats import norm
K = 300
h = 4
mu = 150
sigma = 30
L = 4
alpha = 0.9
Q = math.sqrt((2 * K * mu) / h)
mu_L = mu * L
sigma_L = sigma * (L ** 0.5)
s = sigma_L * norm.ppf(alpha)
r = mu_L + s
print(f"order quantity: {Q:.2f}, reorder point: {r:.2f},  safety stock: {s:.2f}")
order quantity: 150.00, reorder point: 676.89,  safety stock: 76.89