网易严选是一家自营电商,每天有数以万计的订单需要拣货、打包和出库。打包的过程就是把订单中的商品用包材进行包裹,常见的打包方式有缠膜、装袋和装箱。
袋子和箱子有不同的种类和型号,比如袋子有共挤膜袋、镀铝膜袋、塑料袋等。
仓库作业人员需要对商品按订单进行打包。具体来说,主要决策两件事:
第一,根据订单的商品选择正确的包材类型。比如服装毛巾等柔软的商品适合用袋子;易碎品、液体和贵重物品适合用纸箱;有些商品自身的包装结实耐磨,可以选择缠膜或者裸发。如果适用的包材类型有冲突,则选择优先级最高的包材。
第二,如果是装箱(或装袋),需要决定箱型(袋型)。我们要求纸箱的体积最小(袋子的面积最小),并且能装下订单中的所有商品。在实际情况中,如果订单中商品过多,系统会预先把大订单拆成多个子订单。
人工决策不仅效率低而且容易造成浪费。原因有两点:
第一,商品种类太多,人记不住正确的包材,只能凭经验判断。工人害怕出错,最保险的方法是一律使用纸箱,于是一些本来应该缠膜或装袋的订单,结果用纸箱打包。
第二,纸箱型号有三十多种,而且是折叠状态(如下图所示)。工人难以判断哪个纸箱是体积最小且能装下整个订单的商品,最保险的做法是选择较大的纸箱。
折叠状态的纸箱
这样的结果是浪费包材,增加履约成本。此外,纸箱的空间利用率不高,导致商品在运输中容易破损,引发客户投诉甚至是退换货。
在这样的背景下,我们需要一套包材推荐系统来解决上述包材浪费和空间利用率不高的问题。
系统的核心功能是实现订单的包材推荐,即给定订单中的商品列表,输出对应的包材型号。考虑到不同商品适用不同的包材类型,不同仓库有不同的包材列表,我们把这些业务限制称为约束条件。
为了满足多变的业务情况,包材推荐系统需要支持多种包材类型、约束条件和业务目标。
包材类型需要考虑优先级,包材按优先级向下兼容。比如袋子的优先级低于箱子,那么可以用袋子装的商品也可以用箱子,反之则不行。同一个订单中的商品适用的包材类型可能不同,系统会选择优先级最高的包材。
当前支持的包材类型如下所示。
在实际业务中,约束条件多样而且多变,因此系统中维护的约束条件需要可插拔。
考虑如下约束条件(取交集)。
业务目标是降低包材成本和提高包材的体积利用率。在计算最优包材的时候,可以选择成本优先,也可以选择体积利用率优先,或者是两者的加权。
包材推荐系统的整体架构如下图所示。
其中最核心的模块是装箱算法和装袋算法(红色部分)。黄色部分主要是算法相关的工程,主要用规则实现。灰色部分主要是前端展示和底层数据。
输入商品列表,输出包材类型和型号。算法的基本流程如下:
第一步:输入包材列表,包材选择器通过基础数据模块获得商品、包材、承运商、仓库等基础数据。
第二步:包材选择器根据约束条件得到订单对应的可用包材类型和型号列表。
第三步:算法选择器根据包材类型选择对应的算法进行求解。例如,包材类型是袋子,那么选择装袋算法。
第四步:输出算法的计算结果(包材类型和型号)。
装箱算法是包材推荐系统的核心算法。下面我们简单介绍一下装箱算法需要解决的问题。
把商品近似地看成长方体,然后测量商品的长宽高。
箱型选择问题
给定个纸箱,它们的长宽高为,;给定个物品,它们的长宽高分别为,。返回一个体积最小的纸箱,使得它能装下个商品。如果不存在这样的纸箱,则返回空。
注意:允许物品90度旋转。
可以把纸箱按体积从小到大排序,返回第一个能装下所有商品的箱型即可。这样一来,上面的问题可以简化成一个判定问题。
三维装箱判定问题
给定一个纸箱,它的长宽高为;给定个物品,它们的长宽高分别为,。判断所有物品是否能装入纸箱。
袋子在几何上是一个三维流形,通俗地讲,袋子是软的。它可以捏成奇奇怪怪的形状,精确地建模和求解显得非常困难。
我们的做法是先把袋子看成“两层”的矩形薄膜,长宽为,(厚度为0)。
然后把它捏成长方体,长宽高记作,如下图所示。
其中阴影部分代表上层的“膜”,白色部分代表下层的“膜”。长宽高满足如下条件:
这样一来,通过规则适当地枚举的可能性,我们把装袋问题近似地转化成上面的装箱问题。
我们一般假设普通物品不可折叠,但在实际情况中,很多物品是柔性的,例如服装。这不仅会增加建模和求解的难度,还让测量更复杂。
假设柔性物品有 种尺寸,,要求所有尺寸对应的体积相同,即 , 。这样一来,普通物品可以看成只有一种尺寸的柔性物品。
在实际的测量中,我们可以要求测量人员用两到三种折叠方式测量物品的长宽高。通过这种方式,我们把柔性物品的装箱问题转化成了普通物品的装箱问题。
装箱算法结果需要满足真阳性:算法说能装下就能装下;算法说装不下,可以允许出错。设计装箱算法时,我们考虑了多个精确算法和启发式算法,由于篇幅有限,这里不介绍具体的装箱算法。
效果评估主要分为两个方面:一是业务效果,二是算法效果。最重要的当然是业务效果,算法效果的评估是为了改进算法,从而更好地提升业务效果。
如前文所述,业务关心两个指标:包材成本和空间利用率。由于测量存在误差,还需要追踪基础数据和算法的异常。我们通过对比“推荐的”和“实际使用的”包材型号来分析问题。
推大用小:算法推荐的箱型比实际箱型大。说明人工经验比算法结果好,对成本节省有利。从另一个方面也说明算法可能有优化的空间。
推小用大:算法推荐的箱型比实际箱型小。说明数据测量有问题或者人工操作不规范。这种情况下需要重点检查数据的准确性以及加强对操作人员的培训。
推用一致:算法推荐的箱型与实际箱型一致。基础数据越准确,人工操作越规范,算法效果越好,于是“推用一致”的占比就越高。
装箱算法的效果主要从两个方面衡量:一是计算效率,我们要求单个请求的响应时间不超过1秒;二是计算效果,用准确率来衡量,比如计算一批三维装箱判定问题的实例,然后评估正确回答的占比。
计算效果的衡量并不简单。原因在于三维装箱判定问题的计算复杂性是 NP-hard,这意味着它不存在多项式时间的精确算法(在 的假设下)。
通俗地说,如果想要准确求解,那么随着物品数量的增加,计算需要的时间呈指数增长。例如,当物品的数量增加到十多个,计算时间可能是分钟、小时甚至是天的级别。
既然不知道装箱问题的正确答案,那么如何测试效果?
需要用一些方法构造三维装箱问题的实例,保证构造的实例符合预设的答案。可以考虑四种方法:
第一,根据箱型的可用空间进行随机切分,从而保证切分出的物体始终能装入该箱型;
第二,随机生成三维物品和摆放位置,保证物品摆放的长宽高不超过箱子的长宽高;
第三,随机生成三维物品,然后用精确算法进行求解(适用于物品数量较少的情况)。
第四,用真实的订单数据进行测试。虽然有测量误差和物品形状的干扰,但可以用来横向比较算法之间的差异。
包材推荐系统支持了网易严选数亿包裹的打包。系统上线后经历了业务的千锤百炼,例如大促发货、仓库新增、承运商变更、包材型号变更、商品上下架等等,系统的稳定性、扩展性和业务效果全部达到预期。
包材推荐系统主要解决人工选材导致的包材浪费和空间利用率不高的问题。
站在企业的角度,包材推荐系统不仅节省了物流成本,还提升了打包效率;站在用户的角度,空间利用率的提升减少了投诉;站在社会的角度,该系统增加了裸发、缠膜和塑料袋的包裹量,从而减少了纸箱的浪费。