我只选取了索罗门数据集的20位顾客,只考虑载重约束,未考虑时间窗约束。
染色体的编码方式带分隔,如01230450670
这种染色体表示方式能有利于我们马上得出车辆行驶方案,即三辆车分别服务{123}、{45}、{67}。
顾客数:20
1-20随机排列,然后依次插入染色体中,并且比较插入各个位置的可行(满足载重约束)方案,
如现在要将2插入到0130490中那可插入的方案有length(r)-1=6种:02130490、01230490、01320490、01302490、01304290、01304920。
留下满足载重约束的染色体,
选择最小距离和的染色体,然后再在此染色体的基础上再插入剩余顾客
迭代你需要的种群大小的次数,就可以得到较好的初始种群。
当然生成初始种群的方法有很多种。
主代码:
clc
clear
c101=importdata('c101.txt');
c102=c101(1:21,:); %提取前20位顾客
cap=100; %车辆最大装载量
% 提取数据信息
xypos=c102(:,2:3); %所有点的坐标x和y
customerXY=xypos(2:end,:); %顾客坐标
customerQty=size(customerXY,1); %顾客数
v_num=3; %车辆最多使用数目
demands=c101(2:end,4); %需求量
newXY=xypos';
nowDist=dist(newXY); %距离矩阵
popsize=50; %种群大小
%生成初始种群
Popu=inChromes(popsize,customerQty,demands,cap,nowDist); %生成初始种群的函数
popus=Popu(1:popsize,:);
chromes=sortrows(popus,2); %路径,目标值升序排列
optRoute=cell2mat(chromes(1,1)); %最短距离的路径且转为矩阵
optFitness=cell2mat(chromes(1,2)); %最短距离的路径对应的目标值
生成初始种群函数代码:
function Popu=inChromes(popsize,customerQty,demands,cap,nowDist)
Popu=cell(100,1); %种群
for p=1:popsize
s=1;
r=[0 0 0 0 0];
Q=randperm(customerQty);
while s<=customerQty
q=Q(s); %利用for循环将20个客户点(随机排列)插入路径中
W=[]; %将各个路径的目标值存在W中
R=cell(100,1); %将各个路径存在R(元胞数组)中
for v=1:length(r)-1 %客户点q插入各个位置的方案
if v==1
A=[r(1),q,r(v+1:end)];
elseif v==length(r)-1
A=[r(1:v),q,r(length(r))];
else
A=[r(1:v),q,r(v+1:end)];
end
output=Result(demands,cap,A); %判断这个A是否满足约束
if output==1
L=Dists(A,nowDist); %输出目标函数值
W=[W,L]; %将各个路径的目标值存在W中
t=length(W);
R{t,1}=A; %将各个路径存在R中
end
end
in_val=min(W);
in_idx=find(W==in_val); %找到最小值所在位置
r=R{in_idx}; %将最小的目标值对应的路径赋给r
s=s+1;
end
Popu{p,1}=r;
Popu{p,2}=in_val;
end
end
Result函数代码:
function [result]=Result(demands,cap,A)
for i=1:length(A)
if A(i)==0
w=0;
else w=w+demands(A(i));
if w>cap %判断是否满足载重约束
result=0;
break
end
end
result=1;
end
end
Dists函数代码:
% 计算目标函数值(染色体距离和)
function [L]=Dists(A,nowDist)
L=0;
b=1;
for j=1:length(A)
L=L+nowDist(b,A(j)+1);
b=A(j)+1;
end
end
matlab新手小白,欢迎批评指正!也希望大佬们提出建议。