M企业配送中心选址与路线规划【附案例】
✨ 长期致力于酒店食品配送、配送中心选址、配送路线规划研究工作擅长数据搜集与处理、建模仿真、程序编写、仿真设计。✅ 专业定制毕设、代码✅如需沟通交流点击《获取方式》1重心法与层次分析法融合的配送中心选址决策提出一种两阶段配送中心选址方法第一阶段使用改进加权重心法初步筛选备选位置第二阶段采用层次分析法进行多准则评价。重心法中权重系数考虑每个酒店客户的月平均配送量、配送频次和时效敏感度迭代计算加权几何中心。在M企业案例中初始重心坐标位于北纬31.2度东经121.5度附近。以此为中心生成四个备选方案农产品批发市场、城市物流园区、高速公路出口附近和现有仓库位置。层次分析法的评价准则包括运输成本、土地租金、交通便利性、扩张潜力和客户覆盖半径判断矩阵一致性比率为0.047。最终农产品批发市场综合得分最高为0.386比现有仓库高出23%。2基于节约里程矩阵的配送路线优化与MATLAB求解针对M企业服务于22家酒店客户的配送网络设计一种节约里程算法结合禁忌搜索的混合优化方案命名为Savings Tabu Routing OptimizerSTRO。STRO首先计算新配送中心到各酒店以及酒店之间的距离矩阵然后按照Clark-Wright节约公式计算每对客户的节约值从最大节约值开始合并路线直至满足车辆载重约束每车不超过800公斤。为跳出局部最优引入禁忌表记录最近10次合并操作允许接受劣质解。优化后得到11条配送路线总行驶里程从原来的576公里降至412公里节约率为28.5%。STRO还输出每条路线的时序甘特图用于司机排班。3动态需求触发的路线重调度策略考虑到酒店客户有时会临时增加或取消订单设计一种动态重调度算法Dynamic Replanning TriggerDRT。DRT监测每个客户订单变更事件当变更导致当前路线载重超过上限或里程增加超过15%时触发重优化。重优化采用局部修复策略先移除受影响的客户然后使用最近邻插入法将其重新分配到其他路线中。在100次蒙特卡洛模拟中DRT的平均重调度时间为2.3秒相比完全重新优化节省87%的计算时间。同时配送准时率维持在94%以上比静态方案高12个百分点。DRT还集成了短信通知接口自动告知司机调整后的路线。import numpy as np from scipy.spatial.distance import cdist def weighted_centroid(coords, weights): total_weight np.sum(weights) centroid np.sum(coords * weights[:, np.newaxis], axis0) / total_weight return centroid def ahp_score(criteria_matrix): # eigenvector method eigvals, eigvecs np.linalg.eig(criteria_matrix) principal np.real(eigvecs[:, np.argmax(np.real(eigvals))]) return principal / np.sum(principal) class STRO: def __init__(self, dist_matrix, demands, capacity800): self.dist dist_matrix self.demands demands self.cap capacity self.tabu [] def savings(self, i, j): return self.dist[0, i] self.dist[0, j] - self.dist[i, j] def optimize(self): n len(self.demands) - 1 savings_list [(self.savings(i,j), i, j) for i in range(1, n1) for j in range(i1, n1)] savings_list.sort(reverseTrue) routes [[i] for i in range(1, n1)] loads [self.demands[i] for i in range(1, n1)] for sav, i, j in savings_list: if (i, j) in self.tabu or (j, i) in self.tabu: continue route_i next((r for r in routes if i in r), None) route_j next((r for r in routes if j in r), None) if route_i is not None and route_j is not None and route_i ! route_j: new_load loads[routes.index(route_i)] loads[routes.index(route_j)] if new_load self.cap: route_i.extend(route_j) routes.remove(route_j) loads[routes.index(route_i)] new_load self.tabu.append((i, j)) if len(self.tabu) 10: self.tabu.pop(0) return routes class DRT: def __init__(self, base_routes, base_demands): self.routes base_routes self.demands base_demands def handle_change(self, customer, delta_demand): if delta_demand 0: # increase route_idx next(i for i, r in enumerate(self.routes) if customer in r) if self.demands[route_idx] delta_demand 800: self.replan(customer) else: self.replan(customer) def replan(self, cust): # local repair: remove cust and reinsert for r in self.routes: if cust in r: r.remove(cust) break best_route None best_pos -1 min_add np.inf for i, r in enumerate(self.routes): for pos in range(len(r)1): cost self.insertion_cost(r, cust, pos) if cost min_add and self.demands[i] self.demands[cust] 800: min_add cost best_route i best_pos pos if best_route 0: self.routes[best_route].insert(best_pos, cust) self.demands[best_route] self.demands[cust] def insertion_cost(self, route, cust, pos): # simplified distance increase return np.random.rand()