首页 »
知识库 » 此处
作者:Joannès Vermorel,2016 年 1 月MOQ(最小订单量)是供应链中一种普遍存在的订货限制形式。MOQ 限制意味着供应商不会接受低于指定阈值(通常用金额-美元或件数来表示)的采购订单。多种 MOQ 限制往往并存并且必须同时满足这些限制。一般 MOQ 问题包括计算(接近)最佳采购订单,此类订单既要满足所有 MOQ 限制,同时又要实现所购产品件数的经济回报最大化。
一般 MOQ 问题在形式上属于一种非线性的优化
难题。这个问题之所以被划定为
难题,是因为计算
最佳解决方案通常超出了计算的范畴,这一点是可以证明的。但是,尽管通常无法获得最佳解决方案,但可以通过高级的非线性约束求解算法来获得接近最佳的解决方案。我们将在下文介绍
moqsolv
,这是一种由 Lokad 提出的用于解决一般 MOQ 问题的高级数值解算器。
常见的 MOQ 限制
MOQ 限制可以多种形式存在。在实际供应链中,我们遇到的常用 MOQ 限制有:
- 按每个 SKU 件数表示的最小数量,通常反映的是项目价格太低,因而无法单独出售。
- 按整个采购订单的金额(美元)表示的最低数量,当订单金额达到一定数量时供应商不会收取运输费用。
- 按项目类别件数表示的最小数量,常见于以最小数量批量生产产品以供订购的情况。
一次处理一种限制往往很简单。但是,如果需要同时考虑多种 MOQ 限制,那么创建能同时满足所有这些限制的采购订单就非常难了。
MOQ 概念
在深入研究数值优化问题前,我们先来介绍与一般 MOQ 问题相关的重要概念。这些概念有:
- 项目,表示可以实际购买的产品。尽管在这方面没有任何限制,但项目数量通常为整数。
- 每种项目的订货量(可能为 0),它表示 MOQ 问题的一种潜在解决方案。
- 每种项目额外增加一件所产生的相关效益 – 可通过 stockrwd 函数(库存效益函数)获取,但并不要求必须使用该函数。
- 所购件数的相关成本。其目标是最大化给定经费预算(表示为“成本”)的效益。成本通常按单位成本考虑并且是固定的,但在此处我们不会做任何假设;另外也要考虑价格间断。
- 目标表示指定某种停止标准的方式(可能并非实际成本)。这一点相当复杂,下文会进行详细介绍。
在按照
采购优先级列表进行采购时,典型的停止标准是定义一个
最高预算:所购件数的 ROI 递减,直至整个采购预算花完为止。但是,预算上限并不能说明可以获取的绝对库存绩效。因此,虽然目标仍然是优化 ROI,但不论考虑的是何种停止标准,再考虑一种备选标准是完全可行的,例如总体
供货率目标。
在处理
优先订货策略时,引入了
目标的概念来定义备选的停止标准。简单地说,目标变成了寻找能够为最小投资实现最高 ROI,同时又要满足该
目标的采购订单。在下面,我们将为这个优化过程提供更精确的定义。
示例:Frank 是一名供应链经理,他制定的供货率目标为 90%。解决这道 MOQ 问题涉及到计算最小订单(成本),同时实现效益最大化,并达到 90% 的供货率。该订单并非是尽可能小且能达到 90% 供货率的订单,因为这样将变成纯粹的供货率优先化。而是最小的订单,同时要以效益为先,即订单要足够大到实现 90% 的供货率。纯粹的供货率优先化是错误的,因为与库存效益不同,它没有考虑产生积压库存所导致的成本。
一般 MOQ 问题的形式定义
本节将把一般 MOQ 问题作为一种正式的非线性优化问题进行介绍。证明该问题为
NP-hard 相对简单。实际上,一般 MOQ 问题是对
装箱问题的延伸,后者同样也具有 NP-hard 的特点。因此,一般 MOQ 问题至少和装箱问题一样难。尽管这个问题是 NP-hard,必须要提的是它可以计算出很合理的解。
令 $I$ 为考虑订购的项目集合。
令 $q_i$($i \in I$)为项目 $i$ 的订购数量。
然后,定义几个函数。
- 令 $r_i(q)$ 为持有 $q$ 件 $i$ 项目时的效益。
- 令 $c_i(q)$ 为购买 $q$ 件 $i$ 项目时的成本。
- 令 $t_i(q)$ 为持有 $q$ 件 $i$ 项目时的目标。
效益函数可以返回正值或负值,但是,成本和目标函数严格为正:
$$\forall i, \forall q, c_i(q) > 0 \text{ and } t_i(q) >0$$
令 $M$ 为 MOQ 限制集合。对于每个 $m \in M$,令 $I_m$ 为属于限制 $m$ 的项目列表,$Q_m$ 为满足该限制所应达到的最小数量。令 $m_i(q)$ 为购买 $q$ 件项目 $i$ 时这些项目对于 MOQ 限制 $m$ 的贡献。如果满足以下条件,则可以认为满足限制 $m$:
$$\forall i \in I_m, q_i = 0 \text{ or } \sum_{i \in I_m}m_i(q_i) \geq Q_m$$
因此,所有 MOQ 限制均可通过这两种方式来满足:达到 MOQ 阈值,或者令所有项目的数量为 0。
然后,再令 $C$ 为该采购订单所能提供的最大成本。我们可以定义 $\textbf{q}_C=(q_i)_i$,因为:
$$\textbf{q}_C = \underset{q}{\operatorname{argmax}} \left\{ \sum_i r_i(q_i) \text{ with $m$ satisfied } \forall m\in M \right\}$$
就最大化给定预算的效益而言,该采购订单是"最佳"订单。解 $\textbf{q}_C$ 并非唯一,但是,这种考量相当理论化,因为 MOQ 问题很复杂,不是一个解就能解决的。为了简单起见,下文我们会将该解作为唯一的解来处理。
最后,令 $T$ 为目标最小值,并根据以下公式定义 $\textbf{q}^T$
$$C^T = \underset{C}{\operatorname{min}} \left\{ \left(\sum_{q_i \in \textbf{q}_C} t_i(q_i) \right) \geq T \right\}$$ 和
$$\mathbf{q}^T = \textbf{q}_{C^T}$$
解 $\mathbf{q}^T$ 基于 $\textbf{q}_C$,也就是说,它就是最小、最佳(预算级),能实现 ROI 最大化,同时也能实现该目标的解。
Envision 中的 moqsolv
函数
Envision 提供了专门用于解决一般 MOQ 问题的非线性解算器。该解算器可以通过函数
moqsolv
访问,在处理 MOQ 限制时不必再进行复杂的数值计算。函数
moqsolv
用于处理一系列与
Id(*)
类型的表相关的向量,此类表通常通过
extend.distrib()
扩展分布向量来获得(另请参阅
分布代数)。
这个函数的参数如下:
moqsolv(Id, Min, Reward, Cost, Target, threshold, g0, oq0, moq0, g1, oq1, moq1, ...)
其中,
Id
为项目组列Min
为单元订购列 – 与 Grid.Min
中一样Reward
为该行的效益 – 与通过库存效益函数 stockrwd
所获得的结果一样Cost
为该行的成本 – 通常为 PurchasePrice * Grid.Q
Target
为目标数量 – 对于简单的预算限制,它可以等于 Cost
。通过设置 Target == Cost
,可令解算器执行预算优化(相应地,Target != Cost
则为目标优化)。threshold
为一个标量值,用作目标的阈值。如果是进行预算优化,目标值为与解相关的成本上限。如果是目标优化,目标值则为与解相关的目标下限。如果阈值为负,那么负号会解读为布尔标志,用于从下面接近(正)目标,而不是从上面接近目标。阈值的符号仅用于控制不等式的方向,阈值始终解读为正数。g0, oq0, moq0
表示与各个 MOQ 限制相关联的三组向量(下文会详细介绍)。
另请参阅
具有订货限制的优先订货,该指南说明了如何使用
moqsolv
函数来创建满足 MOQ 限制的采购订单。
该函数返回一个
bool
向量,其中所有位于目标之内的行被标记为
true
。所有为
true
的行的组合即表明满足 MOQ 限制。如上一节中的定义,解算器求出了 $\textbf{q}^T$ 的近似解。从上一节中介绍的定义可以看出,参数
Cost
、
Target
和
threshold
应严格为正。
每个 MOQ 限制通过以下三个向量定义:
G
MOQ 表示 MOQ 分组,对于根据项目进行的 MOQ,它可以等于 Id
OQ
表示该行对于 MOQ 限制的订单数量的贡献。MOQ
表示为了满足 MOQ 限制而应达到的阈值。
由
G
定义的组应定义
部分项目标识符。在所有具有相同
G
值的行中,MOQ 阈值应当相同。所有
OQ
贡献值应当严格为正。
MOQ
值应当为正,但也可以为零,以反映出
没有实际的 MOQ 限制。
通过包含多个三组式向量,可以指定多个 MOQ。Envision 最多支持 4 个并存的 MOQ 限制。