🎓 レベル:応用 | 重要度:A(必須)
📎 前提:安全在庫と発注点(サービス水準 CSL を所与にした連続監視の発注点 ROP=μ+zσ。本稿はその対)・経済的発注量EOQ(多期・補充あり。本稿は単一期) | 確率の土台:正規分布(標準正規・標準化)(z=分位点 Φ^{-1}) | 次:収益管理(レベニューマネジメント)
要点(BLUF)
- 新聞売り子問題は、需要が判明する前に発注量 を1回だけ決める単一期間の確率的在庫です。季節品・生鮮・イベント物販・新聞や雑誌など、売れ残れば次に持ち越せない/不足しても追加できないモノが対象。経済的発注量EOQ の多期・補充ありとは別世界です。
- トレードオフは2つのコスト。過小コスト (1個足りないと取り逃す粗利=)と過剰コスト (1個余ると原価を残存価値でしか回収できない損=)。
- 最適発注量 は臨界比(critical ratio/critical fractile) を満たす分位点 で与えられます。正規需要なら 。
- 安全在庫と発注点 がサービス水準 CSL を所与にして を引いたのに対し、新聞売り子はコスト比からサービス水準が出ます——達成される こそが「コストが含意するサービス水準」。同じ でも の出どころが違う(所与の CSL か、コスト比 CR か)——これが両者の表裏の関係です。
1. 単一期間の在庫:補充できない一発勝負
EOQ(経済的発注量EOQ)や発注点(安全在庫と発注点)は、在庫が減ればまた発注して補充できる多期の世界でした。新聞売り子問題はそうではありません。シーズン前に1回だけ仕入れ量 を決め、需要 が実現したら終わり。売れ残りは捨てる(か叩き売る)、不足は機会損失。クリスマスケーキ、夏物アパレル、当日の生鮮、限定グッズ、印刷部数——「作り直しが間に合わない/持ち越せない」モノはすべてこの型です。
決めるべきは ただ一つ。多すぎれば売れ残り(過剰)、少なすぎれば品切れ(過小)。需要 は確率変数なので、 をどちらに振ってもある確率で損が出ます。期待損失を最小にする を選ぶのが目的です。
flowchart LR ORDER["需要が判明する前に<br/>発注量 Q を1回だけ決める"] --> REAL["需要 D が実現"] REAL -->|"D が Q 超過(品切れ)"| UNDER["不足 D-Q 個<br/>1個につき逸失利益 Cu=p-c"] REAL -->|"D が Q 以下(売れ残り)"| OVER["余り Q-D 個<br/>1個につき過剰損 Co=c-s"]
2つのコストを、売価 ・仕入原価 ・残存価値 (売れ残り1個の処分価値、)で定義します。
2. 限界分析から臨界比を導く
最適 を限界分析(1個増やす価値)で出します。発注量を から に増やすと、その** 個目**の運命は需要次第です。
- 売れる(、確率 ):それまで取り逃していた1個の需要を拾えるので、 だけ得。
- 売れ残る(、確率 ):余剰が1個増えるので、 だけ損。
ここで は需要の累積分布関数。 個目を仕入れる期待限界利得は
これが非負である限り在庫を1個ずつ増やすべきです。 を解くと
増やす価値がなくなる境目、すなわち が臨界比 に達したところが最適です。
コスト関数からの裏取り(同じ式が出る)
限界分析は直感的ですが、期待コストを微分しても同じ臨界比が出ます。完璧な予測( ちょうど)からの期待ミスマッチコストは、売れ残り分()と不足分()の和です。
ライプニッツの積分則で について微分すると、被積分関数の 依存だけが残り(境界項は被積分関数が0なので消える)、
とおけば 、整理して ——限界分析とまったく同じ。さらに2階微分は
で凸なので、この停留点は最小だと確定します。なお、期待利益の最大化も同じ を与えます。完璧予測時の利益 は に依らない定数で、期待利益 定数 だから、利益最大化はミスマッチコスト最小化と同値だからです(第4節のコードで利益を直接最大化して確かめます)。
3. 正規需要での Q*
需要が正規分布 なら、 は標準化して
形は 安全在庫と発注点 の とそっくりですが、 の出どころが違います。03-02 は「守りたいサービス水準 CSL」を人が決めて を引きました。新聞売り子は「コスト比 」が** を決め**、結果として達成されるサービス水準 がコストから内生的に出てくる。 そのものの理論は 正規分布(標準正規・標準化) に譲り、ここでは scipy.stats.norm.ppf で値を取ります。
4. Q* が期待利益を最大化することをモンテカルロで実証(コード)
(売価10・原価4・残存1)で 。正規需要 のもとで を計算し、続けて** のグリッド上で期待利益を200万サンプルでモンテカルロ**して、最大化点が に一致するか・達成サービス水準が になるかを確かめます。
import numpy as np
from scipy.stats import norm
rng = np.random.default_rng(20260627)
# 単一期の経済条件:売価 p・仕入原価 c・残存価値 s(売れ残りの処分価値, p>c>s)
p = 10.0 # 売価(円/個)
c = 4.0 # 仕入原価(円/個)
s = 1.0 # 残存価値(売れ残り1個の処分価値, 円/個)
# 過小コスト Cu(1個不足の逸失利益)と過剰コスト Co(1個売れ残りの損)
Cu = p - c # = 6:1個足りないと粗利 p-c を取り逃す
Co = c - s # = 3:1個余ると原価 c を s でしか回収できない
CR = Cu / (Cu + Co) # 臨界比 critical ratio
print(f"Cu = p-c = {Cu:.1f}, Co = c-s = {Co:.1f}")
print(f"臨界比 CR = Cu/(Cu+Co) = {CR:.4f}")
# 正規需要 N(mu, sigma) のもとで最適発注量 Q* = mu + z*sigma, z = Phi^{-1}(CR)
mu, sigma = 100.0, 30.0
z = norm.ppf(CR)
Q_star = mu + z * sigma
print(f"需要 ~ N(mu={mu:.0f}, sigma={sigma:.0f})")
print(f"z = norm.ppf(CR) = {z:.4f}")
print(f"最適発注量 Q* = mu + z*sigma = {Q_star:.2f}")
print()
# --- モンテカルロ:Q のグリッドで期待利益を評価し、最大化点が Q* に一致するか ---
N = 2_000_000
D = rng.normal(mu, sigma, size=N) # 需要サンプル(全 Q で共通=CRN)
def expected_profit(Q):
sold = np.minimum(D, Q) # 売れた数
profit = p * sold + s * np.maximum(Q - D, 0.0) - c * Q
return profit.mean()
Q_grid = np.arange(80.0, 145.0 + 0.5, 0.5)
profits = np.array([expected_profit(Q) for Q in Q_grid])
Q_best = Q_grid[np.argmax(profits)]
print(f"MC 期待利益を最大化する Q (グリッド探索) = {Q_best:.2f}")
print(f"臨界比から求めた Q* = {Q_star:.2f}")
print(f"Q* での期待利益 = {expected_profit(Q_star):.4f} 円/期")
print()
# 達成サービス水準 P(D <= Q*) は臨界比 CR に一致するはず
service = np.mean(D <= Q_star)
print(f"達成サービス水準 P(D<=Q*) 実測 = {service:.4f}(理論 CR = {CR:.4f})")
出力:
Cu = p-c = 6.0, Co = c-s = 3.0
臨界比 CR = Cu/(Cu+Co) = 0.6667
需要 ~ N(mu=100, sigma=30)
z = norm.ppf(CR) = 0.4307
最適発注量 Q* = mu + z*sigma = 112.92
MC 期待利益を最大化する Q (グリッド探索) = 113.00
臨界比から求めた Q* = 112.92
Q* での期待利益 = 501.7746 円/期
達成サービス水準 P(D<=Q*) 実測 = 0.6668(理論 CR = 0.6667)
出力の意味:臨界比 、その正規分位点 、最適発注量 個。コードはこの を一切使わず、 を80から145まで動かして期待利益をMCで評価しただけですが、最大化点 113.00 が臨界比から求めた 112.92 とぴたり一致しました(グリッド幅0.5の丸め差だけ)。限界分析・コスト微分・利益最大化の3つが同じ を指す、という導出が数値で裏取りできています。最後の行が肝で、達成サービス水準 が臨界比 にそのまま一致——「過剰3:過小6」というコスト比が、67%という品切れ防止水準を勝手に決めているわけです。03-02 で人が「95%にしよう」と決めていたサービス水準が、ここではコストから自動的に出てくる。これが新聞売り子の本質です。
5. 臨界比の含意:粗利が高いほど多めに、腐りやすいほど少なめに(コード)
臨界比 は、粗利が高い( 大)と1に近づき多めに持て、腐りやすい/値引きが効かない( 大)と0に近づき絞れ、と言っています。同じ需要 でも商品の経済性で がどう動くかを、3つの商品で見ます。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
from scipy.stats import norm
# 同じ需要 N(mu, sigma) でも、粗利と廃棄リスクで臨界比=最適発注量が変わる
mu, sigma = 100.0, 30.0
# 3つの商品(売価 p・原価 c・残存価値 s)。Cu=p-c, Co=c-s, CR=Cu/(Cu+Co)
products = [
("高粗利・低廃棄(雑誌)", 500.0, 300.0, 250.0),
("バランス型", 300.0, 200.0, 100.0),
("腐りやすい・薄利(生鮮)", 300.0, 200.0, 0.0),
]
rows = []
for name, p, c, s in products:
Cu, Co = p - c, c - s
CR = Cu / (Cu + Co)
z = norm.ppf(CR)
Q_star = mu + z * sigma
rows.append({"商品": name, "Cu": Cu, "Co": Co, "CR": CR,
"z": z, "Q*": Q_star, "対平均": Q_star - mu})
df = pd.DataFrame(rows)
print(df.to_string(index=False, float_format=lambda x: f"{x:.3f}"))
print()
print("CR が高い(粗利大・廃棄損小)ほど多めに持ち、低いほど絞る。")
print("達成サービス水準 P(D<=Q*) は CR にそのまま等しい(03-02 はこれを所与にした)。")
# --- 図:臨界比 CR と最適発注量 Q* の関係(CR が上がるほど Q* が増える) ---
CR_grid = np.linspace(0.02, 0.98, 400)
Q_curve = mu + norm.ppf(CR_grid) * sigma
plt.figure(figsize=(10, 5.5))
plt.plot(CR_grid, Q_curve, color="#1f77b4", lw=2,
label=r"$Q^*=\mu+\Phi^{-1}(CR)\,\sigma$")
plt.axhline(mu, color="gray", ls="--", lw=1, label=f"平均需要 μ={mu:.0f}")
colors = ["#2ca02c", "#ff7f0e", "#d62728"]
offsets = [(12, -34), (12, 12), (-150, -30)] # ラベルの位置(重なり回避)
for (name, p, c, s), col, off in zip(products, colors, offsets):
Cu, Co = p - c, c - s
CR = Cu / (Cu + Co)
Q_star = mu + norm.ppf(CR) * sigma
plt.scatter([CR], [Q_star], color=col, zorder=5, s=60)
plt.annotate(f"{name}\nCR={CR:.2f}, Q*={Q_star:.0f}",
(CR, Q_star), textcoords="offset points",
xytext=off, fontsize=9, color=col)
plt.axvline(0.5, color="purple", ls=":", lw=1, label="CR=0.5(過小=過剰)")
plt.xlabel("臨界比 CR = Cu/(Cu+Co) = 達成サービス水準 P(D≦Q*)")
plt.ylabel("最適発注量 Q*")
plt.title("新聞売り子:粗利が高い(CR→1)ほど多めに、腐りやすい(CR→0)ほど少なめに持つ")
plt.legend(loc="upper left"); plt.tight_layout(); plt.show()
出力:
商品 Cu Co CR z Q* 対平均
高粗利・低廃棄(雑誌) 200.000 50.000 0.800 0.842 125.249 25.249
バランス型 100.000 100.000 0.500 0.000 100.000 0.000
腐りやすい・薄利(生鮮) 100.000 200.000 0.333 -0.431 87.078 -12.922
CR が高い(粗利大・廃棄損小)ほど多めに持ち、低いほど絞る。
達成サービス水準 P(D<=Q*) は CR にそのまま等しい(03-02 はこれを所与にした)。
出力の意味:同じ需要分布でも、最適発注量が商品で大きく変わります。粗利が大きく売れ残りロスが小さい雑誌()は と平均より25個多く持つ。過小と過剰が拮抗するバランス型()は ぴったりで (中央値発注)。腐りやすく薄利の生鮮()は で と平均より13個少なく絞る。図は を横軸に取った の曲線で、3商品がその上に乗っています。(粗利が圧倒的)で青曲線が跳ね上がり、(捨てるしかない)で沈む——「足りない痛み と余る痛み のどちらが大きいか」で発注量が決まる。横軸が「達成サービス水準 」でもあることに注意:03-02 で人が選んでいたサービス水準が、ここではコスト比そのものだという対応関係が、1本の曲線に集約されています。
⚠️ よくある誤解
- 「新聞売り子=多期の在庫管理」ではない:新聞売り子は単一期間・補充なし・持ち越せないモノ(季節品・生鮮・印刷部数)の問題です。減ったら補充できる多期の世界は EOQ+発注点(経済的発注量EOQ・安全在庫と発注点)。多期でも「期末の余剰を捨てる」構造があれば各期が新聞売り子になりますが、繰り越せる在庫がある一般の多期問題は基在庫(base-stock)方策で、 などに発展します(離散事象シミュレーション最適化)。
- 「臨界比=任意に決めるサービス水準」ではない:臨界比 はコストが含意するサービス水準で、人が決めるものではありません。逆に 安全在庫と発注点 はサービス水準 CSL を所与にしました。両者は表裏——「サービス水準を約束する」のか「コストを最小化する」のかで、 の出どころが CSL か CR かに分かれます。コスト を正直に見積もれるなら、サービス水準を勘で決めるより新聞売り子のほうが筋が通ります。
- 「過剰と過少は対称」ではない: なら最適は非対称で、 は平均からずれます。(品切れのほうが痛い)なら平均より多め()、逆なら少なめ。 のときだけ 中央値(正規なら平均)。「とりあえず平均ぶん仕入れる」は の特殊ケースを暗黙に仮定しています。
- 「需要分布は何でも正規でいい」ではない: は任意の分布で成立しますが、 の形は正規(や対称分布)の近似です。需要が右に歪む(在庫品・低頻度大口)なら正規は危険で、ポアソン・負の二項・対数正規などで を直接取るべき。とくに が1に近い高粗利品は裾の形が効くので、分布の選択が在庫量を左右します(要最新確認)。
- 「残存価値や品切れペナルティは無視できる」ではない: の (値引き処分・転用価値)と、 に上乗せされるのれん損・代替購買による将来損を入れ忘れると、臨界比がずれて系統的に過少/過剰発注になります。実務では に「失客の長期損」を、 に「在庫処分・廃棄・保管」を丁寧に積むのが勘所です(要最新確認)。
関連ノート
- 安全在庫と発注点(サービス水準 CSL を所与にした連続監視の発注点 。本稿はコストから が出る表裏)
- 経済的発注量EOQ(多期・補充ありのロットサイズ。本稿は単一期・補充なし)
- 正規分布(標準正規・標準化)(統計・ 分位点の土台)
- 収益管理(レベニューマネジメント)(次のトピック・リトルウッドの保護水準は新聞売り子の親戚)
- 離散事象シミュレーション最適化(閉形式が効かない多期・確率リードタイムの在庫を探索で解く)
- オペレーションズ・マネジメント 全体目次