粒子群算法(PSO)求解无时间窗的车辆路径规划问题(VRP)

这个VRP问题可以描述为:

在这里插入图片描述

代码通俗易懂,可以结合这篇粒子群算法的基本思想
源代码:

主程序:

%Author: Chauncy
%Date: 2020年4月23日
clear;
close all;
clc;
%% 参数设置
city=[22,60;58,69;71,71;83,46;91,38;24,42;18,40];%城市坐标
num_city=size(city,1);
need=[0.89;0.14;0.28;0.33;0.21;0.41;0.57];%城市的需求量
num_che=3;  %车辆个数
num_gen=50;
num_pop=80;
c1=1.49445;
c2=1.49445;
w=0.729;    %惯性权重
%% 初始化
Xv=zeros(num_pop,num_city);
Xr=zeros(num_pop,num_city);
Vv=zeros(num_pop,num_city); 
Vr=zeros(num_pop,num_city);
fit=zeros(num_pop,1);       %存放种群的适应度值
for i=1:num_pop
    for j=1:num_city %生成初始解
        Xv(i,j)=randperm(num_che,1);
        Xr(i,j)=randperm(num_city,1);
        Vv(i,j)=randperm(2,1)-2;
        Vr(i,j)=randperm(12,1)-6;
    end
    %对Xr按行进行合法化
    Xr(i,:)=Valid_Xr(Xv(i,:),Xr(i,:),num_che);
    Capacity=zeros(1,num_che);
    for j=1:num_che 
        Capacity(j)=sum(need(find(Xv(i,:)==j)));
    end
    if ~isempty(find(Capacity>1,1))
        fit(i)=inf; %不满足汽车容量限制的粒子的适应值取无穷大
    else            %满足汽车容量限制,就取欧式距离
        fit(i)=Fit(Xv(i,:),Xr(i,:),city,num_che);%计算满足条件的解的适应值
    end
end
%% 迭代准备
%对初始化情况进行记录
person_best_fit=fit;%个体最优值
person_best_Xv=Xv;  %个体最优路径
person_best_Xr=Xr;
[globalbest_fit,globalbest_fit_index]=min(person_best_fit);%全局最优值
globalbest_route=[person_best_Xv(globalbest_fit_index,:);person_best_Xr(globalbest_fit_index,:)];%全局最优路径
%% 迭代
mem_global_bestfit=zeros(num_gen,1);%记录每一次迭代的全局最优值
mem_global_bestfit(1)=globalbest_fit;
gen=2;
while(gen<=num_gen)
    for i=1:num_pop
        Vv(i,:)=w*Vv(i,:)+c1*rand*(person_best_Xv(i,:)-Xv(i,:))+c2*rand*(globalbest_route(1,:)-Xv(i,:));
        Xv(i,:)=Xv(i,:)+Vv(i,:);
        Vr(i,:)=w*Vr(i,:)+c1*rand*(person_best_Xr(i,:)-Xr(i,:))+c2*rand*(globalbest_route(2,:)-Xr(i,:));
        Xr(i,:)=Xr(i,:)+Vr(i,:);
        Xv(i,:)=Valid_Xv(Xv(i,:),num_che);%规范化
        Xr(i,:)=Valid_Xr(Xv(i,:),Xr(i,:),num_che);
        for j=1:num_che     %惩罚项
            Capacity(j)=sum(need(find(Xv(i,:)==j)));
        end
        if isempty(find(Capacity>1,1))==0
            fit(i)=inf;
        else
            fit(i)=Fit(Xv(i,:),Xr(i,:),city,num_che);
        end  
    end
    %根据新的种群更新所有的局部最优解
    for i=1:num_pop
        if person_best_fit(i)>fit(i)
            person_best_fit(i)=fit(i);
            person_best_Xv(i,:)=Xv(i,:);
            person_best_Xr(i,:)=Xr(i,:);
        end
    end
    %根据所有的的局部最优解更新全局最优解
    if min(person_best_fit)<globalbest_fit
        [globalbest_fit,globalbest_fit_index]=min(person_best_fit);
        globalbest_route=[person_best_Xv(globalbest_fit_index,:);person_best_Xr(globalbest_fit_index,:)];
    end
    %记录每一代的全局最优解
    mem_global_bestfit(gen)=globalbest_fit;    
    gen=gen+1;
end    
%% 结果输出
plot(mem_global_bestfit,'k');
title('全局最小值变化曲线');
xlabel('迭代次数');
ylabel('总路程');

适应度函数:

function fit=Fit(Xv,Xr,city,num_che)%适应度函数
cangku=[18,54];
fit=0;
for i=1:num_che       %计算每辆车的路程
    index=find(Xv==i);
    y=Xr(1,index);
    t=[index;y]';
    tt=sortrows(t,2);
    f='sqrt(x(1)^2+x(2)^2)';%匿名函数
    dist=eval(['@(x)',f]);
    if size(tt,1)~=0
        fit=fit+dist(city(tt(1,1),:)-cangku);
        if size(tt,1)>1
            for j=2:length(tt(:,1))
                fit=fit+dist(city(tt(j,1),:)-city(tt(j-1,1),:));
            end
        end
        fit=fit+dist(city(tt(end,1),:)-cangku);
    end
end
end

规范化函数:

function [new_x]=Valid_Xr(Xv_i,Xr_i,num_che)
% 对Xr进行合法化,根据Xr的编码大小调整车辆的路径
new_x=ceil(Xr_i);
for i=1:num_che
    y=ceil(Xr_i(1,Xv_i==i)); %找出所有第i辆车运输的城市
    y=[y;1:length(y)];       %得到第i辆车运送的城市以及顺序
    t=sortrows(y',1)';       %第一列为这辆车拉的第几个城市,第二列为城市的刚才对应的Xr
    for j=1:length(t(2,:))
        y(2,t(2,j))=j;
    end
    new_x(1,Xv_i==i)=y(2,:);
end
end
function [a]=Valid_Xv(Xv,num_che)  %xr规范化
a=ceil(Xv);
for m=1:length(a)
    if a(m)<1
        a(m)=1;
    elseif a(m)>num_che
        a(m)=num_che;
    end
end
end
  • 11
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值