优化算法|蚁群算法求解电动车辆路径规划问题

问题描述

电动车辆路径规划问题(Electric Vehicle-Routing Problem, EVRP),相较于传统的VRP需要考虑车辆的电量、里程焦虑。因此,电动车辆路径规划问题需要决策车辆是否需要去充电、决策选择哪个充电站。

本篇推文求解的问题,做出如下合理假设:

  1. 充电量与充电时长为线性函数关系;
  2. 所有车辆的最大载重、最大电量相同,且车辆单位距离的电量消耗相同
  3. 存在多个车场以及若干充电站;
  4. 客户点分为两类:取货点以及送货点;
  5. 车辆完成服务之后,无需返回指定车场;

蚁群算法原理

(1)状态转移函数

初始状态下,每条路径上的信息素数量是相同的。同时,初始状态下,每只蚂蚁会通过随机寻找路径的方式前行,信息素释放的数量与搜索路径的目标函数值成反比。随后,搜索过程中,每只蚂蚁根据路径上残留的信息素,计算蚂蚁前往每一个节点的概率,并基于概率选择下一个访问的节点。其中,第 t t t次迭代蚂蚁 k k k从节点 i i i前往节点 j j j的概率 P i j k ( t ) P_{ij}^k(t) Pijk(t)的计算表达式如下:

表达式中, τ i j ( t ) \tau_{ij}(t) τij(t)表示第 t t t次迭代从节点 i i i前往节点 j j j残留的信息素数量, η i j ( t ) \eta_{ij}(t) ηij(t)表示节点 i i i前往节点 j j j的距离长度的倒数, J k J_k Jk表示蚂蚁 k k k还没有访问过的节点的集合。同时, a a a表示信息素因子, b b b表示启发函数因子,这两个参数为蚁群优化算法的关键参数。

(2)更新信息素

在初始状态下,每条路径的信息素数量均设置为0。在搜索过程中,部分信息素会随着时间流逝而挥发,信息素挥发快慢通过参数信息素挥发因子 c c c进行控制。信息素的更新计算表达式如下:

表达式中, Δ τ i j k \Delta \tau_{ij}^k Δτijk蚂蚁 k k k遍历过的路径总长度的倒数, τ i j ( t ) \tau_{ij}(t) τij(t)表示第 t t t次迭代从节点 i i i前往节点 j j j残留的信息素数量。

算法结果

测试数据

    1      55.00      50.00      0.00      0.00 
    2      45.00      68.00      0.00      0.00 
    3      35.00      70.00      0.00      0.00 
    4      72.00      66.00      0.00      0.00
    5      12.00      68.00      0.00      0.00 
    6      82.00      65.00      -15.00    90.00 
    7      40.00      69.00      20.00     90.00 
    8      80.00      96.00      -20.00    90.00 
    9      55.00      88.00      20.00     90.00 
   10      38.00      70.00      -15.00    90.00 
   11      85.00      66.00      10.00     90.00 
   12      58.00      69.00      -10.00    90.00 
   13      85.00      55.00      -20.00    90.00
   14      52.00      64.00      16.00     90.00
   15      90.00      26.00      -9.00     90.00
   16      60.00      30.00      21.00     90.00
   17      61.00      47.00      15.00     90.00
   18      17.00      63.00     -19.00     90.00
   19      31.00      62.00      23.00     90.00
   20      52.00      33.00     -11.00     90.00
   21      51.00      21.00     -5.00      90.00
   22      42.00      41.00     -10.00     90.00
   23      36.00      16.00      10.0      90.00
   24      28.00      55.00      -10.00    90.00 
   25      25.00      50.00      -10.00    90.00 
   26      25.00      52.00      40.00     90.00 
   27      25.00      55.00      10.00     90.00 
   28      23.00      52.00      -10.00    90.00 
   29      23.00      55.00      20.00     90.00 
   30      20.00      50.00      -10.00    90.00 
   31      20.00      55.00      10.00     90.00 
   32      10.00      35.00      -20.00    90.00 
   33      80.00      40.00      30.00     90.00 
   34       8.00      40.00      40.00     90.00 
   35       68.00     45.00       0.00     0.00 
   36       5.00      35.00       0.00     0.00 
   37       45.00     45.00       0.00     0.00
   38       22.00     40.00       0.00     0.00 
   39       10.00     10.00       0.00     0.00

节点编号 X坐标 Y坐标 需求(需求为正表示取货、需求为负表示送货) 服务时间
编号前几个 需求和服务时间为0 表示车场(车辆出发地点)
编号后几个 需求和服务时间为0 表示充电场站

代码展示

while iter <= iter_max
    % construct ant solution
    Population = cell(ant_number, 1);
    for m = 1: ant_number
        copy_customer_list = List.customer_list;
        load = 0;
        battery = vehicle.battery;
        route_list = cell(data.customer_number,1);
        route_count = 1;
        flag = 1;  % 判断是否需要重新随机选择节点 1表示需要随机选择  0表示不需要
        while ~isempty(copy_customer_list)
            if flag == 1
                depot_id = randi([1, data.depot_number]);  % 随机选择出发车场
                msize = numel(copy_customer_list);
                idx = randperm(msize);
                preNode = copy_customer_list(idx(1));      % 随机选择起始节点
                route_list{route_count} = [route_list{route_count} depot_id preNode];
                load = load + Demand(preNode);
                battery = battery - dist(depot_id, preNode);
            end
            if sum(preNode == List.station_list) == 0
                copy_customer_list(copy_customer_list == preNode) = [];
            end
            r = rand;
            nextNode = NextPoint(preNode,Tau,Eta,alpha,beta,Demand,vehicle,load,dist,battery,copy_customer_list,List,data,r,r0);
            if isempty(nextNode)  % 无后续节点,创建新路径
                route_count = route_count + 1;
                load = 0;   % 重置车辆载重和电量
                battery = vehicle.battery;
                flag = 1;
            elseif sum(nextNode == List.station_list) ~= 0  % 后续节点为充电站
                flag = 0;
                route_list{route_count} = [route_list{route_count} nextNode];
                load = load + Demand(nextNode);  % 更新车辆载重与电量
                battery = vehicle.battery;
                preNode = nextNode;
            else
                flag = 0;
                route_list{route_count} = [route_list{route_count} nextNode];
                load = load + Demand(nextNode);  % 更新车辆载重与电量
                battery = vehicle.battery - dist(preNode, nextNode);
                preNode = nextNode;
            end
        end
        Population{m} = CleanVehiclesCustomer(route_list);
    end
    
    NV = zeros(ant_number,1);   % number of vehicle
    Obj = zeros(ant_number,1);  % objective value
    for i = 1:ant_number
        [NV(i), Obj(i)] = CostFun(Population{i}, dist, service_time, vehicle, List, a, b);
    end
    
    if iter == 1
        [min_Cost,min_index] = min(Obj);
        Solution_best = Population{min_index};
        Cost_best(iter) = min_Cost;
    else
        [min_Cost,min_index] = min(Obj);
        if min_Cost < Cost_best(iter - 1)
            Cost_best(iter) = min_Cost;
            Solution_best = Population{min_index};
        else
            Cost_best(iter) = Cost_best(iter - 1);
        end
    end
    
    %% print
    disp(['Iteration: ',num2str(iter), ' Total Objective Value: ',num2str(Cost_best(iter))]);
    fprintf('\n')
    
    %% update the pheromene
    Tau = UpdateTau(Tau, Solution_best, rho, Q, a, b, data, service_time, dist, vehicle, List);
    iter = iter + 1;
    
end

若有运筹优化建模及算法定制需求,欢迎联系我们私聊沟通

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eternal1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值