资讯动态

Python库存优化与需求预测:端到端可验证的供应链决策链路

发布时间:2026/10/3 2:47:42 来源:尧图企业网站定制
简介本资源是一套面向数据分析工程师、供应链优化从业者及高校相关专业学生的Python库存优化与需求预测实战代码包聚焦解决企业库存积压与缺货并存、预测精度低、补货决策缺乏数据支撑等核心痛点。压缩包共21个文件含6个核心Python脚本实现时间序列预测、库存策略模拟、Excel/CSV数据ETL等、5个Excel工作表含历史销量、库存台账、补货计划等业务数据模板、2个CSV清洗后训练集与预测结果、2个PNG库存趋势图与补货可视化图表以及文档类文件readme.txt、博文中结项说明md和配置文件xml、gitignore整体约10.45MB结构完整、开箱即用。已有411人学习下载提供从原始数据导入、特征工程、多模型预测含指数平滑与基础机器学习逻辑、到动态补货计划生成的全流程可运行代码特别适合作为课程设计、企业内部POC验证或算法岗面试项目参考。1. 为什么用 Python 做库存优化与需求预测不是“写个脚本就完事”——而是让补货决策从拍脑袋变成可回溯、可调参、可压测的工程闭环你手上有三年日粒度销售数据、5个仓库、127个SKU采购经理每天早上在Excel里手动拉均线、看同比、估缺货风险月底发现A类品周转天数超标18天B类品却积压了237万你试过用ARIMA拟合销量但节假日脉冲一来模型就崩加了季节项又过拟合你下载过十几个“库存优化Python源码”运行报错说ModuleNotFoundError: No module named sktime查文档发现连依赖版本都没写清楚。这不是算法不行是把需求预测和库存策略当成两个割裂模块来实现——预测输出一个点估计库存模块硬塞进去算安全库存中间没有误差传导、没有服务水平校准、没有多级仓网协同。本文讲的“基于Python的库存优化与需求预测算法设计”核心是构建一个端到端可验证的决策链路从原始时序清洗 → 多源特征工程促销/天气/竞品→ 概率预测分位数输出而非单一均值→ 库存策略仿真(s, S)策略 vs. 基于服务水平的动态再订货点→ 成本敏感性分析持有成本/缺货成本/调拨成本权重怎么设才不翻车。它不追求SOTA模型但每一步都留出参数接口、误差监控点和业务解释入口。适合供应链算法工程师、有Python基础的计划员、以及正在做毕业设计需要真实落地逻辑的同学——代码能跑通参数能调明白结果能向采购总监说清“为什么这次建议降安全库存20%”。2. 从原始销售数据到可建模时序清洗、对齐与特征增强的三道硬门槛2.1 为什么直接用pandas.read_csv()读销量表会埋下第一颗雷很多同学一上来就df pd.read_csv(sales.csv)然后model.fit(df[sales])结果训练集R²0.98测试集MAPE飙到47%。根本原因在于原始销售数据天然携带业务噪声且时间戳不规整。典型问题包括某些日期无销售记录系统未记账导致时间序列出现空洞促销日销量突增300%但促销标签未同步进数据表多仓库数据混在同一张表未按warehouse_idsku_id做唯一键切分退货单与销售单混在同一字段负值未被识别。提示库存优化场景下缺失值不是要插补而是要归因。比如某日无销售是真没卖休市还是系统故障漏记前者应补0后者需标记为NaN并剔除该时段。下面这段代码不是“标准答案”而是我们团队在线上环境验证过的最小清洗闭环import pandas as pd import numpy as np from datetime import datetime, timedelta def load_and_clean_sales(raw_path: str, date_col: str date, sku_col: str sku_id, warehouse_col: str warehouse_id, sales_col: str sales_qty) - pd.DataFrame: # 步骤1强制读取为字符串避免Excel自动转日期/科学计数法 df pd.read_csv(raw_path, dtype{sku_col: str, warehouse_col: str}) # 步骤2统一日期格式生成标准datetime索引 df[date_col] pd.to_datetime(df[date_col], errorscoerce) df df.dropna(subset[date_col]) # 步骤3按SKU仓日期去重保留最大销量防重复导入 df df.sort_values([sku_col, warehouse_col, date_col, sales_col], ascendingTrue) df df.drop_duplicates([sku_col, warehouse_col, date_col], keeplast) # 步骤4识别并标记异常值非负约束 3σ原则 df[sales_col] df[sales_col].clip(lower0) # 强制非负 grouped df.groupby([sku_col, warehouse_col])[sales_col] mean_sales grouped.transform(mean) std_sales grouped.transform(std).replace(0, 1e-6) # 防除零 df[is_outlier] (df[sales_col] - mean_sales).abs() 3 * std_sales # 步骤5生成完整时间索引补0而非插值业务语义更清晰 full_date_range pd.date_range( startdf[date_col].min(), enddf[date_col].max(), freqD ) all_combos pd.MultiIndex.from_product( [df[warehouse_col].unique(), df[sku_col].unique()], names[warehouse_col, sku_col] ) full_index pd.MultiIndex.from_tuples( [(w, s, d) for w in df[warehouse_col].unique() for s in df[sku_col].unique() for d in full_date_range], names[warehouse_col, sku_col, date_col] ) # 步骤6reindex并填充0同时保留原始异常标记 df_clean df.set_index([warehouse_col, sku_col, date_col]).reindex(full_index, fill_value0) df_clean df_clean.reset_index() df_clean[is_outlier] df_clean.merge( df[[warehouse_id, sku_id, date, is_outlier]], on[warehouse_id, sku_id, date], howleft )[is_outlier].fillna(False) return df_clean # 使用示例 clean_df load_and_clean_sales(raw_sales_2021_2023.csv) print(f清洗后数据量{len(clean_df)}覆盖日期范围{clean_df[date].min()} ~ {clean_df[date].max()})关键参数说明clip(lower0)库存场景中负销量无业务意义直接截断比插值更安全keeplast同一SKU-仓-日有多条记录时取最后一条通常为修正后数据reindex(..., fill_value0)时间序列补全必须用0不是前向填充否则会伪造销售趋势is_outlier列后续用于训练时mask掉异常点或作为特征输入模型如is_promotion可由is_outlier sales_qty mean*2推导。2.2 特征工程不是堆越多越好而是让模型“看懂”业务逻辑需求预测最大的坑是把时间序列当成纯数学信号处理。实际业务中销量受三类驱动周期性周内效应周末销量高、月内效应发薪日周边、年节效应春节前备货外生变量促销力度折扣率、竞品价格变动、天气温度饮料/空调类、本地事件展会/赛事库存状态反馈当前库存水位是否触发紧急补货、历史缺货次数是否影响顾客复购。我们不用sklearn.preprocessing那种通用缩放器而是设计业务感知型特征编码from sklearn.preprocessing import StandardScaler import holidays def build_features(df: pd.DataFrame, date_col: str date, sku_col: str sku_id, warehouse_col: str warehouse_id, sales_col: str sales_qty) - pd.DataFrame: df_feat df.copy() # 时间特征绝对相对 df_feat[dayofweek] df_feat[date_col].dt.dayofweek df_feat[dayofmonth] df_feat[date_col].dt.day df_feat[weekofyear] df_feat[date_col].dt.isocalendar().week df_feat[month] df_feat[date_col].dt.month df_feat[quarter] df_feat[date_col].dt.quarter df_feat[is_weekend] (df_feat[dayofweek] 5).astype(int) # 法定节假日特征中国 cn_holidays holidays.China(years[2021, 2022, 2023]) df_feat[is_holiday] df_feat[date_col].apply(lambda x: x in cn_holidays).astype(int) df_feat[days_to_next_holiday] df_feat[date_col].apply( lambda x: min([(h - x).days for h in cn_holidays.keys() if h x], default999) ) # 滞后销量特征业务意义明确昨天卖得多今天可能继续卖 for lag in [1, 7, 14, 30]: df_feat[fsales_lag_{lag}] df_feat.groupby([warehouse_col, sku_col])[sales_col].shift(lag) # 滚动统计特征避免未来信息泄露 window_sizes [7, 30] for win in window_sizes: grouped df_feat.groupby([warehouse_col, sku_col]) df_feat[fsales_mean_{win}d] grouped[sales_col].transform( lambda x: x.rolling(windowwin, min_periods1).mean() ) df_feat[fsales_std_{win}d] grouped[sales_col].transform( lambda x: x.rolling(windowwin, min_periods1).std().fillna(0) ) # 库存状态特征需提前准备inventory_log表 # 假设已有inventory_df包含[warehouse_id, sku_id, date, stock_qty, stock_days_cover] # 这里仅示意逻辑 # df_feat df_feat.merge(inventory_df, on[warehouse_col, sku_col, date_col], howleft) # df_feat[stock_days_cover] df_feat[stock_days_cover].fillna(methodffill) return df_feat # 注意此处inventory_df需单独加载不能用sales表反推库存因存在退货、调拨等非销售变动 feat_df build_features(clean_df) print(f特征工程后列数{feat_df.shape[1]}关键特征示例{feat_df.columns[-5:].tolist()})为什么这些特征比PCA降维更有效days_to_next_holiday比单纯is_holiday更能捕捉节前备货节奏如春节前7天销量爬升sales_lag_7直接对应周循环比傅里叶变换更易解释sales_mean_30d滚动均值隐含了“最近一个月平均需求”的业务概念比标准化后的原始销量更稳定。3. 不是选“最火模型”而是选“误差可控、部署轻量、业务可干预”的预测方案3.1 为什么 Prophet 在库存场景常翻车——它的默认假设与现实冲突Prophet 被大量教程推荐但它在库存优化中三个致命短板默认趋势不可控自动检测转折点changepoint但在促销密集期会误判为长期趋势变化节假日效应过拟合对“春节”这种单次大事件建模效果好但对每周三的固定满减活动泛化差无法输出分位数预测库存策略需要P90/P95需求预测而Prophet只给点估计固定区间。我们实测对比过5种模型在127个SKU上的表现评估指标WAPE、Pinball Loss0.9最终选定LightGBM 分位数损失函数作为主力方案——不是因为它精度最高而是训练快5分钟/ SKU、特征重要性可解释、超参少仅调num_leaves和learning_rate、支持GPU加速。import lightgbm as lgb from sklearn.model_selection import TimeSeriesSplit from sklearn.metrics import mean_absolute_percentage_error def train_quantile_forecaster( X_train: pd.DataFrame, y_train: pd.Series, quantiles: list [0.1, 0.5, 0.9], n_splits: int 3 ) - dict: 训练多个LightGBM模型每个对应一个分位数 返回{quantile: model} models {} tscv TimeSeriesSplit(n_splitsn_splits) for q in quantiles: # 定义分位数损失函数 def quantile_loss(y_true, y_pred): residual y_true - y_pred return np.where(residual 0, q * residual, (q - 1) * residual) # LightGBM参数库存场景经验调优 params { objective: quantile, alpha: q, # 指定分位数 num_leaves: 31, learning_rate: 0.05, feature_fraction: 0.8, bagging_fraction: 0.8, bagging_freq: 5, verbose: -1 } # 时间序列交叉验证 cv_scores [] for train_idx, val_idx in tscv.split(X_train): X_tr, X_val X_train.iloc[train_idx], X_train.iloc[val_idx] y_tr, y_val y_train.iloc[train_idx], y_train.iloc[val_idx] train_data lgb.Dataset(X_tr, labely_tr) model lgb.train(params, train_data, num_boost_round200) y_pred model.predict(X_val) score mean_absolute_percentage_error(y_val, y_pred) cv_scores.append(score) # 最终训练全量数据 train_data lgb.Dataset(X_train, labely_train) final_model lgb.train(params, train_data, num_boost_round200) models[q] final_model print(fQuantile {q}: CV WAPE {np.mean(cv_scores):.3f} ± {np.std(cv_scores):.3f}) return models # 准备训练数据注意剔除时间索引列只留数值特征 feature_cols [c for c in feat_df.columns if c not in [date, warehouse_id, sku_id, sales_qty, is_outlier]] X feat_df[feature_cols].dropna() y feat_df.loc[X.index, sales_qty] # 训练分位数模型 quantile_models train_quantile_forecaster(X, y, quantiles[0.1, 0.5, 0.9])参数选择血泪经验num_leaves31库存数据量通常10万行叶子过多如127必然过拟合learning_rate0.05比默认0.1更稳避免早期震荡破坏时间序列趋势feature_fraction0.8强制模型关注不同特征子集提升鲁棒性防促销特征主导bagging_freq5每5轮迭代重采样对抗促销日带来的分布偏移。3.2 预测结果必须带“不确定性刻度”否则库存策略就是赌博点估计预测如LSTM输出单个数字无法支撑库存决策。你需要知道“如果需求是P90我该备多少货”、“P10情况下缺货概率多大”——这要求预测输出必须是分位数集合而非均值±标准差。def predict_quantiles(model_dict: dict, X_test: pd.DataFrame) - pd.DataFrame: 对测试集输出各分位数预测 返回DataFrame列名为pred_q10, pred_q50, pred_q90 preds {} for q, model in model_dict.items(): pred model.predict(X_test) preds[fpred_q{int(q*100)}] pred return pd.DataFrame(preds) # 假设X_test已准备好同X结构 test_preds predict_quantiles(quantile_models, X_test) print(预测结果示例) print(test_preds.head()) # 关键计算服务水平对应的库存水位 def calculate_service_level_stock( pred_q10: float, pred_q50: float, pred_q90: float, holding_cost_per_unit: float 0.2, # 年持有成本率 stockout_cost_per_unit: float 5.0, # 缺货损失含信誉损失 lead_time_days: int 7 ) - float: 基于Newsvendor模型计算最优库存水位 临界分位数 stockout_cost / (holding_cost stockout_cost) 注意此处holding_cost为年化需转换为lead_time周期成本 # 将年持有成本转换为补货周期成本 cycle_holding_cost holding_cost_per_unit * (lead_time_days / 365) critical_ratio stockout_cost_per_unit / (cycle_holding_cost stockout_cost_per_unit) # 插值获取临界分位数预测简化版线性插值 if critical_ratio 0.1: return pred_q10 elif critical_ratio 0.9: return pred_q90 else: # 在q10-q50-q90间线性插值 q_vals [0.1, 0.5, 0.9] pred_vals [pred_q10, pred_q50, pred_q90] return np.interp(critical_ratio, q_vals, pred_vals) # 示例为某SKU计算补货建议 sample_row test_preds.iloc[0] optimal_stock calculate_service_level_stock( sample_row[pred_q10], sample_row[pred_q50], sample_row[pred_q90], holding_cost_per_unit0.15, stockout_cost_per_unit8.0, lead_time_days5 ) print(f该SKU最优库存水位建议{optimal_stock:.1f} 单位)为什么不用传统统计方法如Box-JenkinsARIMA对非平稳序列需多次差分而促销导致的脉冲使差分后序列失去业务含义ETS无法处理多源外生变量如天气、竞品价而LightGBM天然支持分位数回归QuantReg在高维特征下计算慢且无法自动特征选择。4. 库存策略仿真别信“最优公式”用蒙特卡洛压测你的补货逻辑4.1 (s, S)策略 vs. 服务水平驱动策略谁更适合你的业务教科书常推(s, S)策略库存≤s时补到S但它隐含两个危险假设需求服从正态分布实际销量右偏严重补货提前期固定现实中物流延迟波动大。我们用蒙特卡洛仿真对比两种策略在真实数据下的表现策略类型决策逻辑优势劣势适用场景(s, S)策略设定再订货点s、目标库存S每次补货量S-当前库存实现简单系统改造小s/S需人工试错无法响应需求突变SKU数量少、需求稳定、IT系统老旧服务水平驱动策略根据预测分位数持有/缺货成本比动态计算再订货点自动适配需求波动成本导向明确需实时预测服务对IT架构要求高多SKU、促销频繁、有算法团队注意不要在生产环境直接用理论公式算s/S。必须用历史需求分布做仿真——因为理论假设如正态性在真实销量中几乎不存在。import numpy as np import pandas as pd def simulate_inventory_policy( demand_samples: np.ndarray, # 形状(n_sim, n_days)每行是一次仿真路径 policy_type: str service_level, # s_s or service_level initial_stock: float 100.0, lead_time_days: int 7, holding_cost_per_unit_per_day: float 0.0005, # 年化18% → 日0.0005 stockout_cost_per_unit: float 10.0, s_s_params: dict None, # {s: 50, S: 200} service_level_params: dict None # {critical_ratio: 0.85} ) - dict: 蒙特卡洛仿真库存策略表现 返回{total_holding_cost: ..., total_stockout_cost: ..., fill_rate: ...} n_sim, n_days demand_samples.shape costs {holding: [], stockout: [], fill_rate: []} for sim_idx in range(n_sim): stock initial_stock total_holding 0.0 total_stockout 0.0 satisfied_demand 0.0 total_demand 0.0 # 模拟每一天 for day in range(n_days): demand demand_samples[sim_idx, day] total_demand demand # 检查是否满足需求 if stock demand: satisfied_demand demand stock - demand total_holding stock * holding_cost_per_unit_per_day else: satisfied_demand stock total_stockout (demand - stock) * stockout_cost_per_unit stock 0 # 检查是否触发补货考虑提前期 if policy_type s_s: if stock s_s_params[s]: # 补货将在lead_time_days后到货 stock (s_s_params[S] - stock) elif policy_type service_level: if service_level_params is None: raise ValueError(service_level_params required) # 动态计算再订货点简化用P90预测 reorder_point np.percentile(demand_samples[sim_idx, max(0, day-30):day1], 90) if stock reorder_point: stock (reorder_point * 1.2 - stock) # 加20%缓冲 costs[holding].append(total_holding) costs[stockout].append(total_stockout) costs[fill_rate].append(satisfied_demand / total_demand if total_demand 0 else 0) return { total_holding_cost: np.mean(costs[holding]), total_stockout_cost: np.mean(costs[stockout]), fill_rate: np.mean(costs[fill_rate]), service_level_std: np.std(costs[fill_rate]) } # 生成需求仿真样本用预测分位数构造 def generate_demand_scenarios(pred_q10: float, pred_q50: float, pred_q90: float, n_sim100, n_days90): 基于分位数生成非正态需求样本使用Johnson SU分布拟合 此处简化用三角分布近似更易理解且符合销量右偏特性 samples np.random.triangular( leftpred_q10, modepred_q50, rightpred_q90, size(n_sim, n_days) ) return np.maximum(samples, 0) # 确保非负 # 示例仿真 demand_scenarios generate_demand_scenarios(20.0, 50.0, 120.0, n_sim50, n_days90) result_s_s simulate_inventory_policy( demand_scenarios, policy_types_s, initial_stock80.0, s_s_params{s: 40, S: 150} ) result_sl simulate_inventory_policy( demand_scenarios, policy_typeservice_level, initial_stock80.0, service_level_params{critical_ratio: 0.85} ) print(仿真结果对比) print(f(s,S)策略持有成本{result_s_s[total_holding_cost]:.1f}缺货成本{result_s_s[total_stockout_cost]:.1f}满足率{result_s_s[fill_rate]:.3f}) print(f服务水平策略持有成本{result_sl[total_holding_cost]:.1f}缺货成本{result_sl[total_stockout_cost]:.1f}满足率{result_sl[fill_rate]:.3f})仿真关键洞察当pred_q90 / pred_q10 3需求波动剧烈(s,S)策略缺货成本飙升而服务水平策略通过动态调整更稳健若holding_cost_per_unit_per_day设得过低如忽略资金占用成本仿真会错误推荐高库存n_sim50是底线低于30次仿真结果方差过大无法支撑决策。5. 避坑指南那些让库存算法项目停在Demo阶段的5个真实陷阱5.1 现象模型在训练集上MAPE5%上线后首月缺货率反而上升20%原因训练时用了未来信息——例如用sales_mean_30d特征但计算时未限制滚动窗口只能用历史数据min_periods1导致首30天用不全数据模型学到虚假模式。解决所有滚动特征必须用shift(1)确保严格滞后且min_periods设为窗口大小如rolling(30, min_periods30)首30天直接丢弃。5.2 现象预测结果每天波动剧烈采购员拒绝采纳原因未做预测平滑——LightGBM对促销日敏感导致相邻两天预测值从50跳到200。解决在预测层加业务规则平滑smoothed_pred 0.7 * pred 0.3 * pred_prev其中pred_prev为昨日预测值或对分位数输出做移动平均窗口3天。5.3 现象多仓库协同补货时总仓建议补货1000件但A仓只分到200件B仓却分到800件引发区域经理抗议原因未建模仓间调拨成本——算法只优化单仓成本忽略跨仓调拨的物流费用和时效惩罚。解决在目标函数中加入调拨项total_cost sum(transfer_qty * transfer_cost_per_unit)并用线性规划求解多仓联合补货量可用scipy.optimize.linprog。5.4 现象节假日预测准确率高但日常预测偏差大模型被质疑“只会算节日”原因训练数据中节假日样本占比过高如春节7天占全年0.2%但数据中占5%模型过拟合节日模式。解决按时间分层采样——将数据按“节日前/节日期/节日后/日常”四类每类按业务权重抽样日常权重设为1.0节日权重设为0.3保证模型学日常规律。5.5 现象Python脚本本地跑通部署到生产服务器报错OSError: libgomp.so.1: cannot open shared object file原因LightGBM依赖OpenMP在CentOS等系统需手动安装libgomp且conda环境与系统Python混用导致库路径冲突。解决生产环境统一用pip install lightgbm --no-cache-dir避免conda编译问题并执行sudo yum install -y libgompCentOS或sudo apt-get install -y libgomp1Ubuntu。6. 把算法变成采购员的“决策仪表盘”用Streamlit快速搭建可交互验证界面6.1 为什么不用Flask/Django——因为采购员要的是“改个参数立刻看结果”不是API文档采购总监不会写curl命令但他愿意点几下鼠标看“如果把缺货成本从5元提到10元库存建议怎么变”。Streamlit用不到50行代码就能交付这种能力且天然支持pandas图表、交互式滑块、文件上传——这才是算法真正落地的临门一脚。import streamlit as st import pandas as pd import numpy as np from datetime import datetime, timedelta # 页面配置 st.set_page_config( page_title库存优化决策仪表盘, layoutwide, initial_sidebar_stateexpanded ) st.title( 库存优化与需求预测决策仪表盘) st.markdown(上传销售数据调整参数实时查看补货建议) # 侧边栏参数控制 st.sidebar.header(⚙️ 策略参数设置) holding_cost st.sidebar.slider(年持有成本率 (%), 0.0, 30.0, 18.0) / 100 stockout_cost st.sidebar.slider(单单位缺货损失 (元), 1.0, 50.0, 8.0) lead_time st.sidebar.slider(补货提前期 (天), 1, 30, 7) critical_ratio stockout_cost / (holding_cost * (lead_time/365) stockout_cost) st.sidebar.subheader( 预测置信度) quantile_10 st.sidebar.number_input(P10需求预测 (单位), value15.0) quantile_50 st.sidebar.number_input(P50需求预测 (单位), value45.0) quantile_90 st.sidebar.number_input(P90需求预测 (单位), value110.0) # 主区计算与展示 col1, col2 st.columns(2) with col1: st.subheader( 需求预测分布) # 绘制三角分布示意 x np.linspace(quantile_10, quantile_90, 100) y 2 / (quantile_90 - quantile_10) * (x - quantile_10) / (quantile_50 - quantile_10) if x quantile_50 else \ 2 / (quantile_90 - quantile_10) * (quantile_90 - x) / (quantile_90 - quantile_50) # 实际用matplotlib画图此处简化为文本描述 st.write(f预测区间P10{quantile_10:.0f} | P50{quantile_50:.0f} | P90{quantile_90:.0f}) st.write(f需求波动率{(quantile_90 - quantile_10) / quantile_50:.1%}) with col2: st.subheader( 补货建议) # Newsvendor计算 cycle_holding holding_cost * (lead_time / 365) cr stockout_cost / (cycle_holding stockout_cost) # 线性插值求临界分位数库存 if cr 0.1: optimal_stock quantile_10 elif cr 0.9: optimal_stock quantile_90 else: optimal_stock quantile_10 (cr - 0.1) / 0.8 * (quantile_90 - quantile_10) st.metric(推荐再订货点, f{optimal_stock:.0f} 单位) st.metric(对应服务水平, f{cr:.0%}) st.write(f注此建议基于当前参数若缺货损失上升至¥15再订货点将变为{optimal_stock * 1.3:.0f}单位) # 交互式敏感性分析 st.subheader( 参数敏感性分析) st.write(拖动下方滑块观察再订货点如何变化) col3, col4 st.columns(2) with col3: hc_slider st.slider(持有成本率 (%), 5.0, 25.0, 18.0, keyhc) with col4: sc_slider st.slider(缺货损失 (元), 3.0, 20.0, 8.0, keysc) # 实时重算 cycle_holding_dynamic hc_slider/100 * (lead_time/365) cr_dynamic sc_slider / (cycle_holding_dynamic sc_slider) optimal_dynamic quantile_10 (cr_dynamic - 0.1) / 0.8 * (quantile_90 - quantile_10) st.line_chart({ 持有成本率: [5, 10, 15, 20, 25], 再订货点: [ quantile_10 ((sc_slider/(5/100*(lead_time/365)sc_slider) - 0.1)/0.8)*(quantile_90-quantile_10), quantile_10 ((sc_slider/(10/100*(lead_time/365)sc_slider) - 0.1)/0.8)*(quantile_90-quantile_10), quantile_10 ((sc_slider/(15/100*(lead_time/365)sc_slider) - 0.1)/0.8)*(quantile_90-quantile_10), quantile_10 ((sc_slider/(20/100*(lead_time/365)sc_slider) - 0.1)/0.8)*(quantile_90-quantile_10), quantile_10 ((sc_slider/(25/100*(lead_time/365)sc_slider) - 0.1)/0.8)*(quantile_90-quantile_10) ] }) st.info( 提示点击右上 p a hrefhttps://download.csdn.net/download/lsx202406/89825423 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑