报童问题 (The Newsvendor Problem)

引言

本文介绍了一个经典的商品采购模型(报童问题)及其解法. 该模型通过考虑需求的不确定性来最大化销售利润. 注: 本文的主要内容参考Gallego1.

1. 报童问题

这是一个关于卖报商人采购报纸的问题. 每天早上, 卖报商以批发价0.3元(每份)向报社采购当天的报纸, 然后以零售价1元(每份)进行售卖. 如果报纸在当天没有卖完, 他会把报纸以0.05元(每份)的价格卖给废品回收站. 那么卖报商应该如何确定报纸的采购数量?

我们先简单分析一下这个问题的特点:

  1. 采购一个商品.
  2. 在一个采购周期内仅采购一次.
  3. 采购之时不知道准确的需求.
  4. 商品会过期.

2. 数学模型

下面我们用数学语言把这个问题再描述一下.

参数

  • 单位采购成本(cost per unit): c c c
  • 零售价(sale price): p p p
  • 残值(salvage value), 即商品过期之后的售价: s s s
  • 需求(demand): 随机变量 D D D服从分布 F F F, 均值和标准差分别记为 μ , σ \mu, \sigma μ,σ

决策变量

  • 采购量: x x x

目标

  • 最大化期望收益 π ( x ) : = p ⋅ E [ min ⁡ ( x , D ) ] + s ⋅ E [ max ⁡ ( x − D , 0 ) ] − c x \pi(x) := p \cdot \mathbb{E}[\min(x, D)] + s\cdot \mathbb{E}[\max(x-D, 0)] - cx π(x):=pE[min(x,D)]+sE[max(xD,0)]cx

不失一般性, 我们假设 p > c > s p>c>s p>c>s, 否则问题的最优解是显而易见的.

3. 求解

x + : = max ⁡ ( x , 0 ) , x − : = min ⁡ ( x , 0 ) x^+ := \max(x, 0), x^-:=\min(x, 0) x+:=max(x,0),x:=min(x,0). 因此 x = x + + x − x=x^+ + x^- x=x++x, x − = − ( − x ) + x^- = -(-x)^+ x=(x)+. 利用 min ⁡ ( x , D ) = D − ( D − x ) + \min(x, D) = D - (D-x)^+ min(x,D)=D(Dx)+, 我们可以把 π ( x ) \pi(x) π(x)表示成如下形式:

π ( x ) = ( p − c ) μ − α ( x ) , \pi(x) = (p-c)\mu - \alpha(x), π(x)=(pc)μα(x),

其中

α ( x ) = ( c − s ) E [ ( x − D ) + ] + ( p − c ) E [ ( D − x ) + ] . \alpha(x) = (c-s)\mathbb{E}[(x-D)^+] + (p-c)\mathbb{E}[(D-x)^+]. α(x)=(cs)E[(xD)+]+(pc)E[(Dx)+].

因此 max ⁡ π ( x ) ⇔ min ⁡ α ( x ) \max \pi(x) \Leftrightarrow \min \alpha(x) maxπ(x)minα(x). 记 h = c − s h = c-s h=cs, b = p − c b=p-c b=pc. 则 h , b h, b h,b分别代表采购过量(overage)和少量(underage)的单位成本.

f ( z ) = h z + − b z − f(z) = hz^+ - bz^- f(z)=hz+bz. α ( x ) \alpha(x) α(x)可以被写成

α ( x ) = E [ f ( x − D ) ] . \alpha(x)=\mathbb{E}[f(x-D)]. α(x)=E[f(xD)].

由于 f ( z ) f(z) f(z)是凸函数, 它的线性变换 α ( x ) \alpha(x) α(x)也是凸函数, 当 F F F是连续分布时, 最优解的一阶导数为0. 我们可以通过交换积分号导, 即

α ′ ( x ) = h ⋅ E [ δ ( x − D ) ] − b ⋅ E [ δ ( D − x ) ] \alpha'(x) = h\cdot \mathbb{E}[\delta(x-D)] - b\cdot \mathbb{E}[\delta(D-x)] α(x)=hE[δ(xD)]bE[δ(Dx)]

其中 δ ( z ) = 1 \delta(z)=1 δ(z)=1 如果 z > 0 z>0 z>0, 否则 δ ( z ) \delta(z) δ(z)为0.

注意到 E [ δ ( x − D ) ] = P r ( x − D > 0 ) \mathbb{E}[\delta(x-D)] = Pr(x-D>0) E[δ(xD)]=Pr(xD>0) E [ δ ( D − x ) ] = P r ( D − x > 0 ) \mathbb{E}[\delta(D-x)] = Pr(D-x>0) E[δ(Dx)]=Pr(Dx>0). 我们有

α ′ ( x ) = h ⋅ P r ( D < x ) − b ⋅ P r ( D > x ) . \alpha'(x)= h \cdot Pr(D < x) - b \cdot Pr(D>x). α(x)=hPr(D<x)bPr(D>x).

α ′ ( x ) = 0 \alpha'(x)=0 α(x)=0, 我们得到

F ( x ) : = P r ( D ≤ x ) = b b + h . F(x) := Pr(D\leq x) = \frac{b}{b+h}. F(x):=Pr(Dx)=b+hb.

临界分位数(Critical Fractile)
γ = b b + h . \gamma = \frac{b}{b+h}. γ=b+hb.

由于 F F F是随机变量 D D D的cdf(cumulative distribution function) (单调非递减), 因而存在逆函数. 设最优解为 x ∗ x^* x, 因此
x ∗ = F − 1 ( γ ) . x^* = F^{-1}(\gamma). x=F1(γ).

4. 例子

本节考虑两个具体的例子. 一个是 D D D服从正态分布(连续分布), 可以按照前文的公式计算最优解; 另一个例子是 D D D服从Poisson分布, 我们介绍如何把计算方法适配到离散分布的情形.

4.1 正态分布

D ∼ N ( μ , σ 2 ) D\sim N(\mu,\sigma^2) DN(μ,σ2). 令 Z ∼ N ( 0 , 1 ) Z\sim N(0, 1) ZN(0,1), Φ ( z ) = P r ( Z ≤ z ) \Phi(z) = Pr(Z\leq z) Φ(z)=Pr(Zz) z γ = Φ − 1 ( γ ) z_{\gamma} = \Phi^{-1}(\gamma) zγ=Φ1(γ).
由于
P r ( D − μ σ ≤ z γ ) = Φ ( z γ ) = γ . Pr\left(\frac{D-\mu}{\sigma}\leq z_{\gamma}\right) = \Phi(z_{\gamma}) = \gamma. Pr(σDμzγ)=Φ(zγ)=γ.
因此
x ∗ = μ + z γ σ . x^* = \mu + z_{\gamma}\sigma. x=μ+zγσ.

D D D服从正态分布, μ = 100 \mu=100 μ=100, σ = 20 \sigma=20 σ=20. 设 c = 5 c=5 c=5, h = 1 h=1 h=1, b = 3 b=3 b=3. 我们的计算步骤如下:

  1. γ = b h + b = 0.75 \gamma = \frac{b}{h+b} = 0.75 γ=h+bb=0.75
  2. z γ = Φ − 1 ( 0.75 ) = 0.6745 z_{\gamma} = \Phi^{-1}(0.75) = 0.6745 zγ=Φ1(0.75)=0.6745
    # python
    >>> from scipy.stats import norm
    >>> norm.ppf(0.75)
    0.6744897501960817
    
  3. x ∗ = μ + z γ ⋅ σ = 100 + 0.6745 ∗ 20 = 113.49 x^*=\mu + z_{\gamma} \cdot \sigma = 100 + 0.6745 * 20 = 113.49 x=μ+zγσ=100+0.674520=113.49
4.2 Poisson分布

Poisson分布的pmf (probability mass function)为

P r ( D = k ) = e − λ λ k k ! . Pr(D=k) = e^{-\lambda}\frac{\lambda^k}{k!}. Pr(D=k)=eλk!λk.

由于Possion分布是离散分布(对任意的 γ \gamma γ, F − 1 ( γ ) F^{-1}(\gamma) F1(γ)不一定可计算), 我们令
x ∗ = arg ⁡ min ⁡ x { x ∈ N ∣ P r ( D ≤ x ) ≥ γ } . x^* = \arg\min_x \{x\in \mathbb{N}\mid Pr(D\leq x) \geq \gamma\}. x=argxmin{xNPr(Dx)γ}.

D D D服从Poisson分布, λ = 25 \lambda=25 λ=25. 设 c = 5 c=5 c=5, h = 1 h=1 h=1, b = 3 b=3 b=3. 我们的计算步骤如下:

  1. γ = b h + b = 0.75 \gamma = \frac{b}{h+b} = 0.75 γ=h+bb=0.75
  2. 利用二分法找到最小的整数 x ∗ x^* x使得 F ( x ∗ ) ≥ 0.75 F(x^*)\geq 0.75 F(x)0.75(其中 F F F是随机变量 D D D的cdf).
    # python
    >>> from scipy.stats import poisson
    >>> poisson(25).cdf(27)
    0.7001861449652768
    >>> poisson(25).cdf(28)
    0.763400741866402
    
  3. x ∗ = 28 x^*=28 x=28

5. 总结

  1. 报童问题是商品采购问题的一个例子. 对该问题的研究和求解可以指导我们在实际中优化采购计划, 从而提高商品的销售利润.
  2. 但在实际中制定商品的采购计划时, 我们的目标与约束一般会比报童问题复杂(例如考虑库存成本), 因此需要根据实际问题进行建模和求解, 不能盲目照搬已有的模型.
  3. 制定采购计划之前可以采用需求预测(销量预测), 但同时也要考虑销量的随机性(详情见《如何在商品采购中考虑不确定性》).

参考文献


  1. Guillermo Gallego. “IEOR 4000 Production Management Lecture 7”. Columbia University, 2005. ↩︎

  • 19
    点赞
  • 116
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
所谓报童问题是一个与需求有关,而需求是随机的问题。一位报童从报刊发行处订报后零售,每卖出一份可获利a元,若订报后卖不出去,则退回发行处,每份将要赔钱b元。那么报童如何根据以往的卖报情况(每天报纸的需求量为k份的概率为 )来推算出每天收益达到最大的订报量n? 算法解说分析: ① 我利用负指数分布公式“g(u)=-lg(u)”,其中“u=1.0*u/RAND_MAX(产生[0,1]均匀分布的随机数)”。函数中“g(u)=-lg(u)”的自变量“u”是均匀产生[0,1]之间的数,可知“g(u)”的函数值也是等可能的产生的,而且这些函数值是呈一种负指数分布趋向的。我可以通过一些巧妙地方法,就是让这些函数值乘上一个数值,让其不能超过1并且把这些值累加起来(今次加上上一次的),这是一个循环,结束的条件是累加的这些和的值≥1。到循环结束的时候,我可以算一下究竟循环了多少次,而这个循环了“多少次”就是我们所需要的需求量的模拟值。 ② 因为我们都知道“-lg(u)”的值是公平地呈负指数分布出现的,为何?很明显,“u=1.0*u/RAND_MAX(产生[0,1]均匀分布的随机数)”证明其“公平性”。“公平性”很重要,因为能出现通过“-lg(u)”计算得出的值必须要公平才有“可信性”。同理,“-lg(u)”乘上一个具体的数以后也是能“g(u)”的值是公平地呈负指数分布出现的“x=-1.0/t*log(u);/*产生负指数分布的随机数(t是确定的常数)*/ ” ③ 根据负指数函数的分布规律可知,每次让这些函数值缩小某个级别的时候在累加起来,直到其值“=1”才停止,其中循环的次
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值