题目描述 :
现有16个客户点,1个配送中心。客户点有不同数量的货物需求、期望收货时间以及所能接受的收货时间。有7辆运送货物的车,每辆车有不同的承载量。现需要指派n(n<=7)辆货车携带货物送往客户点,在不超载的情况下,保证每个客户收到货物并且由一辆货车满足配送要求,还要保证客户在可接受收货时间内收到货物(在客户所能接受的收货时间之外收到货物不满足配送要求),目标函数为满足配送要求的条件下成本最小,并给出具体配送方案。
目标函数:
其中,f1代表车辆行驶距离造成的费用,α为单位路程的行驶费用。f2代表早到或者晚到的惩罚成本,D为惩罚系数。
约束函数:
其中,第一个约束为配送中心发出的车辆不许超过配送中心车辆的最大值,第二个约束为配送客户的货物之和不得超过车辆的容量,第三个约束为车辆到达时间不得超过客户能接受的到货时间。
求解:
采用遗传算法,算法框图如下:
算法编程难点在于对解集的建立和变换,对于这种复杂的解集,本文采用matlab的元胞数组建立解集,如下图所示。每一行代表一个个体,也就是一个解。
对于每一行来说,第一个数组表示选择车的数量
第二个数组表示选择车的编号,例如populationMat{1,2}=[2,3,7,6],代表的含义为选择第2,3,7,6号车。
第三列数组表示车所对应的配送客户数目。例如populationMat{1,3}=[5,6,2,3]代表第2号车配送5个客户,第3号车配送6个客户,第7号车配送2个客户,第6号车配送3个客户。
第四列数组代表客户的编号,populationMat{1,3}=[1 3 15 11 4 16 2 5 12 13 14 10 9 6 7 8],代表2号车需要配送5个客户,这5个客户分别是第1 3 15 11 4号客户,3号车需要配送6个客户,这6个客户分别是16 2 5 12 13 14,以此类推。
以下是主函数部分,函数总体是按照遗传算法步骤来写的,初始化种群,计算适应度,选择,交叉,变异...
%% 清空变量
clear
clc
%% 导入参数
[expectTime,acceptTime,serviceTime,customerPosition,customerRequirement,distriCenterPosition,speed,truckVolume] = DataFunction;
%% 定义变量
populationNumber = 50; %种群数量
probabilityMat = [0.01,0.1,0.3,0.3,0.1,0.1,0.09]; %概率矩阵
N = length(customerRequirement); %客户的数目
M = length(probabilityMat); %车辆的最大数目
alpha = 1; %单位距离运输费用
D = 1; %过早或者过晚到达时时间成本
pro = 0.1; %变异概率
populationMat = cell(populationNumber,4); %种群数据矩阵
iter = 1; %当前迭代次数
iterMax = 500; %最大迭代次数
bestValueNow = inf;
bestValueMat = zeros(populationNumber,1);
bestSolveNow = cell(1,4);
bestValue = inf;
bestSolve = cell(1,4);
%% 初始化种群
populationMat = InitializeIndividuality(populationMat,populationNumber,M,N,probabilityMat,distriCenterPosition,customerPosition,truckVolume,customerRequirement,speed,acceptTime,serviceTime);
while iter<iterMax
%% 计算适应度
p = CalcuFitCapacity(populationMat,distriCenterPosition,customerPosition,populationNumber,alpha,speed,expectTime,D,serviceTime);
%% 选择
populationMat = SelectionFunction(populationMat,populationNumber,p);
%% 交叉
populationMat = CrossFunction(populationMat,populationNumber,distriCenterPosition,customerRequirement,truckVolume,customerPosition,speed,acceptTime,serviceTime,N);
%% 变异
populationMat = HeteromorphosisFunction(populationMat,probabilityMat,pro,populationNumber,M,N,customerRequirement,distriCenterPosition,customerPosition,truckVolume,speed,acceptTime,serviceTime);
%% 寻找最优解
[bestValueNow,bestSolveNow] = CalcuBestIndividuiality(populationMat,populationNumber,distriCenterPosition,customerPosition,alpha,speed,expectTime,D,serviceTime);
if bestValueNow<bestValue
bestValueMat(iter) = bestValueNow;
bestValue = bestValueNow;
bestSolve = bestSolveNow;
else
bestValueMat(iter) = bestValue;
end
iter = iter+1;
end
%% 可视化最优解
DrawPicture(bestSolve,distriCenterPosition,customerPosition,bestValueMat,N,speed,expectTime,serviceTime);
%% 输出结果
disp(['选取的车辆编号为:',num2str(bestSolve{1,2}),',总费用为:',num2str(bestValue),'万元']);
numberMat = cumsum(bestSolve{1,3});
for k1 = 1:bestSolve{1,1}
if k1 == 1
disp(['第',num2str(bestSolve{1,2}(k1)),'号车辆服务的客户为:',num2str(bestSolve{1,4}(1:numberMat(k1)))]);
else
disp(['第',num2str(bestSolve{1,2}(k1)),'号车辆服务的客户为:',num2str(bestSolve{1,4}(numberMat(k1-1)+1:numberMat(k1)))]);
end
end
以下是运行结果:
获取代码方式:遗传算法求解VRPTW问题
自己手写遗传算法求解配送车辆路径问题(含时间窗VRPTW),代码逻辑清晰,内含详细注释,代码可直接运行,而且含视频教程!!!
代码均为本人手写,创作不易。
代码可作为日常学习使用,不得用于商业和私自摆卖,违者追究法律责任,望重视!!!