matlab遗传算法求解车辆路径问题(一)续

本文介绍了使用matlab实现的遗传算法解决车辆路径问题,结合爬山算法进行改进。通过对个体车辆分配、选择、交叉、变异和爬山操作,找到优化的配送路径。算例展示了算法效果,平均最短路径优于原文结果。
摘要由CSDN通过智能技术生成

一、引言

上篇关于使用matlab编写遗传算法求解车辆路径问题写完后,我发现南柯一梦那篇文章的参考文献应该是一篇《中国管理科学》的文章《用混合遗传算法求解物流配送路径优化问题的研究》,果然期刊水平高,文章的质量还是更有保障。这篇文章提出用爬山算法对遗传算法进行改进,本文将对基于爬山算法的遗传算法进行复现,并用于求解原文中的车辆路径优化问题。问题描述在上一篇文章中,这里不再赘述。

二、算法思路及GA代码

2.0算法思路

本文针对VRP问题所编写代码的核心过程为车辆路径的分配过程,即把哪些顾客安排给第几辆车。不同于上一篇文章,本文代码中的种群个体没有包含虚拟配送中心,只包含了需要配送的需求点。所以首先要做的就是为顾客安排车辆,具体的思路如下。以6-9-4-2-1-3-8-7-5为例,首先将第一个顾客6安排给第一辆车(这里的隐含假设是,不存在需求量或配送距离大于单个车辆限额的顾客),接着计算将第二个顾客9加入第一个路径后的配送距离及载重量,如果都没超过,则将9安排给第一辆车,否则将9安排给下一个车辆,以此类推。

对于一个安排好车辆的个体,如果安排的车辆总数小于等于配送中心的车辆限额,则为可行解。如果安排的车辆总数大于配送中心得车辆限额,则对该个体进行惩罚。具体操作就是给该个体的总路径增加一个较大的惩罚值。接着进行的算法步骤为:选择-交叉-变异-爬山-重插入。爬山操作的思想是,对于通过遗传操作形成的每代群体中的最优个体,通过领域搜索实施爬山操作。具体做法是:(1)在个体中随机选择两个基因,交换其位置;(2)判断基因换位后适应值是否增加,若增加,则以换位后的个体取代原个体;(3)重复操作(1)(2)直到达到指定次数为止。

2.1车辆路径分配及个体总路径距离计算

%% LengthInd函数用于计算个体的总路径长度
%  输入:个体a,车辆数carNum,客户之间的距离里矩阵DL,
%        距离限制disMax,客户重量需求DW,车辆重量限制capMax,客户到需求点距离X
%  输出:个体的总路径长度
%%
% 整体思路是给个体中每个客户赋予对应的车辆编号,从小到大,
% 如果新增加的个体超过当前车辆的距离或重量限制,则分配给下一个车辆,
% 如果被分配的车辆总数超过了给定车辆数,对个体进行惩罚
function lengthInd = LengthInd(a,carNum,DL,disMax,DW,capMax,X)
custNum = length(a);         % 记录顾客的数量
matchA = zeros(custNum,4);   % 记录顾客和车辆的匹配情况,第一列为顾客的编号,第二列为匹配的车辆编号
                             % 第三列为子路径总距离只记录在一个路径最后一个顾客对应的位置,第四列为需求重量
matchA(:,1) = a';
matchA(:,4) = DW(a)';
matchA(1,2) = 1;             % 第一个顾客一定在第一个路径中
k = 1;                       % 车辆的编号

for i = 2:custNum
    % 对于第i个顾客,首先要计算的是在当前路径加入该顾客后的路径总距离以及总重量
    custTemp = find(matchA(:,2)==k); % 先找到第k个路径中包含的顾客
    custK = [matchA(custTemp,1)' matchA(i,1)]; % 在第k个路径中加入第i个顾客后的总顾客情况
    i1 = custK(1:end-1);
    i2 = custK(2:end);
    custKL = sum(DL((i1-1)*custNum+i2));
    custKL = custKL + X(custK(1)) + X(custK(end)); % 计算第k辆车的总路径
    custKW = sum(DW(custK));                       % 计算第k辆车的总载重
    if (custKL > disMax || custKW > capMax)
        k = k + 1;
        matchA(i,2) = k;
        % 此时判断出了上一辆车的最后一个需求点,因此需要记录上一个路径的距离
        custK(end) = [];
        i1 = custK(1:end-1);
        i2 = custK(2:end);
        custKL = sum(DL((i1-1)*custNum+i2));
        custKL &
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值