在使用面向对象的语言实现该算法的时候,可以定义粒子这一对象,其应具有属性:当前位置、当前速度、当前代价值、历史最优位置、历史最优代价值,应具有方法:速度更新方法、位置更新方法、代价值更新方法。
%
tic
clear
clc
%% 用importdata这个函数来读取文件
r101=importdata(‘r101.txt‘);
cap=200; %车辆最大装载量
%% 提取数据信息
E=r101(1,5); %配送中心时间窗开始时间
L=r101(1,6); %配送中心时间窗结束时间
vertexs=r101(:,2:3); %所有点的坐标x和y
customer=vertexs(2:end,:); %顾客坐标
cusnum=size(customer,1); %顾客数
v_num=25; %车辆最多使用数目
demands=r101(2:end,4); %需求量
a=r101(2:end,5); %顾客时间窗开始时间[a[i],b[i]]
b=r101(2:end,6); %顾客时间窗结束时间[a[i],b[i]]
s=r101(2:end,7); %客户点的服务时间
h=pdist(vertexs);
dist=squareform(h); %距离矩阵
%% 粒子群算法参数
alpha=10; %违反的容量约束的惩罚函数系数
belta=100; %违反时间窗约束的惩罚函数系数
NIND=50; %粒子数目
MAXGEN=100; %迭代次数
w=1; %惯性因子
wdamp=0.99; %惯性因子衰减率
c1=1.5; %个体学习因子
c2=2.0; %全局学习因子
XvMin=1; %Xv下限
XvMax=v_num; %Xv上限
XrMin=1; %Xr下限
XrMax=cusnum; %Xr上限
VvMin=-(v_num-1); %Vv下限
VvMax=v_num-1; %Vv上限
VrMin=-(cusnum-1); %Vr下限
VrMax=cusnum-1; %Vr上限
%% 初始化粒子群位置
init_vc=init(cusnum,a,demands,cap); %构造初始解
population=initpopCW(init_vc,NIND,cusnum,XvMin,XvMax,XrMin,XrMax,VvMin,VvMax,VrMin,VrMax);
ObjV=calObj(population,v_num,cap,demands,a,b,L,s,dist,alpha,belta); %计算各个粒子的目标函数值
gbest_pos=population{1,1}(1:2,:); %假设第一个粒子位置为全局最优位置
gbest_obj=ObjV(1,1); %第一个粒子位置的目标函数值
pbest_pos=cell(NIND,1); %初始化各个粒子的个体最优位置
pbest_obj=ObjV; %初始化各个粒子的个体最优的目标函数值
for i=1:NIND
particle=population{i,1}; %第i个粒子
position=particle(1:2,:); %第i个粒子的位置
pbest_pos{i,1}=position; %初始化这个粒子的个体最优
if pbest_obj(i,1)<gbest_obj
%更新初始种群中的全局最优粒子
gbest_obj=pbest_obj(i,1);
gbest_pos=position;
end
end
globalVC=decode(gbest_pos,v_num); %初始全局最优配送方案
%统计一个配送方案的总成本、车辆使用数目、行驶总距离、违反约束路径数目、违反约束顾客数目
[cost,NV,TD,vio_NV,vio_cus]=statistic(globalVC,a,b,s,L,dist,demands,cap,alpha,belta);
disp([‘初始全局最优解总成本为:‘,num2str(cost),‘,车辆使用数目为:‘,num2str(NV),...
‘,行驶总距离为:‘,num2str(TD),‘,违反约束路径数目为:‘,num2str(vio_NV),‘,违反约束顾客数目为:‘,num2str(vio_cus)]);
BestCost=zeros(MAXGEN,1); %记录每次迭代的全局最优目标函数值
%% 主循环
gen=1; %计数器
while gen<=MAXGEN
%% 更新各个粒子的位置和速度
for i=1:NIND
particle=population{i,1}; %第i个粒子
position=particle(1:2,:); %第i个粒子的位置
Xv=position(1,:);
Xr=position(2,:);
velocity=particle(3:4,:); %第i个粒子的速度
Vv=velocity(1,:);
Vr=velocity(2,:);
%% 更新速度
velocity=w*velocity+ +c1*rand([2,cusnum]).*(pbest_pos{i,1}-position)...
+c2*rand([2,cusnum]).*(gbest_pos-position);
%% 速度越界处理
velocity(1,:)=max(velocity(1,:),VvMin);
velocity(1,:)=min(velocity(1,:),VvMax);
velocity(2,:)=max(velocity(2,:),VrMin);
velocity(2,:)=min(velocity(2,:),VrMax);
%% 更新位置
position=position+velocity;
position(1,:)=ceil(position(1,:)); %对Xv向上取整
%% 速度镜像影响
IsOutside=(position(1,:)<XvMin | position(1,:)>XvMax | position(2,:)<XrMin | position(2,:)>XrMax);
velocity(IsOutside)=-velocity(IsOutside);
%% 位置越界处理
position(1,:)=max(position(1,:),XvMin);
position(1,:)=min(position(1,:),XvMax);
position(2,:)=max(position(2,:),XrMin);
position(2,:)=min(position(2,:),XrMax);
%% 对第i个粒子解码出的配送方案进行relocate操作
VC=decode(position,v_num);
RVC=relocate(VC,cap,demands,a,b,L,s,dist,alpha,belta);
position=change(RVC,cusnum);
%% 计算第i个粒子目标函数值
cost=costFuction(RVC,a,b,s,L,dist,demands,cap,alpha,belta);
%% 更新个体最优
if cost<pbest_obj(i,1)
pbest_pos{i,1}=position;
pbest_obj(i,1)=cost;
%% 更新全局最优
if pbest_obj(i,1)<gbest_obj
gbest_pos=pbest_pos{i,1};
gbest_obj=pbest_obj(i,1);
end
end
%% 更新第i个粒子的速度和位置
particle=[position;velocity];
population{i,1}=particle;
end
%% 记录各代全局最优解,打印各代全局最优解
BestCost(gen)=gbest_obj;
globalVC=decode(gbest_pos,v_num); %初始全局最优配送方案
%统计一个配送方案的总成本、车辆使用数目、行驶总距离、违反约束路径数目、违反约束顾客数目
[cost,NV,TD,vio_NV,vio_cus]=statistic(globalVC,a,b,s,L,dist,demands,cap,alpha,belta);
disp([‘第‘,num2str(gen),‘代全局最优解总成本为:‘,num2str(cost),‘,车辆使用数目为:‘,num2str(NV),...
‘,行驶总距离为:‘,num2str(TD),‘,违反约束路径数目为:‘,num2str(vio_NV),‘,违反约束顾客数目为:‘,num2str(vio_cus)]);
w=w*wdamp;
%% 更新计数器
gen=gen+1;
end
%% 将全局最优粒子解码为全局最优配送方案
globalVC=decode(gbest_pos,v_num);
%% 对全局最优配送方案进行局部搜索
globalVC=relocate_gbest(globalVC,cap,demands,a,b,L,s,dist,alpha,belta);
%% 统计全局最优配送方案的总成本、车辆使用数目、行驶总距离、违反约束路径数目、违反约束顾客数目
[cost,NV,TD,vio_NV,vio_cus]=statistic(globalVC,a,b,s,L,dist,demands,cap,alpha,belta);
disp([‘最终全局最优解总成本为:‘,num2str(cost),‘,车辆使用数目为:‘,num2str(NV),...
‘,行驶总距离为:‘,num2str(TD),‘,违反约束路径数目为:‘,num2str(vio_NV),‘,违反约束顾客数目为:‘,num2str(vio_cus)]);
%% 画出全局最优配送方案路线图
draw_Best(globalVC,vertexs);
%% Results
figure;
%plot(BestCost,‘LineWidth‘,2);
semilogy(BestCost,‘LineWidth‘,2);
xlabel(‘迭代次数‘);
ylabel(‘全局最优目标函数值‘);
grid on;
toc
