envision 供应商价格间断

供应商价格间断


首页 » 资源 » 此处

价格间断或数量折扣表示商品的边际单价随考虑购买的数量而异。一般来说,为了激励客户购买更多产品,采购数量越多,单价越低。供应商提供价格间断时存在一种经济刺激,采购数量将相应调整以充分利用这些价格间断。Envision 为供应商价格间断提供广泛支持。在本节,我们将详细介绍如何从采购优化角度对价格间断建模。


价格间断的表格表示

表示产品列表价格间断的最常见方式就是创建一个包含 3 列的表格:

  • Id:产品标识符
  • MinQuantity:为达到单价条件所需采购的最低数量
  • Price:产品的采购单价

为了保持表格一目了然,在考察某种指定的产品时,表格中的行通常按升序对数量排序。这种排序方式有助于明确折扣幅度。

这种表示存在负边际单价的趋势,即多购买一件可能导致总价降低。

假设产品 A 以单价 1 欧元进行销售。产品 A 在数量达到 50 件时存在价格间断,即价格降至每件 0.9 欧元。购买 46 件的价格是 46 欧元,而购买 50 件只需花费 45 欧元。因此,购买 46 至 49 件之间的任意件数是没有经济刺激的,因为购买 50 件反而更便宜。第 50 件产品的边际单价就是 -4 欧元。

些负边际价格就是对价格间断采用基本数据模式的结果。一些精心设计的价格间断模式能够消除这些负边际价格,但是这些模式超出了本节的范畴。

在下面,我们假设可以通过上述表格获得价格间断数据。

pricebrk() 函数

Envision 中 pricebrk() 函数的目的是将表格形式的价格间断数据转换为表示边际件数费用的分布。语法如下:
expect Prices[Id, *] // 'Prices' is the price break table
B = pricebrk(Demand, Price, Prices.MinQuantity, Prices.Price, Stock, StockPrice)
此函数返回边际采购单价的分布,也即购买第 k 件产品所要支付的价格。此函数略显复杂,下文将详细介绍和证明其复杂性。

其参数包括:
  • Demand 是一种分布,从数学的意义上说,其作用是为要返回的分布选择一种支持。这种分布的值不使用,但返回的分布至少会调整得和 Demand 一样精准。
  • Price 为数值,解译为产品的默认单价。如果最小数量 1 没有价格间断,则使用此值;原因是价格间断从大于 1 的值开始,或者该种产品根本没有价格间断。
  • Prices.MinQuantity 为价格间断行适用的最小数量。必须为大于或等于 1 的整数。不允许重复。
  • Prices.Price 为该价格间断行的单价。它适用于所有采购件数,而不只是超过 Prices.MinQuantity 的件数。它必须为 Prices.MinQuantity 的递减函数。
  • Stock 为可用的产品库存。非零值意味着只需采购较少件数即可达到规定的库存水平,这也就意味着较难达到价格间断。此参数为可选参数,必须为非负整数。在忽略此参数的情况下,StockPrice 也应当忽略。忽略此参数时,默认值为零。
  • StockPrice 为库存中现有产品件数的单价。忽略此参数时,默认值为零。

Price 参数只是一种语法糖而已,用于处理价格间断表只涵盖真正受益于价格间断的产品的情形。通过这个参数,我们就可以避免将表 Price 扩展为每种产品至少一行。

分布解析

pricebrk() 的第一个参数必须是分布,因为 Envision 中的分布并非任意精度。实际上,对 Envision 中的分布解析存在多种实际限制。但是,从指定供应商处获得的价格间断,其范围可能介于采购 1 件和采购(理论上)1000 万件之间。pricebrk() 函数使用 Demand 分布的目的是调整相关区间所返回分布的解析。

当然,Envision 防止的一个陷阱是:当目标价格间断为 1000 件时,库存优化逻辑不会最终给出采购999 件的建议。如果 Envision 生成的分布没有从内部区分 999 件和 1000 件时的价值,可能就会发生这种情况。通过传递分布给 pricebrk() 函数,Envision 可以对返回的分布采用这种解析,从而避免此种特殊情形。

订购空间 vs 库存空间

价格间断表是从订购角度组织的,关联了单位采购价格与各个采购数量。但是,库存优化角度是从库存角度组织的:当我们考虑多增加 1 件存货时,我们应当考虑现有库存,也就是库存空间pricebrk() 函数可以将价格间断表示由原始订购空间转化为库存空间。

这种转化就是 pricebrk() 将库存水平和库存单价这两个参数与库存关联起来的原因。这两个参数用于将边际价格分布转变为按库存单位分布。对分布运用正则移位算子 >> 可以完成这样的转变,但重申一次,这可能触发次要近似值与价格间断阈值相冲突的情形。pricebrk() 函数内在化了这种转变,从而可以消除这些近似值。

边际单位成本

pricebrk() 返回的分布表示边际单位采购成本。[1;Stock] 部分关联当前库存和 StockPrice。如果 B 是由 pricebrk() 返回的分布,那么整数 int(B, Stock + 1, Stock + N) 就是采购N件超出库存现有件数时的总成本。

如上所述,价格间断表常常关联负边际单位成本,即多采购一件时的成本为负的情形。由 pricebrk() 返回的分布通过局部负值反映了这些情况。这些负值是一致的,它们是价格间断数据模式的直接后果。

结合价格间断与库存效益

库存效益函数可以计算出库存中每多一件产品时的边际经济收益分布。在前一节里,我们看到了这个函数与表示毛利润、缺货损失以及储运成本的经济变量的关系。在之前的讨论中,这些经济变量为纯数字。但在涉及价格间断时,这些经济变量连同订购数量也会变化。这些变化很容易通过分布来建模。
B = pricebrk(Demand, BuyPrice, Prices.MinQuantity, Prices.Price, Stock, StockPrice)

M = SellPrice - B // 'M' is a distribution
S = -0.5 * (SellPrice - B) // 'S' is a distribution
C = -0.3 * B * mean(Leadtime) / 365 // 'C' is a distribution
AM = 0.3
AC = 1 - 0.2 * mean(Leadtime) / 365

RM = stockrwd.m(Demand, AM) * M // point-wise multiplication
RS = stockrwd.s(Demand) * S // idem
RC = stockrwd.c(Demand, AC) * C // idem
R = RM + RS + RC 
这个代码块与最初那个代码块之间的主要差别在于引入库存效益函数 BuyPrice 时。列 BuyPrice 转变为第 1 行至函数 pricebrk() 的价格间断分布 B。其余脚本的作用是直接应用分布代数,所有复杂工作都由分布代数来替我们完成。

在第 3 – 5 行,经济变量转变为分布。实际上,常数与分布相加的结果就是分布。常数与分布相减的结果也是分布。上面的 M单位边际效益(即边际利润),而随着数量的增多,价格间断通常会获得更低的单价,因此分布 M 也会增大。

在第 9 -11 行,库存效益函数的分量关联经济分布(而不是数字),但语法是相同的。透过表面,它的实质就是在分布之间进行的点乘。最后是在第 12 行构建最终的库存效益,之前我们已进行过这项操作。