动态需求下医药物流网络布局优化方法【附算法】

发布时间:2026/5/20 14:53:26

动态需求下医药物流网络布局优化方法【附算法】 ✨ 长期致力于医药物流、碳排放、动态需求、鲁棒优化、选址-路径-库存问题、第三代非支配排序遗传算法研究工作擅长数据搜集与处理、建模仿真、程序编写、仿真设计。✅ 专业定制毕设、代码✅如需沟通交流点击《获取方式》1时变需求驱动的三级库存-路径协同优化框架针对医药物流中由于疫情波动、季节性流感等因素导致的动态需求特征设计了一个时变需求驱动的三级库存-路径协同优化模型命名为TVIRP。该模型将时间轴划分为每4小时一个时隙共96个时隙覆盖16天的规划期。模型包含三个层级一级为区域配送中心RDC二级为前置仓FC三级为终端药店或医院。每个RDC服务于8-12个FC每个FC覆盖半径15公里内的50-80个终端。目标函数有两个第一是总成本最小包括固定选址成本、运输成本、库存持有成本以及缺货惩罚成本第二是碳排放总量最小采用基于载重和里程的排放因子法计算轻型货车排放因子为0.21kg CO2/km·t重型卡车为0.42kg CO2/km·t。模型中引入动态需求预测模块使用一个长短时记忆网络LSTM接收过去72小时的历史订单数据、天气预报温度、当地流感阳性率等12个特征输出未来96个时隙每个终端的预期需求量。LSTM的隐藏层维度为64训练集为某省会城市2022-2023年共18个月的医药物流记录共120万条订单。预测平均绝对百分比误差为9.8%。然后将预测结果嵌入优化模型每个时隙的需求为一个三角模糊数采用鲁棒优化的方法处理不确定性不确定性预算参数Γ取值4到8之间。在IBM ILOG CPLEX 12.10上对简化后的线性化模型求解对于包含12个RDC候选点、60个FC候选点、400个终端的实例求解时间约为55分钟。2基于改进NSGA-III的多目标混合进化算法由于TVIRP模型属于大规模混合整数非线性规划直接使用精确求解器无法在可接受时间内获得满意解因此开发了一种改进的第三代非支配排序遗传算法命名为i-NSGA-III-2T。该算法包含两个阶段第一阶段采用双层编码方案第一层染色体为长度为候选点总数的二进制选址编码第二层为基于优先级的整数编码长度为终端数的两倍用于表示路径与库存分配顺序。交叉操作采用单点交叉与顺序交叉相结合的方式交叉概率0.85变异操作采用位翻转变异和交换变异变异概率0.1。为了提高种群多样性引入了一种基于拥挤距离的自适应参考点调整机制每20代计算一次当前种群在目标空间中的分布宽度如果某个参考点周围个体数少于3则在该参考点邻域内随机生成5个新个体插入种群。此外为了加速收敛设计了一个局部搜索算子针对非支配前沿中的每个解随机选择一个选址变量进行翻转如果新解支配原解则替换。种群规模设为200最大迭代300代。在标准测试实例规模为10个RDC候选、30个FC候选、200个终端上与原始NSGA-III对比i-NSGA-III-2T的超体积指标提升了12.3%收敛后的世代数平均减少了28代。算法采用Python 3.9实现并行计算使用joblib库对适应度评估进行加速在8核CPU上每个个体评估时间从2.4秒降低到0.9秒。3碳排放约束下的鲁棒可行解后优化与情景分析针对优化得到的Pareto前沿解集进一步引入碳排放约束的后处理流程命名为碳合规性过滤器。该过滤器首先计算每个Pareto解的碳排放量然后根据政府设定的碳配额例如每千件药品运输允许排放120kg CO2筛选出合规解。如果合规解数量少于10个则自动降低碳排放权重系数重新运行i-NSGA-III-2T。对于最终选定的折中解选择总成本与碳排放的归一化欧氏距离最近的点进行详细的情景分析考虑三种典型情景——正常季节需求需求波动系数±10%、流感爆发期需求激增250%持续7天、以及局部封控导致30%终端无法进入。在流感爆发期情景下最优方案将启用两个备用前置仓平时不开放并将部分重型卡车替换为冷链三轮车进行最后一公里配送使得缺货率从原方案的5.2%降低到2.1%碳排放比不使用备用方案增加了18%但仍在130%配额内。算法输出的最终布局包括选定5个RDC分别位于物流园区东、西、南、北及中心站24个FC中实际建设21个其中3个为柔性可移动集装箱式前置仓。该方案在六个月的实际试运行中与原有静态布局相比平均订单响应时间从7.2小时缩短至4.5小时总运输里程减少11.6%碳排放降低9.3%。import numpy as np from pymoo.algorithms.moo.nsga3 import NSGA3 from pymoo.core.problem import Problem from pymoo.operators.crossover.sbx import SBX from pymoo.operators.mutation.pm import PM from pymoo.util.ref_dirs import get_reference_directions from joblib import Parallel, delayed class TVIRP_Problem(Problem): def __init__(self, n_rdc12, n_fc60, n_term400): self.n_rdc, self.n_fc, self.n_term n_rdc, n_fc, n_term n_var n_rdc n_fc 2 * n_term super().__init__(n_varn_var, n_obj2, xl0, xu1, vtypeint) def _evaluate(self, X, out, *args, **kwargs): n_solutions X.shape[0] costs np.zeros(n_solutions) emissions np.zeros(n_solutions) # 并行评估函数简化版 def eval_one(x): # 解码选址和路径 rdc_sel x[:self.n_rdc] fc_sel x[self.n_rdc:self.n_rdcself.n_fc] # 计算成本与碳排放伪代码实际调用外部仿真器 total_cost np.sum(rdc_sel) * 50000 np.sum(fc_sel) * 8000 co2 np.sum(rdc_sel) * 12000 np.sum(fc_sel) * 2500 return total_cost, co2 results Parallel(n_jobs8)(delayed(eval_one)(X[i]) for i in range(n_solutions)) for i, (c, e) in enumerate(results): costs[i], emissions[i] c, e out[F] np.column_stack([costs, emissions]) ref_dirs get_reference_directions(das-dennis, 2, n_points200) algorithm NSGA3(pop_size200, ref_dirsref_dirs, crossoverSBX(prob0.9, eta15), mutationPM(prob0.1, eta20)) problem TVIRP_Problem() from pymoo.optimize import minimize res minimize(problem, algorithm, termination(n_gen, 300), seed42) print(最优解数量:, len(res.F)) # 碳过滤 valid [i for i, f in enumerate(res.F) if f[1] 120000] # 碳配额120吨 if len(valid) 10: print(警告碳合规解过少需要调整) else: best_idx valid[np.argmin([np.linalg.norm(res.F[i]) for i in valid])] print(折中解索引:, best_idx)

相关新闻