1. 业务背景
电子商务公司或传统零售公司在生产销售中, 一般会自建或租用多个仓库来存储商品. 这些仓库一般分布在不同地区用来覆盖区域中的客户. 当客户下达订单后, 商品一般会从客户所在区域的仓库发货, 然后通过承运商送达客户手中. 由于不同客户购买的商品和数量可能不同, 因此单个仓库的商品可能会发生供需不均的情况.
例如, 某个商品在仓库A发生了缺货, 但在仓库B却可能产生积压. 这样一来, 仓库A附近的客户要么无法购买该商品, 因而公司会损失销售利润; 要么客户成功下单, 但是商品会从比较远的仓库B发货, 从而造成更高的物流费用和更长的运输时间.
为了增加销售利润, 降低供应链的配送成本并提升配送时效, 我们希望仓库出现缺货或商品积压之前, 对多个仓库之间的商品执行库存平衡计划. 尤其在电商业务中, 商品的种类多达上万种, 因此供需不均的情况常有发生. 为了减少损失, 我们需要定期对所有仓库和商品制定库存平衡计划, 然后对其合理性进行验证, 最终实施计划. 在实施过程中,我们不仅要考虑车辆调度成本还要考虑仓库的处理能力等业务因素.
在这样的背景下,我们需要一套系统能实现如下功能:
- 计算库存平衡计划. 算法需要支持10万+商品数量和1000+仓库数量的计算.
- 计算调度方案. 包括商品的数量, 箱数, 商品的流向(从哪来到哪去), 车辆安排等.
- 考虑复杂的业务约束. 在实际的执行中, 由于仓库人力有限, 车辆数量和容量有限等多种因素制约, 算法提供的调度计划必须满足实际的业务约束.
- 优化业务目标. 算法的结果尽量使得业务目标最优, 例如降低成本, 提高效率.
- 支持灵活的调拨策略. 不同商品, 不同时期可能有不同的业务目标, 因而需要不同的调拨策略. 这样一来, 系统要求调度算法可插拔, 可配置.
2. 算法架构
完整的算法架构(图1)主要从四个层面来考虑:
首先是数据层, 它包含了基础数据(例如商品销量和库存), 业务数据(例如运费, 仓库的地理位置, 仓库的处理能力等数据), 算法配置(参数配置, 模型配置)和计算结果(中间结果, 最终结果).
第二是算法层. 这是算法设计和实现的核心部分, 它包含了四个计算步骤: 需求计算, 需求平衡, 流向计算和车辆调度. 详细的模块介绍参考下文(第三节).
第三是分析层. 主要做两块工作: 一是分析数据输入和算法输出, 包括异常数据和统计结果(例如调度sku数量/车辆数/库存状态等); 二是对算法模型自身以及业务目标的评估.
最后是接口层. 把所有功能封装成统一的接口, 方便前端业务系统进行调用.
3. 算法模块介绍
算法流程如下图所示.
下面我们分别介绍各模块的功能.
3.1 需求计算
输入: 商品在各仓库的历史销量, 商品在各仓库的当前库存和在途库存.
输出: 各仓库中商品的多余量和不足量.
仓库中商品的多余量和不足量称为仓库的需求. 一般来说, 仓库的需求取决于商品的历史销量和业务目标. 商品的销售速度越快, 需要准备的库存量也越大; 商品的重要性越高, 仓库需要准备的安全库存也会越大. 此外, 大促期间(例如双11)和平销期间需求计算的方式也会有所区别.
综上所述, 需求计算我们应该注意以下几点:
- 需求计算一般依赖销量预测, 但销量是无法准确预测的. 销量预测不是最终目的, 它的输出形式取决于需求计算的模型. 在实际中, 我们应该在算法模型中充分考虑销量的不确定性.
- 不同商品/不同时期的需求计算方式可能不相同.
3.2 需求平衡
输入: 仓库的需求(不足量/多余量).
输出: 仓库的需求使之满足平衡性.
我们用一个例子来说明平衡性约束: 考虑一个商品和4个仓库A,B,C,D. 其中仓库A的多余量是200. 仓库B, C, D的不足量分别是100, 200, 300. 此时"总多余量"与"总不足量"是不相等的, 因此需求是不平衡的. 需求平衡模块的作用是用算法分配需求, 使得总多余量等于总不足量.
注意: 需求平衡的策略不应该是唯一的, 实际执行的平衡策略应取决于业务目标.
3.3 流向计算
输入: 仓库的需求(满足平衡性).
输出: 商品流向, 即三元组 -- (调出仓库, 调入仓库, 商品的调拨数量)
我们用一个简化的例子来说明流向计算问题(图3):
问题 如何计算商品流向使得运输成本最低?
注意两点:
- 一般来说, 流向计算的业务目标是降低运输成本. 输入还应该包含与业务目标和约束相关的数据(例如单位运费).
- 实际业务中的限制条件可能更多, 应该根据具体业务进行建模.
3.4 车辆调度
输入: 商品流向.
输出: 各仓库的车辆调度安排, 包含运输车辆和对应的商品数量.
该模块需要考虑较多的业务限制, 例如:
- 仓库的处理能力(例如调拨商品总数量, 总体积数)
- 商品的体积和包装箱的容量
- 货车的容量
- 货车的成本
4. 分析模块介绍
- 异常数据: 监控底层数据(例如历史销量, 库存)是否出现异常. 如发现异常, 应该处理异常或报警, 避免导致库存平衡和调度方案出错.
- 统计报告: 输出算法模块的中间结果和最终结果, 包含算法模型, 参数相关的信息, 从而辅助业务方决策.
- 模型评估: 建立科学的计算指标, 用来评估算法模型的好坏.
- 收益分析: 根据业务指标(例如成本的降低, 时效的提升), 评估算法产生的收益极其上界.