13  経済的発注量

経済的発注量(EOQ: Economic Order Quantity)モデルは,最も基本的な在庫管理モデルの一つである.Harris (1990) がこのモデルを最初に提案した.

EOQモデルは,単位時間あたりの需要量は決定論的で,一定であると仮定する.すなわち,需要量は事前に分かっており,時間とともに変化しない.単位時間あたりの需要量は需要率(demand rate)と呼ばれ,記号 \(d\) で表される.リードタイムは0とし,発注から納品までの時間はないと仮定する.一回の発注量を \(Q\) とし,一定であるとする.欠品は許せないとする.全ての需要は満されなければならない.また,EOQモデルでは,在庫量は連続的に観測され,いつでも発注が可能であるとする.

在庫に関わる費用は,1回あたりの発注費用 \(K\),単位時間あたりの1単位の保管費用 \(h\) と,購入単価 \(c\) がある.

EOQモデルの最適解は次の二つの性質を持つ(Snyder と Shen 2019)

  1. Zero-inventory ordering (ZIO). 在庫量が0のときに発注を行う.リードタイムは0であるため,在庫量が0でないときに発注すると,保管費用が発生する.
  2. Constant order sizes. 発注量は一定である.需要率 \(d\) が一定であり,在庫量が0のときに発注を行うため,最適発注量も一定である.

以上の性質から,在庫量の時間的変化は下図のようになる.

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

# Parameters
d = 250  # Demand rate
Q = 500  # Order quantity
T = Q / d  # Cycle length
t = np.linspace(0, 3 * T, 1000)  # Time from 0 to 3 cycles

# Inventory level over time
inventory = np.maximum(0, Q - (d * t) % Q)
inventory[0] = 0

# Plotting the inventory level
plt.plot(t, inventory, label="Inventory Level", color="black", linewidth=2)
plt.xlabel("Time")
plt.ylabel("Inventory Level")
plt.axhline(0, color="gray", linewidth=1)
plt.ylim(bottom=0, top=Q + 100)
plt.tight_layout()
plt.show()

発注の間隔をサイクル(cycle)と呼び,サイクル期間は

\[ T = \frac{Q}{d} \]

で与えられる.

例 13.1 A社は,毎月250個の需要がある商品を取り扱っている.一回の発注量は500個とし,サイクル期間は

\[ T = \frac{500}{250} = 2 \text{ヶ月} \]

となる.

13.1 記号

記号 意味
\(d\) 単位時間あたりの需要量
\(K\) 1回あたりの発注費用
\(h\) 単位時間あたりの1単位の保管費用
\(c\) 購入単価
\(Q\) 発注量
\(T\) サイクル期間
\(g(Q)\) 平均コスト

13.2 コスト関数

ここでは,1サイクルあたりのコストを考える.

発注費用:発注は1回だけ行うため,発注費用は \(K\) である.

購入費用\(Q\) 個の商品を単価 \(c\) で購入するため,購入費用は \(cQ\) である.

保管費用:サイクル期間 \(T\)\(\frac{Q}{d}\) であるため,1サイクルあたりの保管費用は

\[ \frac{TQ}{2} h = \frac{hQ^2}{2d} \]

となる.

以上より,1サイクルあたりのコストは次のように表される.

\[ K + cQ + \frac{hQ^2}{2d} \]

平均コストは,これをサイクル期間 \(T\) で割ったものとして定義される.したがって,平均コスト \(g(Q)\) は次のように表される.

\[\begin{align*} g(Q) &= \frac{1}{T} \left( K + cQ + \frac{hQ^2}{2d} \right) \\ &= \frac{d}{Q} \left( K + cQ + \frac{hQ^2}{2d} \right) \\ &= \frac{Kd}{Q} + c d + \frac{hQ}{2} \end{align*}\]

以上より,平均コストは発注量 \(Q\) の関数として次のように表される.

\[ g(Q) = \frac{Kd}{Q} + cd + \frac{hQ}{2} \]

13.3 最適発注量

EOQモデルの目的は,平均コスト \(g(Q)\) を最小化する発注量 \(Q\) を求めることである.

平均コストの導関数 \(g'(Q)\) が 0 となる点を求めることで,最適発注量 \(Q^*\) を求めることができる.

\[ g'(Q) = -\frac{Kd}{Q^2} + \frac{h}{2} = 0 \]

これを解くと,最適発注量

\[ Q^* = \sqrt{\frac{2Kd}{h}} \]

を得る.これをEOQ公式(EOQ formula)と呼ぶ.\(Q^*\) を経済的発注量と呼ぶ(経済的は最適という意味である).

二階導関数 \(g''(Q)\) を求めて,最適発注量が最小値を与えることを確認する.

\[ g''(Q) = \frac{2Kd}{Q^3} > 0 \]

\(g''(Q) > 0\) であるため,\(Q^*\) は最小値を与える.

最適発注量 \(Q^*\) を次の定理にまとめる.

定理 13.1 EOQモデルにおいて,最適発注量 \(Q^*\)\[ Q^* = \sqrt{\frac{2Kd}{h}} \tag{13.1}\]

で与えられる.

\(Q^*\) を用いて,最適なサイクル期間 \(T^*\) を求めることができる.

\[ T^* = \frac{Q^*}{d} = \sqrt{\frac{2K}{hd}} \tag{13.2}\]

式 13.1式 13.2 から,以下の性質がわかる.

  1. \(h\) の増加に伴い,\(Q^*\) は減少する.保管費用が高い場合は,少量で高い頻度で発注することが望ましい.
  2. \(K\) の増加に伴い,\(Q^*\) は増加する.発注費用が高い場合は,多量で低い頻度で発注することが望ましい.
  3. \(d\) の増加に伴い,\(Q^*\) は増加する.
  4. \(c\)\(Q^*\) に影響しない.購入単価は最適発注量に影響しない.

次の図は,購入単価を \(c = 0\) とするとき,平均コスト \(g(Q)\),発注コスト \(\frac{Kd}{Q}\),保管コスト \(\frac{hQ}{2}\) のグラフを示す.

コード
# Parameters
K = 40  # Order cost
h = 10  # Holding cost
d = 5  # Demand rate
Q = np.linspace(1, 40, 400)  # Order quantity from 1 to 40

# Cost calculations
order_cost = K * d / Q
holding_cost = (h * Q) / 2
average_cost = order_cost + holding_cost
optimal_Q = np.sqrt(2 * K * d / h)

# Plotting the costs
plt.plot(Q, order_cost, label=r"$Kd/Q$", color="blue")
plt.plot(Q, holding_cost, label=r"$hQ/2$", color="orange")
plt.plot(Q, average_cost, label=r"$g(Q)$", color="green", linewidth=2)
plt.axvline(optimal_Q, color="red", linestyle="--", label=r"$Q^*$")
plt.xlabel("Order Quantity Q")
plt.ylabel("Cost")
plt.ylim(bottom=0)
plt.legend()
plt.tight_layout()
plt.show()

平均コストが最小となる発注量 \(Q^*\) は,発注コストと保管コストの交差点である.すなわち,発注コストと保管コストを等しくする発注量は最適な発注量 \(Q^*\) である.この性質は以下の式からわかる.

\[ \frac{Kd}{Q^*} = \frac{hQ^*}{2} \Longrightarrow Q^* = \sqrt{\frac{2Kd}{h}} \]

また,この図からもわかるように,\(Q\) の増加に伴い,平均発注コストは減少し,平均保管コストは増加する.逆もまた然りである.

例 13.2 ある電気量販店では,毎月250台のPCが販売されている.発注費用は5000円,保管費用は1台あたり月150円,購入単価は10万円とする.このとき,最適発注量 \(Q^*\) は次のように求められる.

\[ Q^* = \sqrt{\frac{2 \cdot 5000 \cdot 250}{150}} \]

Excel では,下記のように計算できる.

=SQRT(2 * 5000 * 250 / 150)

13.4 アルゴリズムと実装

\begin{algorithm} \caption{Calculate optimal order quantity $Q^*$ using EOQ formula} \begin{algorithmic} \Procedure{EOQ}{$K, d, h$} \State $Q^* \gets \sqrt{2Kd/h}$ \State \textbf{return} $Q^*$ \EndProcedure \end{algorithmic} \end{algorithm}

Python では,次のようにeoq(K, d, h) 関数を定義し,最適発注量を計算できる.

def eoq(K, d, h):
    """
    Calculate the Economic Order Quantity (EOQ).

    Parameters:
    K (float): Order cost
    d (float): Demand rate
    h (float): Holding cost

    Returns:
    float: Optimal order quantity Q*
    """
    return np.sqrt(2 * K * d / h)


if __name__ == "__main__":
    K = 5000  # Order cost
    d = 250  # Demand rate (units per month)
    h = 150  # Holding cost (per unit per month)

    Q_star = eoq(K, d, h)
    T_star = Q_star / d
    print(f"Optimal Order Quantity (Q*): {Q_star:.2f}")
    print(f"Optimal Cycle Time (T*): {T_star:.2f}")
Optimal Order Quantity (Q*): 129.10
Optimal Cycle Time (T*): 0.52

PCの場合は,注文量が整数である必要があるため,\(g(129)\)\(g(130)\) を比較して最適発注量を決定する.

13.5 リードタイム*

EOQ モデルでは,リードタイムは0と仮定している.リードタイムが \(L > 0\) の場合も,最適発注量 \(Q^*\) も変換せず,\(L\) 期間前に \(Q^*\) を発注すればよい.

ここでは,\(r\) を発注点(reorder point)とする.在庫量が \(r\) になったときに発注を行う.リードタイム \(L\) の間に需要が \(dL\) 個あるため,発注点は次のように表される.

\[ r = dL \]

例 13.3 上の例で,リードタイムが一週間とし,一か月を4週間とすると,リードタイムは \(L = 1/4\) となる.したがって,発注点は次のように求められる.

\[ r = dL = 250 \times \frac{1}{4} = 62.5 \]

PCの在庫量が63台になったときに発注を行う.

13.6 他のEOQモデル*

  • バックオーダーを考慮したEOQモデル
  • 数量割引(quantity discount)を考慮したEOQモデル
    • 総量割引(all-units discount)
    • 増分割引(incremental discount)

13.7 文献案内

オペレーションズ・リサーチに関する教科書の多くは,EOQモデルを取り扱っている.モデルの分類から,「deterministic continuous-review inventory models」などの章で説明されていることが多い.

リードタイムを考慮したEOQモデルについては,Snyder と Shen (2019) で説明されている.

数量割引を考慮したEOQモデルについては,Snyder と Shen (2019)Camm ほか (2022) で説明されている.

バックオーダーを考慮したEOQモデルについては,Snyder と Shen (2019)Camm ほか (2022)Hillier と Lieberman (2025) で説明されている.

13.8 練習問題

練習 13.1 (EOQ for Vaccines) ある病院では,毎月300本のワクチンを使用している.ワクチンの製造業者に発注するたびに,固定費用として100ドルがかかる.ワクチン1本あたりの保管費用は,年間3ドルである.EOQモデルを用いて,次の問いに答えよ.

  1. 最適な発注量 \(Q^*\) を求めよ.
  2. 固定費用が減少した場合,最適発注量はどのように変化するか説明せよ.

練習 13.2 EOQモデルに基づき,次の各条件の変化が最適発注量 \(Q^*\) にどのような影響を与えるかを説明せよ.

  1. 発注費用が2倍になった場合.
  2. 保管費用が0.25倍になった場合.
  3. 需要率が4倍になった場合

練習 13.3 (EOQ for Steel) ある工場は,鋼材を毎日16トン消費し,年間250日稼働している.鋼材の購入単価は1トンあたり1100ドル,1回の発注にかかる固定費は5500ドル,保管費は鋼材1トンあたり年間は275ドルである.EOQモデルを用いて,次の問いに答えよ.

  1. 最適な発注量を求めよ.
  2. 最適なサイクル期間を求めよ.
  3. 年間の平均費用を求めよ.

練習 13.4 (EOQ for Smartphones) ある家電量販店では,あるスマートフォンを毎週50台販売している.店舗はスマートフォンを1台あたりメーカーに10万円で購入している.毎回の発注には発注処理や配送などで5000円の固定費がかかる.また,スマートフォン1台あたりの保管費用は1週間で100円である.EOQモデルを用いて,次の問いに答えよ.

  1. 最適な発注量を求めよ.
  2. 最適なサイクル期間を求めよ.

解答 13.1. 需要率は \(d = 50\) で,発注費用は \(K = 5000\),保管費用は \(h = 100\) である.

経済的発注量 \(Q^*\)\[ Q^* = \sqrt{\frac{2Kd}{h}} = \sqrt{\frac{2 \cdot 5000 \cdot 50}{100}} \approx 70.71 \text{ 台} \] となる.スマートフォンの場合は,注文量が整数である必要があるため,\(g(70)\)\(g(71)\) を比較して最適発注量を決定する.

\[ g(70) = \frac{5000 \cdot 50}{70} + 100 \cdot 70 / 2 \approx 7071.43 \] \[ g(71) = \frac{5000 \cdot 50}{71} + 100 \cdot 71 / 2 \approx 7071.13 \] \(g(71) < g(70)\) であるため,最適発注量は \(Q^* = 71\) 台となる.

サイクル期間 \(T^*\)\[ T^* = \frac{Q^*}{d} = \frac{71}{50} = 1.42 \text{ 週間} \] となる.

コード
import numpy as np

K = 5000  # Order cost
d = 50  # Demand rate (units per week)
h = 100  # Holding cost (per unit per week)
Q_star = np.sqrt(2 * K * d / h)


# Since order quantity must be an integer, compare g(70) and g(71)
def g(Q):
    return (K * d / Q) + (h * Q / 2)


g_70 = g(70)
g_71 = g(71)
optimal_Q = 70 if g_70 < g_71 else 71
T_star = optimal_Q / d
print(f"Optimal Order Quantity (Q*): {optimal_Q} units")
print(f"Optimal Cycle Time (T*): {T_star:.2f} weeks")
Optimal Order Quantity (Q*): 71 units
Optimal Cycle Time (T*): 1.42 weeks