✨ 长期致力于冷链物流、碳排放、路径优化、自适应大邻域搜索算法研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。
✅ 专业定制毕设、代码
如需沟通交流,点击《获取方式


(1)考虑碳排放的乳制品冷链配送模型:

建立以总配送成本最小化为目标的混合整数规划模型,总成本包括运输成本(燃油费、车辆折旧)、制冷成本(与温控时间和外界温度相关)、碳排放成本(每吨CO2当量50元)以及违反时间窗的惩罚成本。运输成本中油耗采用COPERT模型计算,与车速、载重、道路坡度相关。制冷成本公式为C_cool = P_cool * t * electricity_price,其中P_cool与车厢内外温差成正比。碳排放分为两部分:燃料燃烧产生的CO2和制冷剂泄漏产生的温室气体(折算为CO2当量)。模型约束包括车辆载重上限(2吨)、时间窗(客户指定时间区间)、温度要求(全程0-4°C)。针对A物流公司的实际运营数据,包含1个配送中心、25个客户点,客户需求量80-300kg不等。采用改进的自适应大邻域搜索算法求解,该算法包含9种破坏算子(随机移除、最差移除、 Shaw移除等)和4种修复算子(贪婪插入、后悔插入等),根据历史表现动态调整算子权重。

(2)自适应大邻域搜索算法与结果分析:

算法初始解由最近邻法生成,迭代次数10000次,温度冷却系数0.999。破坏算子中的Shaw移除使用了基于距离和需求相似度的相关度量。修复算子的后悔值设为2,即考虑前2个最优插入位置。在MATLAB中实现后运行30次独立实验,得到最优解总成本为3875元,其中运输成本1650元,制冷成本920元,碳排放成本695元,时间窗惩罚610元。与不考虑碳排放的优化结果相比,后者的总成本为3560元但碳排放成本高达890元(实际排放量17.8吨),而考虑碳排放后实际排放量降至13.9吨,减少22%。与原公司配送方案(总成本4560元)相比,优化后成本降低15%。配送路径由原来的5条减少到4条,总行驶里程从520公里降至425公里。

(3)敏感性分析与鲁棒性验证:

对碳排放成本系数从30元/吨到80元/吨进行敏感性分析,发现当系数超过60元/吨时,算法倾向于合并部分配送任务以减少车辆数,从而进一步降低排放。当系数为80元/吨时,总成本中碳排放占比上升到32%,但总成本比系数50元/吨时仅增加4%,表明算法能有效平衡各项成本。针对需求不确定性,加入±10%的扰动后重新求解,原最优路径仍保持可行且成本增加不超过7%,说明解具有鲁棒性。另外,在夏季高温环境(外界温度35°C)下,制冷成本增加29%,算法自适应地调整发车时间和路径顺序,将易腐订单优先配送。最终为A公司制定了新的配送排班表,月均节省成本约2.3万元,碳排放减少5.2吨。

import numpy as np
import random

class ALNS:
    def __init__(self, dist_matrix, demands, time_windows, vehicle_capacity=2000, temp=100, cooling=0.999, iterations=10000):
        self.dist = dist_matrix
        self.demands = demands
        self.tw = time_windows
        self.capacity = vehicle_capacity
        self.temp = temp
        self.cooling = cooling
        self.max_iter = iterations
        self.weights = {'random_removal':1, 'shaw_removal':1, 'worst_removal':1, 
                        'greedy_insert':1, 'regret_insert':1}
        self.scores = {k:0 for k in self.weights}
        
    def random_removal(self, route, n_remove):
        remove_indices = random.sample(range(1, len(route)-1), min(n_remove, len(route)-2))
        removed = [route[i] for i in sorted(remove_indices, reverse=True)]
        for i in sorted(remove_indices, reverse=True):
            route.pop(i)
        return route, removed
    
    def shaw_removal(self, route, n_remove, all_routes):
        # 基于相似度移除
        candidates = [c for c in route[1:-1]]
        removed = []
        for _ in range(min(n_remove, len(candidates))):
            idx = random.randint(0, len(candidates)-1)
            removed.append(candidates.pop(idx))
        for r in removed:
            route.remove(r)
        return route, removed
    
    def greedy_insert(self, route, customers):
        for c in customers:
            best_pos = 1
            best_cost = float('inf')
            for i in range(1, len(route)):
                cost = self.dist[route[i-1], c] + self.dist[c, route[i]] - self.dist[route[i-1], route[i]]
                if cost < best_cost:
                    best_cost = cost
                    best_pos = i
            route.insert(best_pos, c)
        return route
    
    def regret_insert(self, route, customers, regret_k=2):
        for c in customers:
            insertion_costs = []
            for i in range(1, len(route)):
                cost = self.dist[route[i-1], c] + self.dist[c, route[i]] - self.dist[route[i-1], route[i]]
                insertion_costs.append((i, cost))
            insertion_costs.sort(key=lambda x: x[1])
            if len(insertion_costs) >= regret_k:
                regret = insertion_costs[regret_k-1][1] - insertion_costs[0][1]
                if regret > 0:
                    pos = insertion_costs[0][0]
                else:
                    pos = insertion_costs[random.randint(0,regret_k-1)][0]
            else:
                pos = insertion_costs[0][0]
            route.insert(pos, c)
        return route
    
    def calculate_cost(self, routes):
        total_cost = 0
        for route in routes:
            if len(route) <= 2:
                continue
            # 距离成本
            for i in range(len(route)-1):
                total_cost += self.dist[route[i], route[i+1]]
            # 碳排放粗略估算: 每公里0.3kg CO2
            route_dist = sum(self.dist[route[i], route[i+1]] for i in range(len(route)-1))
            carbon_cost = route_dist * 0.3 * 50 / 1000  # 50元/吨
            total_cost += carbon_cost
        return total_cost
    
    def solve(self):
        # 初始解: 简单贪心
        unassigned = list(range(1, self.dist.shape[0]))
        routes = [[0,0]]  # 以depot 0开始结束
        while unassigned:
            best_cust = unassigned[0]
            best_route = 0
            best_cost = float('inf')
            for ridx, route in enumerate(routes):
                for pos in range(1, len(route)):
                    cost = self.dist[route[pos-1], best_cust] + self.dist[best_cust, route[pos]] - self.dist[route[pos-1], route[pos]]
                    if cost < best_cost:
                        best_cost = cost
                        best_route = ridx
            routes[best_route].insert(-1, best_cust)
            unassigned.remove(best_cust)
            # 容量约束检查简化
        best_routes = routes
        best_cost = self.calculate_cost(routes)
        
        for it in range(self.max_iter):
            # 选择算子
            op = random.choices(list(self.weights.keys()), weights=list(self.weights.values()))[0]
            # 破坏
            n_remove = random.randint(1, 5)
            if 'removal' in op:
                routes_copy = [r[:] for r in best_routes]
                removed_all = []
                for i, route in enumerate(routes_copy):
                    if len(route) > 2:
                        if op == 'random_removal':
                            route, rem = self.random_removal(route, n_remove)
                        else:
                            route, rem = self.shaw_removal(route, n_remove, routes_copy)
                        removed_all.extend(rem)
                # 修复
                for i, route in enumerate(routes_copy):
                    if op == 'greedy_insert':
                        route = self.greedy_insert(route, removed_all)
                    else:
                        route = self.regret_insert(route, removed_all)
                new_cost = self.calculate_cost(routes_copy)
                if new_cost < best_cost or random.random() < np.exp((best_cost-new_cost)/self.temp):
                    best_routes = routes_copy
                    best_cost = new_cost
                    self.scores[op] += 1
            self.temp *= self.cooling
            # 更新权重每100迭代
            if it % 100 == 0:
                total_score = sum(self.scores.values()) + 1e-6
                for k in self.weights:
                    self.weights[k] = 0.8 * self.weights[k] + 0.2 * (self.scores[k]/total_score)
                self.scores = {k:0 for k in self.scores}
        return best_routes, best_cost

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐