经济采购优先化


首页 » 资源 » 此处

相比较传统的预测方法,概率预测可针对未来提供更细粒化的洞察,并激发我们重新思考整个订货过程。在本文中,我们将详细介绍如何利用 Lokad 生成采购优先级列表。与再订货点相比,这种方法的主要优势有两点:不必再维护和微调服务水平;采购方法更灵活、对供应限制的适应更出色。

采购优先级列表是对库存实施[cn.优先-订购-定义|优先订购策略的一个范例。相比传统库存策略,这些类别广泛的库存策略可以提供卓越的库存绩效。在适用情况下,Lokad 建议您采用优先订购策略。

优先级列表的脚本模板

为了生成优先级列表,我们需要使用一小段 Envision 脚本(见下文)。这段脚本可以在您的 Lokad 帐户中利用创建 Envision 脚本按钮来创建。创建新项目后,系统会显示源代码编辑器。请复制并粘贴下面的代码,然后单击保存

read "/sample/Lokad_Items.tsv" with Supplier: text, Category: text, SubCategory: text
read "/sample/Lokad_Orders.tsv" as Orders
read "/sample/Lokad_PurchaseOrders.tsv" as PO

orderingLeadtime := 7 // 7 days

where PO.DeliveryDate > PO.Date // exclude non-delivered POs
Leadtime = forecast.leadtime(
hierarchy: Category, SubCategory
present: (max(Orders.Date) by 1) + 1
leadtimeDate: PO.Date
leadtimeValue: PO.DeliveryDate - PO.Date + 1)

Demand = forecast.demand(
horizon: Leadtime +* dirac(orderingLeadtime)
hierarchy: Category, SubCategory
present: (max(Orders.Date) by 1) + 1
demandDate: Orders.Date
demandValue: Orders.Quantity)

show form "Purchase simulator" a1b3 tomato with Form.budget as "Max budget"

M = SellPrice - BuyPrice
S = - 0.25 * SellPrice // stock-out penalty
C = - 0.3 * BuyPrice * mean(Leadtime) / 365 // % '0.3' as annual carrying cost
MB = 0.5 * SellPrice // back-order case
SB = 0.5 * SellPrice // back-order case
AM = 0.3 // opportunity to buy later
AC = 1 - 0.2 * mean(Leadtime) / 365 // % '0.2' as annual economic discount

RM = MB * uniform(1, Backorder) + (stockrwd.m(Demand, AM) * M) >> Backorder
RS = SB * uniform(1, Backorder) + zoz(stockrwd.s(Demand) * S) >> Backorder
RC = (stockrwd.c(Demand AC) * C) >> BackOrder
R = RM + RS + RC // plain recomposition

table G = extend.distrib(Demand >> BackOrder, StockOnHand + StockOnOrder, LotMultiplier)

where G.Max > StockOnHand + StockOnOrder
G.Q = G.Max - G.Min + 1
G.Reward = int(R, G.Min, G.Max) // integral of the stock reward function
G.Score = G.Reward / max(1, BuyPrice * G.Q)

G.Rank = rank(G.Score, Id, -G.Max) // top scores first, but preserve ordering of pairs (Id, G.Max)
G.Invest = cumsum(BuyPrice * G.Q, G.Rank)

where G.Invest < Form.budget + 0
where exists(G.Q)
show table "Purchase priority list with $\{Form.budget}" c1g3 tomato with
Id as "Id"
Supplier as "Supplier"
StockOnHand as "OnHand"
StockOnOrder as "OnOrder"
sum(G.Q) as "Qty"
mean(Leadtime) as "Leadtime"
sum(G.Reward) as "Reward" unit:"$"
sum(BuyPrice * G.Q) as "Cost" unit:"$"
group by Id
order by avg(G.Score) desc

这段脚本将生成包含一个表的仪表板。供应链专员应根据列表的顺序来采购所建议的项目。所建议的数量考虑了缺货通知单批次倍数

Image

我们来看一下脚本的内容。前 4 行为文件阅读说明。具体地说,您在 /hello 文件夹中可以找到文件,但可能要进行调整以便放入实际的文件夹。Lokad_Items.tsvLokad_Orders.tsv 文件包含的历史数据用于最初生成预测值。预测值保存在 Lokad_Grid.tsv 文件中。 我们来看一下脚本的内容。最上面的一行是从样本文件所在的 /sample 文件夹读取数据。

在包含产品列表或 SKU 的 Lokad_Items.tsv 文件中,假定有以下两个"特殊"的列:

  • SellPrice:销售单价(不含税)
  • BuyPrice:采购单价(不含税)

调整脚本以确保从正确的输入文件夹提取数据后,且假定提供的 SellPriceBuyPrice 字段符合我们的技术的预期,则可以单击运行按钮。系统将执行脚本,并生成包含一个大表的仪表板。单击此表,在屏幕底部,会显示以 Excel 表的格式下载此表的选项。

在这段脚本的最上方,分别针对预测交付周期和预测需求调用了 Lokad 概率预测引擎两次。

然后引入几个与计算库存效益函数相关的经济变量:
  • M:库存中供应的每个库存单位的奖赏(毛利润)。
  • S:库存无法满足需求时每个库存单位的惩罚。
  • C:每个库存单位的单位年度持有成本。
  • AM:边际部分的折扣系数。
  • AC:承载成本部分的折扣系数。

优先级逻辑的核心在于计算 G.RewardG.Score
  • G.Reward:表示与库存中 G.Q 个额外库存单位相关的预期经济效益(G.Q 通常等于 1)。
  • G.Score:表示投入库存的每一美元与收益额的比率。

紧随其后的 where 过滤器用于将再订货点低于当前存货水平的情形排除在外。之所以排除这些情形,是因为我们只考虑旨在获取更多存货的采购场景。在此代码块中,将继续执行第二个用于驱动优先化的计算序列:

  • G.Rank:根据网格条目的计分对所有网格条目排序。但排序操作要进行调整:每个项目的顺序很大程度上与再订货点相一致。
  • G.Invest:说明如何创建累积计算。在这里将计算总投资(累积),计算的前提是假定根据列表顺序来采购每个项目。

脚本的最后是 show table 语句,网格中的所有行通过 Id 聚合,以使每个项目在列表中只出现一次。

提炼优先级



上述脚本对于库存效益计算中使用的经济变量做出了略微简单的假设。并非所有的项目都具有相同的持有成本。有些项目可能易腐,有些项目可能体积庞大等等。有关这类成本的更实际的假设,请参阅存货成本页面。实际上我们发现,大部分商家都有系统地低估了存货成本。根据我们的经验,年度持有成本低于 25% 是很可疑的。

刚开始阅读脚本时可能稍显枯燥。事实上我们发现,要想实施顺应贵公司的假设,这是仅有的能灵活处理的方法之一。Envision 脚本提供有 Excel 表中通常具备的可表达性。

在利润方面,上述脚本单纯地将毛利润最大化。但是,如果某些利润较低的项目生成了许多规模较小,但是盈利性高很多的销售(例如客户购买一部智能手机的毛利润为 2.5%,但购买两个电话配件的毛利润为 50%)时,就会对您的企业产生不利影响。在此情况下,您可以引入一个"信誉"系数,该系数通过应用于此类旗舰项目的递延利润来表示。

根据我们的经验,优先级的设置几乎与企业一样多,优先级反映了定义您企业的特定组合。如果您需要获得更多支持,请随时