Sequential Decision Analytics and Modeling 第2版
Back to SDA site →

第11章:供应链管理 II:啤酒游戏

章节概述

啤酒游戏是供应链管理教学中的经典案例。我们将其作为一个通用的多智能体问题来处理,把啤酒游戏中的每个供应商都建模为一个独立的智能体。这一介绍在第10章所奠定的基础之上进行扩展,增加了一个新的复杂性:智能体既要发送信息(啤酒订单),又要发送实物资源(啤酒)。

本章对不确定性的建模保持相当简单。相反,我们探索了一系列简单的参数化策略,并借此机会引入了一个智能体对另一个智能体可能拥有的信息(在本例中,是关于欠单量)所持有的信念。随后,我们展示了一个著名的”锚定与调整”策略的示例,该策略最初由两位知名决策科学家丹尼尔·卡尼曼(Daniel Kahneman)和阿莫斯·特沃斯基(Amos Tversky)提出,这里我们将其改编应用于啤酒游戏场景。最后,我们勾勒了如何设计一个随机前瞻策略,利用我们的决策是标量这一特性。

本章最后提出了一系列广泛的扩展方向,展示了供应链场景中控制问题变体的丰富性。

叙述

本章介绍一个源自20世纪50年代的著名游戏,即”啤酒游戏”。它最初由麻省理工学院(MIT)教授杰伊·福瑞斯特(Jay Forrester)设计,旨在说明供应链的不稳定性。该问题涉及一条线性供应链,各供应商将啤酒从生产地(制造商)转移到市场(零售商)。啤酒在从生产地到市场的途中必须经过若干中间商。

存在两种类型的流动:

供应链中的每一层被称为一个梯队(echelon)。通常每个团队有四到六个梯队。零售商处的需求事先在一副纸牌中固定但被隐藏起来。当零售商揭示当周的需求时,她会尝试从库存中满足该需求。随后,零售商以及供应链中的其他每个供应商(除制造商外)都要填写一张纸,向下一级请求更多库存。

零售商或任何一个中间供应商都有可能无法满足对更多库存的请求(或零售端的市场需求)。在这种情况下,未满足的需求将停留在订单积压中,等待新库存到达后再被满足。

在填写订单之后,每个人(对该供应链而言)都必须停下来记录他们的库存(库存中的啤酒箱数)或订单积压。订单积压每箱要承担4美元的惩罚成本。多余的库存每箱要承担1美元的持有成本。

该流程的各个步骤如图11.1所示。共有五个步骤:

步骤0: 每周,每位玩家都会有一定的库存(用硬币表示,每枚代表一箱啤酒),以及一份订单,该订单可能是零售需求(对于零售梯队而言),也可能是该玩家左侧玩家下的订单。

步骤1: 每位玩家尝试从自己的库存中取出尽可能多的箱数,并将其移到自己左侧、位于自己与左侧玩家之间的区域(不要把硬币加入左侧玩家的库存中)。如果库存不足以满足订单,就划掉该订单,并将其替换为仍需满足的箱数(这就是订单积压)。

步骤2: 现在写出一份订单,说明你想补充多少箱库存,并将其放在你与你右侧玩家之间的区域(制造商则将订单放在所有啤酒的来源——那堆硬币上)。

步骤3: 停下来,在你的库存记录表上记录你有多少库存。如果你未能满足某个订单,你的库存将为零,并且你会在积压订单中记录未满足的订单。如果出现这种情况,请将其记录为你的订单积压。

步骤4: 这是关键的一步:伸出左手,将下一张订单单据拉入你的订单堆(纸质单据),同时伸出右手,将送到你这里的硬币拉入你的库存中。现在你又回到了步骤0时的状态。

普林斯顿版啤酒游戏的布局。
图11.1。 普林斯顿版啤酒游戏的布局。

非常重要的一点是,所有人必须同时行动,但不允许分享信息(并且他们不应该查看同一条链上其他玩家的库存)。零售商需要承担协调所有人同步行动的角色。

经典啤酒游戏简化版的完整说明可从tinyurl.com/PrincetonBeerGame下载。此版本的游戏特别适合在配有连续拼接桌子、至少有8-10名学生的课堂上进行教学(之所以需要连续拼接的桌子,是为了让玩家能够在彼此之间推送纸张和硬币)。团队应有五到六名玩家(这意味着有五到六个中间梯队加上零售商),但不应少于四人。距离工厂最近的库存管理者可以同时负责两个岗位(因为工厂几乎只需要满足订单)。各团队的规模不必相同,而且要为迟到的学生扩展一条链也相当容易。整个游戏可以在50分钟的课时内完成。

问题框架

这是另一个多智能体问题。针对每个智能体,我们对三个框架性问题的回答是:

基本模型

我们将对供应链中除端点(零售商或啤酒制造商)之外的某个供应商进行建模。该模型将紧密遵循上一章中双智能体报童问题的风格,尽管存在一些调整。在开始之前,我们需要为多智能体系统引入一些新的记号。

多智能体记号

在开始之前,我们需要建立记号体系,用以表示谁知道什么,以及信息共享的过程。

我们将用$\Qcal = \lbrace 1, 2, \ldots, Q\rbrace $来标记供应链中不同的决策智能体。我们将用$q=0$表示市场,它是信息的来源,但不做决策。我们将用$q=Q$表示制造工厂,我们(至少最初)假设该工厂总能生产足够的产品来满足需求。

我们首先使用$S_{tq}$定义智能体$q$的状态变量,$S_{tq}$表示智能体$q$在时间$t$所知道的信息(这可能包括信念)。如果智能体$q$对智能体$q’$采取行动,我们将使用$x_{tqq’}$表示智能体$q$对智能体$q’$的行动。我们注意到,决策$x_{tqq’}$由$q$确定,但作为信息到达$q’$。

$q$在时间$t$对$q’$采取的行动可能涉及实物资源的转移,但也可能包括发送信息。$q$对$q’$的行动将作为一个外源信息过程到达$q’$,在时间$t+1$到达$q’$(这正是任何失真会被体现出来的地方),我们将其写为$W_{t+1,q,q’}$,即智能体$q’$在时间$t+1$从智能体$q$所采取行动中获得的信息(这可能是关于资源的信息,也可能是关于$S_{tq}$发送或共享信息的信息)。

最后,有些时候智能体$q$需要对智能体$q’$所知道的某些信息创建一个估计。如果我们用$S_{tq’}$表示智能体$q’$所知道的某些信息,我们将用$\overleftarrow{S}_{t,q,q’}$表示智能体$q$对$S_{tq’}$中信息所创建的估计。

状态变量

智能体$q=1, \ldots, Q-1$的状态变量为:$R^{inv}_{tq}$,即在迭代$t$向智能体$q$的上游供应商交付产品之后剩余的库存;以及$R^{back}_{tq}$,即尚未从库存中满足的欠单需求。

假设制造商$q=Q$始终拥有无限库存。

随着后续的深入,我们会了解到这其实并未完整描述该问题的状态,但这是一个很好的起点。

决策变量

智能体$q$需要做出两个决策。第一个(也是最重要的)是应向下游智能体$q+1$订购多少,我们将其写为$x^{req}_{tq,q+1}$,即供应商$q$提出、将传递给供应商$q+1$的订单,该订单在迭代$t$的下单时刻做出,将由$q+1$接收,并在迭代$t+1$中被满足。

第二个决策是应从库存中满足上游智能体请求的多少。我们将其写为$x^{fill}_{tq,q-1}$,即在时间$t$从库存中满足未满足需求$R^{back}_{tq}$的数量。

对于$q=1, \ldots, Q-1$,这些决策受到以下约束:

\[\begin{align} 0 \leq x^{fill}_{tq,q-1} &\leq R^{inv}_{tq},\label{eq:beergameconstraint1}\\ 0 \leq x^{fill}_{tq,q-1} &\leq R^{back}_{tq},\label{eq:beergameconstraint2}\\ x^{req}_{tq,q+1},x^{fill}_{tq,q-1} &\geq 0. \label{eq:beergameconstraint3} \end{align}\]

约束$\eqref{eq:beergameconstraint1}$反映了这样一个现实:我们不能向智能体$q-1$发送我们手头没有的库存。约束$\eqref{eq:beergameconstraint2}$表明,我们不能向智能体$q-1$发送尚未被请求的库存。请注意,$R^{back}_{tq}$包括尚未被满足的新订单。

于是我们将决策向量写为

\[x_{tq} = (x^{req}_{tq,q+1},x^{fill}_{tq,q-1}),\]

我们的决策将由某个策略$X^\pi(S_t)$做出,该策略我们将在后面进行设计。

在我们的基本游戏中,我们总是会尽可能多地从库存中满足来自$q-1$的订单,因此从技术上讲,$x^{fill}_{tq,q-1}$并不算是真正的决策,因为我们只需设定$x^{fill}_{tq,q-1} = \min\lbrace R^{back}_{tq},R^{inv}_{tq}\rbrace $。然而,它仍然是$q$所采取的一个行动,并为后续更丰富的行为方式打开了大门。

如果我们是零售市场$q=0$,那么对智能体$q=1$提出的请求$W_{t,0,1} = x^{req}_{t,0,1}$来自一个外源信息源。

如果我们是工厂$q=Q$,我们总是满足来自$q=Q-1$的请求,因此

\[x^{fill}_{t+1,Q,Q-1} = x^{req}_{t,Q-1,Q}.\]

外源信息

对于供应商$q$,存在两类外源信息:$W^{fill}_{t+1,q+1,q}$,即响应在时间$t$提出、在时间$t+1$到达的请求而从供应商$q+1$处收到的产品数量;以及$W^{req}_{t+1,q-1,q}$,即供应商$q-1$在时间$t$向供应商$q$下达的订单,该订单将于时间$t+1$到达。

需要重要认识到的是,智能体$q+1$和$q-1$所做出的决策会作为外源信息到达智能体$q$。这意味着我们可以写出

\[W^{fill}_{t+1,q+1,q} = x^{fill}_{t,q+1,q}, \qquad W^{req}_{t+1,q-1,q} = x^{req}_{t,q-1,q}.\]

我们可以用\(W_{t+1,q} = (W^{fill}_{t+1,q+1,q},W^{req}_{t+1,q-1,q}).\)表示截至时间$t+1$到达智能体$q$的外源信息

\[W_{t+1,q} = (W^{fill}_{t+1,q+1,q},W^{req}_{t+1,q-1,q}).\]

这描述了中间智能体$q=1, \ldots, Q-1$的信息过程。信息过程$W_{t,0}$指的是市场,我们假设存在一个外源的请求来源$x^{req}_{t,0,1} = W_{t,0,1}$,这些请求被提交给智能体1。

转移函数

我们对$q=1, \ldots, Q-1$的状态变量$R^{inv}_{tq}$和$R^{back}_{tq}$按照如下方式演化

\[\begin{align} R^{inv}_{t+1,q} &= R^{inv}_{tq}-x^{fill}_{t,q,q-1} + W^{fill}_{t+1,q+1,q}, \label{eq:beergametrans1}\\ R^{back}_{t+1,q} &= R^{back}_{tq}-x^{fill}_{t,q,q-1} + W^{req}_{t+1,q-1,q}. \label{eq:beergametrans2} \end{align}\]

方程$\eqref{eq:beergametrans1}$从库存中扣除请求$x^{fill}_{t,q,q-1}$(不允许出现负值),然后加上来自下游智能体$q+1$的到达库存$W^{fill}_{t+1,q+1,q}$,从而得到时间$t+1$的库存。方程$\eqref{eq:beergametrans2}$满足保存在$R^{back}_{tq}$中的已请求订单,然后加上将在期间$t+1$被满足的新订单$W^{req}_{t+1,q-1,q}$。

目标函数

我们对智能体$q$的目标函数评估了剩余库存$R^{inv}_{tq}$和未满足需求$R^{back}_{tq}$所产生的惩罚。设$c^{inv}_q$为智能体$q$持有库存的单位成本,$c^{back}_q$为智能体$q$未满足订单的单位成本。

这些成本是在做出满足客户订单的决策之后、但在新订单到达之前,针对库存和积压需求进行评估的。因此,智能体$q$的成本函数由下式给出

\[C(S_t,x_t) = c^{inv}(R^{inv}_{tq}-x^{fill}_{t,q,q-1}) + c^{back}(R^{back}_{tq}-x^{fill}_{t,q,q-1}).\]

记住,$R^{inv}_{tq}$是当前库存,因此$R^{inv}_{tq}-x^{fill}_{t,q,q-1}$是我们已经完成时间$t$的订单填充后的剩余库存。类似地,$R^{back}_{tq}$既包括新订单,也包括之前时间段未完成的订单。因此,$R^{back}_{tq}-x^{fill}_{t,q,q-1}$就是那些没有立即完成的订单。

我们现在使用以下方法搜索最优策略

\[\min_\pi \E\left\{\sum_{t=0}^T C_q(S_t,X^\pi(S_t))\vert S_0\right\}.\]

这必须对每个智能体$q$执行,假设每个智能体都是自我优化的。另一个挑战是为每个智能体选择策略,这些策略只能使用每个智能体所能获得的信息,但我们仍然希望这些策略能够实现全局最优。这个问题超出了本书的范围。

建模不确定性

除了处于端点的智能体外,每个智能体都需要管理两个不确定性来源:

换句话说,唯一的不确定性来源是市场和智能体的行为。智能体(作为人)之间相互作用的方式会带来复杂(且不确定)的动态。通常,游戏运行时市场的动态变化相当温和。即使在这种运行方式下,人类行为仍可能引发显著的不稳定性,这种现象在真实供应链中已被观察到,被称为”牛鞭效应”。

设计策略

我们可以考虑多种基本的PFA类型策略。我们首先假设我们总是在可用库存范围内填充请求,因此

\[x^{fill}_{t,q,q-1} = \min\{x^{req}_{t,q-1,q}, R^{inv}_{tq}\}.\]

我们注意到,在设计不同的策略时,可能需要为状态变量引入额外的元素,以满足策略的信息需求。

一些简单规则

我们将从一些简单的订购规则开始热身:

\[X^{\pi,req}_{t,q,q+1}(S_{tq}\vert \theta) = W^{req}_{t-1,q-1,q} + \theta_{q}.\]

这个策略忽略了我们库存中有多少,它是一种纯粹的跟踪策略。这个策略要求我们在状态变量中存储先前的请求$W^{req}_{t-1,q-1,q}$,因此状态变量变为

\[S_{tq} = (R^{inv}_{tq},R^{back}_{tq}, W_{t-1,q-1,q}).\]

然后我们将其提高$\theta$,以防范不确定性。

\[X^{\pi,req}_{t,q,q+1}(S_{tq}\vert \theta) = R^{back}_{tq} + \theta_{q}.\]

当我们存在未满足的需求时,这一策略会造成重复计算,即发出多次请求。

\[X^{\pi,req}_{t,q,q+1}(S_{tq}\vert \theta) = \max\{0, \theta^{target}_{q}-R^{inv}_{tq}\}.\]

这一策略旨在维持一个指定的目标库存$\theta^{target}$,该目标不随条件变化而改变。

这些都是基本的参数化PFA,易于实现,但当然需要调参。同时,它们相当简单,忽略了诸如尚未填充的过往订单历史等因素(事实上,这些策略每一个都存在根本性缺陷)。

请记住,$R^{back}_{tq}$是智能体$q-1$向智能体$q$下的订单,而$q$尚未填充这些订单。$q$向$q+1$下达但尚未填充的订单由$R^{back}_{t,q+1}$给出,但智能体$q$并不能立即知道这一点。设$\overleftarrow{R}^{back}_{tq,q+1}$为智能体$q$对$R^{back}_{t,q+1}$的估计值,即$q+1$所知的延期订单需求的估计。这些是$q$向$q+1$下达但尚未填充的订单,这通常是由$q+1$维护的统计量。

通常,一个智能体(如$q+1$)已知的信息不能被另一个智能体(如$q$)完全知晓,但在这种情况下,这是$q$可以自行维护的统计量,使用

\[\overleftarrow{R}^{back}_{t+1,q,q+1} = \max\{0,\overleftarrow{R}^{back}_{tq,q+1}+x^{req}_{t,q,q+1} - W^{fill}_{t+1,q+1,q}\}.\]

我们可以利用这个统计量来提出一种调整后的目标库存策略,即把$\overleftarrow{R}^{back}_{t+1,q,q+1}$所捕获的未填充订单加到我们当前的库存$R^{inv}_{tq}$中,我们可将其写为:

\[x^{req}_{t,q,q+1} = \max\{0, \theta^{target}-(R^{inv}_{tq}+\overleftarrow{R}^{back}_{t+1,q,q+1})\}.\]

这一策略是PFA的一种形式(不含嵌入式优化),但它反映了未来将到达的供应。

锚定与调整启发式方法

1989年,约翰·斯特曼(麻省理工学院教授、商业动态学专家)发表了一篇论文,将特沃斯基和卡尼曼(1974年)提出的”锚定与调整”原理应用于啤酒游戏。我们将在这里概述这一思想。

我们首先定义一组状态变量。我们实际使用的变量可能取决于所采用的策略。

我们完整的状态变量即为

\[S_{tq} = (R_{tq}, I_{tq}, B_{tq}).\]

估计填充率$\Fbar_{t,q,q-1}$可以用以下几种方式之一计算:

应用于此背景下的”锚定与调整”原理是选择一个”锚点”,该锚点指定我们预期平均应订购的数量,然后通过一个”调整”来反映当前状况。

\[X^{\pi,req}_{t,q,q+1}(S_{tq}) = \Fbar_{t,q-1,q}.\] \[X^{\pi,req}_{t,q,q+1}(S_{tq}\vert \theta_q) = \max\{0,\Fbar_{t,q-1,q} + \delta R^{inv}_{tq} + \delta R^{transit}_{tq}\}.\]

现在我们必须设计调整机制。$\delta R^{inv}_t$的一种可能策略可能是

\[\delta R^{inv}_{tq} = \theta^{inv}_q (R^{inv-trgt}_q - R^{inv}_{tq}),\]

其中$\theta^{inv}_q$是平滑因子,目标库存$R^{inv-trgt}$是可调参数。

$\delta R^{transit}_{tq}$的一种可能策略可能是

\[\delta R^{transit}_{tq} = \theta^{transit} (R^{transit-trgt}_q - R^{transit}_{tq}).\]

我们的可调参数向量则为

\[\theta_q = (\theta^{inv}_q, R^{inv-trgt}_q, \theta^{transit}_q, R^{transit-trgt}_q).\]

这些参数必须为每个智能体$q$进行调优。

锚定与调整策略的出发点是人类行为,而不是任何证明其接近最优的依据。它的优点是简单、透明且直观。挑战始终在于可调参数,特别是目标值$R^{inv-trgt}$和$R^{transit-trgt}$,因为这些参数被呈现为静态参数,而实际上它们确实需要对条件变化做出响应。

前瞻策略

我们首先在第7章中提出了一个随机前瞻策略,但为便于参考,我们在此重新给出:

\[\begin{align} X^{DLA}(S_t) &= \argmin_{x_t\in\Xcal}\Big(C(S_t,x_t) + {} \nonumber \\ & \ \Etilde_{\Wtilde_{t,t+1}} \Big\{\min_{\tilde \pi} \E_{\Wtilde_{t,t+2}, \ldots, \Wtilde_{tT}} \Big\{\sum_{t'=t+1}^T C(\Stilde_{tt'},\Xtilde^{\tilde \pi}_t(\Stilde_{tt'}))\Big\vert \Stilde_{t,t+1}\Big\} \Big\vert S_t,x_t\Big\}\Big). \label{eq:policiesapproximateDLA2} \end{align}\]

方程$\eqref{eq:policiesapproximateDLA2}$可能特别令人望而生畏。图 11.2用一个基本的决策树说明了策略中的每个元素(所有这些都针对单一智能体$q$,我们在此省略了它)。存在一组从第一个决策节点$S_t$发出的决策$x_t$,之后我们对$\Wtilde_{t,t+1}$中的随机信息取期望。之后,我们对前瞻模型中的每个决策节点$\Stilde_{tt’}$使用一个近似的”前瞻策略”$\Xtilde^{\tilde \pi}(\Stilde_{tt’})$,通常我们以某种方式简化状态变量。我们还使用$\Wtilde_{tt’}$来近似未来到达的信息,无论是使用确定性前瞻模型,还是使用一组模拟的可能结果。

将前瞻策略图示为决策树。
图 11.2。将前瞻策略图示为决策树。

这个方程可以被理解为由两个部分组成:

要在我们的供应链背景下使用这一方法,我们必须模拟其他智能体的行为,同时意识到a) 我们不知道$q’ \ne q$的初始条件$R_{tq’}$,以及b) 我们不知道其他智能体是如何做出决策的。

为了处理我们对起始条件缺乏了解的问题,我们必须将其视为随机变量,并从某个分布中抽样(这隐藏在第一个$\Etilde_{\Wtilde_{t,t+1}}$中)。我们注意到,一个智能体可能存在这样的情况,例如没有库存,却有大量的延期订单。如果我们发现我们下的订单被填充所花的时间很长,我们或许能够猜测到这种情况正在发生。

然后我们必须模拟未知的策略。虽然我们正在为时间$t$的智能体$q$构建一个非常复杂的随机前瞻策略,但我们建议使用之前提出的更简单的策略,不仅对其他智能体如此,对未来时间段的智能体$q$也是如此。

那么,鉴于这些近似,随机前瞻策略是否会优于我们上面概述的更简单的策略之一?这将是一个很好的研究问题,但前瞻策略克服了更简单参数化策略的一个主要局限。具体来说,前瞻策略自然地捕捉了该系统的复杂状态,例如先前订单的历史以及对未来事件的任何预测。参数化策略适用于平稳问题,而前瞻策略则能自然适应可能高度非平稳的行为。

拓展

我们可以通过许多方式修改这个问题。一些想法包括:

1) 我们必须处理上游智能体的订单远大于(或者也许远小于)我们过去所见到的情况,这暗示着需求发生了系统性变化。我们可以引入对未来需求潜在增长的估计,以应对上游需求中意外的变化。

2) 我们可以维持关于上游智能体可能如何表现的信念。例如,如果智能体$q+1$维持充裕的库存,这会对智能体$q$有所帮助。我们可以通过在自己的请求中引入噪声来鼓励库存的积累,这将增加智能体$q+1$对智能体$q$所下订单不确定性的估计。

3) 每个智能体都会对缺货做出反应,并通过维持更高的库存来应对。智能体$q$可以在向$q+1$下的订单中引入一些噪声,这样$q+1$就会维持更高的库存,从而使得$q$的订单更有可能被填充。

4) 该游戏的许多敏感性都源于缺货成本相对于持有库存成本的高惩罚(回想一下,每箱延期订单每天的成本为4美元,而每箱持有库存每天的成本为1美元)。尝试将缺货成本从4美元改为1美元,然后再改为0.5美元。

我们学到了什么?

习题

习题

复习题

  1. 中间智能体的状态是什么?
  2. 每个智能体可以做出哪些决策?
  3. 对每个中间智能体而言,外源信息的来源有哪些?
  4. 哪些不确定性来源会影响该博弈的行为?
  5. 用文字解释一下"锚定与调整"策略是什么意思?其设计者是否期望这可能是一个好策略?

问题求解题

  1. 对上文提出的简单规则给出批评性评价。
  2. 假设市场需求偶尔(但并不频繁)会发生向更高或更低水平的转变。设计一个能够意识到这些转变可能发生的策略,这意味着供应链的其余部分也必须随之调整。你的策略将如何应对必然出现的产品短缺时期?
  3. 上文的前瞻策略一节仅给出了一个前瞻策略的粗略框架。请补充细节,详细写出一个具体的实现。