回来填坑了,本篇推文将详细讲解ALNS算法求解VRP问题及MATLAB代码实现。
算法介绍
节约算法构造初始解
function routes=saving_init(DistMatrix, Demand, Cap)
C_EPS=1e-1;N=size(DistMatrix,1);
routes=cell(numel(2:N),1);
for i=1:numel(routes) % 每个节点单独一条路径routes{i}=i+1;
endroute_demands=Demand(1:end);
saving=clarke_wright_savings(DistMatrix); % 计算节约值矩阵endnode_to_route=[1,1:N-1];for p=1:size(saving,1)i=saving(p,3);j=saving(p,4);cw_saving = DistMatrix(i,1)+DistMatrix(1,j)-DistMatrix(i,j);if cw_saving<0breakendleft_route = endnode_to_route(i);right_route = endnode_to_route(j);if isnan(left_route) || isnan(right_route) || left_route==right_routecontinueendmerged_demand = route_demands(left_route)+route_demands(right_route);if merged_demand-C_EPS > Capcontinueendroute_demands(left_route) = merged_demand;if routes{left_route}(1)==iroutes{left_route}=flip(routes{left_route});endif routes{right_route}(end)==jroutes{right_route}=flip(routes{right_route});endif numel(routes{left_route})>1endnode_to_route( routes{left_route}(end)) = nan;endif numel(routes{right_route})>1endnode_to_route( routes{right_route}(1)) = nan;endendnode_to_route( routes{right_route}(end) ) = left_route;routes{left_route}=[routes{left_route},routes{right_route}];routes{right_route} = nan;
endroutes(cellfun(@(routes) any(isnan(routes)),routes)) = [];
移除算子
1、随机移除算子
function [removed,remove_vc] = RandomRemove(currentSol,dist,toRemove)%% Remove
cusnum=size(dist,1)-1;
visit=ceil(rand*cusnum); %随机从所有顾客中随机选出一个顾客
inplan=1:cusnum; %所有顾客的集合
inplan(inplan==visit)=[]; %将被移出的顾客从原有顾客集合中移出
removed=[visit]; %被移出的顾客集合while length(removed)<toRemovenip=length(inplan); %原来顾客集合中顾客的数量vc=inplan(ceil(rand*nip)); %从inplan数组中选择一个客户removed=[removed vc]; %向被移出的顾客集合中添加被移出的顾客inplan(inplan==vc)=[]; %将被移出的顾客从原有顾客集合中移出
end
remove_vc=currentSol; %移出removed中的顾客后的current_vc
nre=length(removed); %最终被移出顾客的总数量
NV=size(currentSol,1); %所用车辆数
for i=1:NVroute=currentSol{i};for j=1:nrefindri=find(route==removed(j),1,'first');if ~isempty(findri)route(route==removed(j))=[];endendremove_vc{i}=route;
end[ remove_vc] = deal_vehicles_customer( remove_vc );
end
修复算子
贪婪插入算子
function [newRoutes] = GreedyInsert(removed,removeSol,dist,demands,cap)while ~isempty(removed)%% 将最小插入目标距离增量最小的元素找出来[InsertCustomer,InsertVehicle,InsertPosition]=shortestINS(removed,removeSol,dist,demands,cap);removed(removed==InsertCustomer)=[];%% 根据插入点将元素插回到原始解中[removeSol]=insert(InsertCustomer,InsertVehicle,InsertPosition,removeSol);
end
[ newRoutes ] = deal_vehicles_customer(removeSol);
end
输出路径结果
function PlotSolution(model,FinalRoutes)numRoutes=numel(FinalRoutes);xCoords=model.x;
yCoords=model.y;
xCoords_depot=xCoords(1);
yCoords_depot=yCoords(1);Colors=hsv(numRoutes*1);for j=1:numRoutesif isempty(FinalRoutes{j})continue;endX=[xCoords_depot xCoords(FinalRoutes{j}(2:end-1)) xCoords_depot];Y=[yCoords_depot yCoords(FinalRoutes{j}(2:end-1)) yCoords_depot];Color=1*Colors(j,:);plot(X,Y,'-o',...'Color',Color,...'LineWidth',2,...'MarkerSize',10,...'MarkerFaceColor',Color);hold on;endplot(xCoords_depot,yCoords_depot,'ks',...'LineWidth',2,...'MarkerSize',15,...'MarkerFaceColor','yellow');hold on;for i=2:numel(xCoords)text(xCoords(i)-.5,yCoords(i)+2,num2str(i));
end
end
结果展示
参考文献
PISINGER D, ROPKE S. A general heuristic for vehicle routing problems [J]. Computers & Operations Research, 2007, 34(8): 2403-2435.
ROPKE S, PISINGER D. An adaptive large neighborhood search heuristic for the pickup and delivery problem with time windows [J]. Transportation Science, 2006, 40(4): 455-472.
若有运筹优化建模及算法定制需求,欢迎联系我们私聊沟通