AI在智能仓储中的应用:从库存预测到拣货路径优化的技术复盘

发布时间:2026/7/25 2:53:29
AI在智能仓储中的应用:从库存预测到拣货路径优化的技术复盘 AI在智能仓储中的应用从库存预测到拣货路径优化的技术复盘仓储智能化不是堆算法而是把每个决策点的几秒钟优化加起来——拣货员每天走3万步降到1.8万步这就是AI的价值。一、仓储的四个AI决策点2023年我们参与了一个日订单量5万单的电商仓储改造项目。仓库面积2万平米SKU超过15万个拣货员120人日均出库8万件。核心痛点库存周转慢、拣货路径长、爆仓与断货交替出现。我们将仓储AI化拆解为四个独立又关联的决策问题库存预测每个SKU未来N天的需求量是多少安全库存每个SKU应该备多少安全库存拣货路径一张拣货单上的20个SKU最优行走路径是什么AGV调度50台AGV如何协同不碰撞且效率最高二、库存需求的时序预测我们选用了两种模型做对比2.1 Prophet vs DeepARimport pandas as pd from prophet import Prophet from gluonts.model.deepar import DeepAREstimator from gluonts.mx import Trainer class InventoryForecastService: 库存需求预测 Prophet: 适合有明显季节性和趋势的SKU DeepAR: 适合SKU数量多且需要联合建模的场景 def forecast_with_prophet(self, sku_id: str, history: pd.DataFrame, periods: int 30) - pd.DataFrame: Prophet单SKU预测适合TOP 3000高频SKU df history[[ds, y]].copy() model Prophet( growthlinear, yearly_seasonalityTrue, weekly_seasonalityTrue, daily_seasonalityFalse, changepoint_prior_scale0.05, seasonality_prior_scale10.0, holidaysself._build_holidays_df(), # 618/双11/年货节 interval_width0.90 # 90%置信区间 ) # 添加促销事件作为额外回归器 df[is_promotion] history[is_promotion].values model.add_regressor(is_promotion, modeadditive) model.fit(df) future model.make_future_dataframe(periodsperiods, freqD) future[is_promotion] self._get_future_promotions(periods) forecast model.predict(future) # 返回预测分位数用于安全库存计算 return forecast[[ds, yhat, yhat_lower, yhat_upper]].tail(periods) def forecast_with_deepar(self, sku_list: List[str], history_dict: Dict[str, pd.DataFrame], periods: int 30) - Dict[str, pd.DataFrame]: DeepAR多SKU联合预测适合长尾SKU # 构建GluonTS数据集 from gluonts.dataset.common import ListDataset train_data [] for sku_id in sku_list: series history_dict[sku_id] train_data.append({ start: series[ds].min(), target: series[y].values, feat_static_cat: [self._get_category_id(sku_id)], item_id: sku_id }) estimator DeepAREstimator( freqD, prediction_lengthperiods, context_lengthmin(90, len(series)), num_layers3, num_cells64, cell_typelstm, dropout_rate0.1, trainerTrainer(epochs100, learning_rate1e-3) ) predictor estimator.train(ListDataset(train_data, freqD)) results {} for forecast in predictor.predict(ListDataset(train_data, freqD)): sku_id forecast.item_id samples forecast.samples # shape: (num_samples, prediction_length) results[sku_id] pd.DataFrame({ ds: pd.date_range(startforecast.start_date, periodsperiods, freqD), yhat: samples.mean(axis0), yhat_lower: np.percentile(samples, 5, axis0), yhat_upper: np.percentile(samples, 95, axis0), }) return results2.2 ABC分类与安全库存def calculate_safety_stock(sku_id: str, forecast: pd.DataFrame, service_level: float 0.95) - dict: 安全库存 Z_score × σ_demand × √(lead_time) - A类前20% SKU占80%销售额service_level0.99 - B类中30% SKU占15%销售额service_level0.95 - C类后50% SKU占5%销售额service_level0.85 abc_class get_abc_class(sku_id) service_level_map {A: 0.99, B: 0.95, C: 0.85} sl service_level_map.get(abc_class, 0.90) # Z-score from standard normal distribution from scipy.stats import norm z_score norm.ppf(sl) # 需求标准差从90%预测区间反推 sigma_demand (forecast[yhat_upper] - forecast[yhat_lower]).mean() / (2 * 1.645) # 补货提前期(天) lead_time get_lead_time(sku_id) safety_stock z_score * sigma_demand * np.sqrt(lead_time) return { sku_id: sku_id, abc_class: abc_class, service_level: sl, avg_daily_demand: forecast[yhat].mean(), safety_stock: int(np.ceil(safety_stock)), reorder_point: int(np.ceil(forecast[yhat].mean() * lead_time safety_stock)), suggested_order_qty: int(np.ceil(max( forecast[yhat].sum() - get_current_stock(sku_id) safety_stock, 0 ))) }三、拣货路径的TSP优化一张拣货单通常包含15-30个SKU拣货员需要走过所有这些库位。这就是经典的TSP旅行商问题。Service public class PickingPathOptimizer { /** * 使用Lin-Kernighan启发式算法LKH求解TSP * 对于20个拣货点LKH能在100ms内找到最优解 */ public PickingRoute optimize(ListPickLocation locations, Location startPoint) { int n locations.size(); // 构建距离矩阵实际行走距离非欧氏距离 double[][] distanceMatrix buildDistanceMatrix(locations); // LKH求解 LKHSolver solver new LKHSolver(distanceMatrix); int[] tour solver.solve(); // 转换为实际路径 ListPickLocation optimalPath new ArrayList(); optimalPath.add(startPoint); // 起点拣货台 for (int idx : tour) { optimalPath.add(locations.get(idx)); } optimalPath.add(startPoint); // 回到拣货台 double totalDistance calculateTotalDistance(optimalPath, distanceMatrix); return new PickingRoute(optimalPath, totalDistance, estimatePickingTime(totalDistance, locations.size())); } /** * 构建仓库实际行走距离矩阵 * 关键库位之间的实际距离 ≠ 欧氏距离 * 需要考虑通道走向、单向通道、楼梯/货梯 */ private double[][] buildDistanceMatrix(ListPickLocation locations) { int n locations.size(); double[][] matrix new double[n][n]; for (int i 0; i n; i) { for (int j i 1; j n; j) { PickLocation a locations.get(i); PickLocation b locations.get(j); // 同通道内直接距离 if (a.getAisleId().equals(b.getAisleId())) { matrix[i][j] Math.abs(a.getShelfPosition() - b.getShelfPosition()); } else { // 跨通道走到通道口 横向移动 走到目标位置 matrix[i][j] crossAisleDistance(a, b); } matrix[j][i] matrix[i][j]; } } return matrix; } }3.1 优化效果在真实仓库数据上的测试指标按库位顺序贪心最近邻LKH优化单次拣货行走距离850m620m480m拣货时间28min21min16min每人日行走步数320002400018500每人日完成拣货单16张22张29张LKH优化后每人日均拣货效率提升81%人力成本节省约40%。四、AGV调度的多智能体协调50台AGV在仓库中运行核心挑战是死锁避免和路径冲突解决。Service public class AGVScheduler { // 仓库地图将仓库建模为网格图 private final GridMap warehouseMap; // 每台AGV的预留路径时间维度的路径占用 private final MapString, ReservedPath reservedPaths new ConcurrentHashMap(); /** * 基于时空A*的AGV路径规划 * 关键路径不仅包含空间坐标还包含时间维度 * 这样不同AGV可以在不同时间使用同一空间位置 */ public AGVPath planPath(String agvId, Location from, Location to) { // 时空A*状态 (x, y, t) PriorityQueueSTNode openSet new PriorityQueue( Comparator.comparingDouble(n - n.gCost n.hCost) ); MapString, STNode closedSet new HashMap(); STNode start new STNode(from.x, from.y, currentTime(), 0, heuristic(from, to)); openSet.add(start); while (!openSet.isEmpty()) { STNode current openSet.poll(); String key current.key(); if (closedSet.containsKey(key)) continue; closedSet.put(key, current); // 到达目标位置 if (current.x to.x current.y to.y) { return reconstructPath(current); } // 扩展邻居5个动作上下左右 等待 for (Action action : ACTIONS) { int nx current.x action.dx; int ny current.y action.dy; long nt current.time action.duration; // 边界检查 if (!warehouseMap.isValid(nx, ny)) continue; // 冲突检查该位置在该时间是否已被其他AGV预留 if (isReserved(nx, ny, nt, agvId)) continue; double ng current.gCost action.cost; STNode neighbor new STNode(nx, ny, nt, ng, heuristic(nx, ny, to)); openSet.add(neighbor); } } throw new NoPathFoundException(from, to); } /** * 死锁检测与恢复 */ Scheduled(fixedDelay 1000) public void detectDeadlock() { // 构建等待图AGV A等待AGV B释放资源 WaitGraph graph new WaitGraph(); for (AGV agv : agvRegistry.getAllActive()) { if (agv.isWaiting()) { ListString blockingAgvs findBlockingAgvs(agv); for (String blocker : blockingAgvs) { graph.addEdge(agv.getId(), blocker); } } } // 检测环 → 死锁 ListListString cycles graph.findCycles(); for (ListString cycle : cycles) { // 死锁恢复让优先级最低的AGV重新规划路径 String victim selectVictim(cycle); agvRegistry.get(victim).replanPath(); log.warn(死锁检测到牺牲AGV: {}, 死锁环: {}, victim, cycle); } } }五、总结智能仓储的AI落地有三个核心认知预测模型的选择要看SKU规模不是算法前沿程度。TOP 3000的高频SKU用Prophet就够了可解释性强、调参简单业务方看得懂15万SKU的长尾才需要DeepAR联合建模用相似SKU的信息补偿数据稀疏性。拣货路径优化的ROI是所有仓储AI项目中最高的。LKH求解器100ms就能给出近优路径实施成本几乎为零纯软件直接效果是拣货员日行走距离减少40%——人力成本是仓储最大的成本项。AGV调度的复杂度不在单机路径规划而在多机协同。时空A*解决了单AGV的路径规划但50台AGV的全局最优涉及死锁避免、冲突消解、任务分配的多维博弈。我们的经验是宁可牺牲单AGV的路径最优性也要保证全局无死锁。最终效果库存周转天数从45天降到28天拣货效率提升81%AGV利用率从62%提升到88%。仓储AI不是炫技是每平方米、每分钟、每一步的优化累积。