1. 業(yè)務(wù)背景
電子商務(wù)公司或傳統(tǒng)零售公司在生產(chǎn)銷售中, 一般會自建或租用多個倉庫來存儲商品. 這些倉庫一般分布在不同地區(qū)用來覆蓋區(qū)域中的客戶. 當(dāng)客戶下達(dá)訂單后, 商品一般會從客戶所在區(qū)域的倉庫發(fā)貨, 然后通過承運(yùn)商送達(dá)客戶手中. 由于不同客戶購買的商品和數(shù)量可能不同, 因此單個倉庫的商品可能會發(fā)生供需不均的情況.
例如, 某個商品在倉庫A發(fā)生了缺貨, 但在倉庫B卻可能產(chǎn)生積壓. 這樣一來, 倉庫A附近的客戶要么無法購買該商品, 因而公司會損失銷售利潤; 要么客戶成功下單, 但是商品會從比較遠(yuǎn)的倉庫B發(fā)貨, 從而造成更高的物流費(fèi)用和更長的運(yùn)輸時間.
為了增加銷售利潤, 降低供應(yīng)鏈的配送成本并提升配送時效, 我們希望倉庫出現(xiàn)缺貨或商品積壓之前, 對多個倉庫之間的商品執(zhí)行庫存平衡計(jì)劃. 尤其在電商業(yè)務(wù)中, 商品的種類多達(dá)上萬種, 因此供需不均的情況常有發(fā)生. 為了減少損失, 我們需要定期對所有倉庫和商品制定庫存平衡計(jì)劃, 然后對其合理性進(jìn)行驗(yàn)證, 最終實(shí)施計(jì)劃. 在實(shí)施過程中,我們不僅要考慮車輛調(diào)度成本還要考慮倉庫的處理能力等業(yè)務(wù)因素.
在這樣的背景下培愁,我們需要一套系統(tǒng)能實(shí)現(xiàn)如下功能:
- 計(jì)算庫存平衡計(jì)劃. 算法需要支持10萬+商品數(shù)量和1000+倉庫數(shù)量的計(jì)算.
- 計(jì)算調(diào)度方案. 包括商品的數(shù)量, 箱數(shù), 商品的流向(從哪來到哪去), 車輛安排等.
- 考慮復(fù)雜的業(yè)務(wù)約束. 在實(shí)際的執(zhí)行中, 由于倉庫人力有限, 車輛數(shù)量和容量有限等多種因素制約, 算法提供的調(diào)度計(jì)劃必須滿足實(shí)際的業(yè)務(wù)約束.
- 優(yōu)化業(yè)務(wù)目標(biāo). 算法的結(jié)果盡量使得業(yè)務(wù)目標(biāo)最優(yōu), 例如降低成本, 提高效率.
- 支持靈活的調(diào)撥策略. 不同商品, 不同時期可能有不同的業(yè)務(wù)目標(biāo), 因而需要不同的調(diào)撥策略. 這樣一來, 系統(tǒng)要求調(diào)度算法可插拔, 可配置.
2. 算法架構(gòu)
完整的算法架構(gòu)(圖1)主要從四個層面來考慮:
首先是數(shù)據(jù)層, 它包含了基礎(chǔ)數(shù)據(jù)(例如商品銷量和庫存), 業(yè)務(wù)數(shù)據(jù)(例如運(yùn)費(fèi), 倉庫的地理位置, 倉庫的處理能力等數(shù)據(jù)), 算法配置(參數(shù)配置, 模型配置)和計(jì)算結(jié)果(中間結(jié)果, 最終結(jié)果).
第二是算法層. 這是算法設(shè)計(jì)和實(shí)現(xiàn)的核心部分, 它包含了四個計(jì)算步驟: 需求計(jì)算, 需求平衡, 流向計(jì)算和車輛調(diào)度. 詳細(xì)的模塊介紹參考下文(第三節(jié)).
第三是分析層. 主要做兩塊工作: 一是分析數(shù)據(jù)輸入和算法輸出, 包括異常數(shù)據(jù)和統(tǒng)計(jì)結(jié)果(例如調(diào)度sku數(shù)量/車輛數(shù)/庫存狀態(tài)等); 二是對算法模型自身以及業(yè)務(wù)目標(biāo)的評估.
最后是接口層. 把所有功能封裝成統(tǒng)一的接口, 方便前端業(yè)務(wù)系統(tǒng)進(jìn)行調(diào)用.
3. 算法模塊介紹
算法流程如下圖所示.
下面我們分別介紹各模塊的功能.
3.1 需求計(jì)算
輸入: 商品在各倉庫的歷史銷量, 商品在各倉庫的當(dāng)前庫存和在途庫存.
輸出: 各倉庫中商品的多余量和不足量.
倉庫中商品的多余量和不足量稱為倉庫的需求. 一般來說, 倉庫的需求取決于商品的歷史銷量和業(yè)務(wù)目標(biāo). 商品的銷售速度越快, 需要準(zhǔn)備的庫存量也越大; 商品的重要性越高, 倉庫需要準(zhǔn)備的安全庫存也會越大. 此外, 大促期間(例如雙11)和平銷期間需求計(jì)算的方式也會有所區(qū)別.
綜上所述, 需求計(jì)算我們應(yīng)該注意以下幾點(diǎn):
- 需求計(jì)算一般依賴銷量預(yù)測, 但銷量是無法準(zhǔn)確預(yù)測的. 銷量預(yù)測不是最終目的, 它的輸出形式取決于需求計(jì)算的模型. 在實(shí)際中, 我們應(yīng)該在算法模型中充分考慮銷量的不確定性.
- 不同商品/不同時期的需求計(jì)算方式可能不相同.
3.2 需求平衡
輸入: 倉庫的需求(不足量/多余量).
輸出: 倉庫的需求使之滿足平衡性.
我們用一個例子來說明平衡性約束: 考慮一個商品和4個倉庫A,B,C,D. 其中倉庫A的多余量是200. 倉庫B, C, D的不足量分別是100, 200, 300. 此時"總多余量"與"總不足量"是不相等的, 因此需求是不平衡的. 需求平衡模塊的作用是用算法分配需求, 使得總多余量等于總不足量.
注意: 需求平衡的策略不應(yīng)該是唯一的, 實(shí)際執(zhí)行的平衡策略應(yīng)取決于業(yè)務(wù)目標(biāo).
3.3 流向計(jì)算
輸入: 倉庫的需求(滿足平衡性).
輸出: 商品流向, 即三元組 -- (調(diào)出倉庫, 調(diào)入倉庫, 商品的調(diào)撥數(shù)量)
我們用一個簡化的例子來說明流向計(jì)算問題(圖3):
問題 如何計(jì)算商品流向使得運(yùn)輸成本最低?
注意兩點(diǎn):
- 一般來說, 流向計(jì)算的業(yè)務(wù)目標(biāo)是降低運(yùn)輸成本. 輸入還應(yīng)該包含與業(yè)務(wù)目標(biāo)和約束相關(guān)的數(shù)據(jù)(例如單位運(yùn)費(fèi)).
- 實(shí)際業(yè)務(wù)中的限制條件可能更多, 應(yīng)該根據(jù)具體業(yè)務(wù)進(jìn)行建模.
3.4 車輛調(diào)度
輸入: 商品流向.
輸出: 各倉庫的車輛調(diào)度安排, 包含運(yùn)輸車輛和對應(yīng)的商品數(shù)量.
該模塊需要考慮較多的業(yè)務(wù)限制, 例如:
- 倉庫的處理能力(例如調(diào)撥商品總數(shù)量, 總體積數(shù))
- 商品的體積和包裝箱的容量
- 貨車的容量
- 貨車的成本
4. 分析模塊介紹
- 異常數(shù)據(jù): 監(jiān)控底層數(shù)據(jù)(例如歷史銷量, 庫存)是否出現(xiàn)異常. 如發(fā)現(xiàn)異常, 應(yīng)該處理異撤喂拢或報(bào)警, 避免導(dǎo)致庫存平衡和調(diào)度方案出錯.
- 統(tǒng)計(jì)報(bào)告: 輸出算法模塊的中間結(jié)果和最終結(jié)果, 包含算法模型, 參數(shù)相關(guān)的信息, 從而輔助業(yè)務(wù)方?jīng)Q策.
- 模型評估: 建立科學(xué)的計(jì)算指標(biāo), 用來評估算法模型的好壞.
- 收益分析: 根據(jù)業(yè)務(wù)指標(biāo)(例如成本的降低, 時效的提升), 評估算法產(chǎn)生的收益極其上界.