15  安全在庫

15.1 学習目標

  • 需要が確率的な場合の (r, Q) 方策を理解する.
  • リードタイム期間中の需要が従う分布を求めることができる.
  • サービスレベルから,安全在庫と発注点を求めることができる.

15.2 問題設定

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

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

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

例 15.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="#16212d", linewidth=2)
plt.fill_between(
    t, inventory_min, inventory_max, color="#5b6b7c", alpha=0.35, label="Demand Range"
)

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


plt.xlim(0, 2)


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

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

15.3 近似解法

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

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

15.3.1 発注量 Q

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

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

例 15.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

15.3.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) に従う.

例 15.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 などを用いて求めることができる.

例 15.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% である.

例 15.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

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

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

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

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

15.5 まとめ

  • 需要 D が確率的で,リードタイムが L > 0 の場合,(r, Q) 方策のパラメータを近似的に決める.
  • 発注量は,平均需要 \mu をEOQモデルの需要率とみなし,Q = \sqrt{2K\mu/h} で近似する.
  • 正規分布の再生性より,リードタイム期間中の需要は D_L \sim N(\mu L, \sigma^2 L) に従う.すなわち,\mu_L = \mu L\sigma_L = \sigma \sqrt{L} である.
  • サービスレベルを \alpha とすると,安全在庫は s = \Phi^{-1}(\alpha)\, \sigma_L,発注点は r = \mu_L + s で与えられる.
  • サービスレベルを高くするほど \Phi^{-1}(\alpha) は大きくなり,必要な安全在庫も増える.

15.6 練習問題

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

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

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

解答 15.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