% 遗传算法求解旅行商问题
% 系统初始化
clear
close all
clc
% 定义起点和终点
R1 = [50;50];
R2 = [500;660];
% 定义途经点
Points = [171.1867 431.8328 346.1714 823.4578 634.4461 381.5585 795.1999 200 620;
706.0461 276.9230 97.1318 694.8286 438.7444 765.5168 186.8726 500 860];
xy = [R1 Points R2];
N = size(xy,2);
% 计算距离矩阵dmat = zeros(N,N);
% 定义距离矩阵
for i = 2:N
for j = 1:i-1
d = norm(xy(:,i)-xy(:,j));
dmat(i,j) = d;
dmat(j,i) = d;
end
end
% 遗传算法参数
popSize = 32; % 种群大小
numIter = 300; % 迭代次数
[N,~] = size(dmat);
n = N-2; % 编码长度
% 检测
popSize = 4*ceil(popSize/4);
numIter = max(1,round(real(numIter(1))));
% 初始化种群
pop = zeros(popSize,n);
pop(1,:) = (2:n+1);
for k = 2:popSize
pop(k,:) = randperm(n)+1;
end
% 遗传算法相关变量
globalMin = Inf; % 记录最小值
totalDist = zeros(1,popSize); % 记录总距离
distHistory = zeros(1,numIter); % 记录历史值
tmpPop = zeros(4,n); % 临时种群
newPop = zeros(popSize,n); % 新种群
% 遗传算法开始迭代
for iter = 1:numIter
% 评估种群中每一个个体
for p =1:popSize
d = dmat(1,pop(p,1));
for k = 2:n
d =d+dmat(pop(p,k-1),pop(p,k));
end
d = d + dmat(N,pop(p,n));
totalDist(p) = d;
end
% 找出最优路径
[minDist, index] = min(totalDist);
distHistory(iter) = minDist;
% 替代上一次进化汇总最好的染色体
globalMinOld = globalMin;
if(minDist < globalMin)
globalMin = minDist;
optRoute = pop(index,:);
end
% 遗传操作
randomOrder = randperm(popSize);
for p = 4:4:popSize
rtes = pop(randomOrder(p-3:p),:);
dists = totalDist(randomOrder(p-3:p));
[~,idx] = min(dists);
bestOf4Route = rtes(idx,:); % 每4个里面找一个最好的
routeInsertionPoints = sort(ceil(n*rand(1,2)));
I = routeInsertionPoints(1);
J = routeInsertionPoints(2);
% 由最好个体变异,得到其他3个个体
for k = 1:4
mpPop(k,:) = bestOf4Route;
switch k
case 2 % 翻转
mpPop(k,I:J) = tmpPop(k,J:-1:I);
case 3 % 交换
tmpPop(k,[I J]) = tmpPop(k,[J I]);
case 4 % 滑移
mpPop(k,I:J) = tmpPop(k,[I+1:J I]);
otherwise
end
end
newPop(p-3:p,:) = tmpPop;
end
pop = newPop;
end
% 最优化路径
optRoute = [1 optRoute N]; % 补全起点和终点
% 绘图:地图
figure('name','地图','color',[1,1,1]);
plot(R1(1),R1(2),'ko');
text(R1(1)+20,R1(2)-20,'S','FontName','Times New Roman','FontSize',12);
hold on
axis equal
axis([0 1000 0 1000]);
plot(R2(1),R2(2),'k*');
text(R2(1)+20,R2(2)-20,'T','FontName','Times New Roman','FontSize',12);
plot(Points(1,:),Points(2,:),'k^');
set(gca,'FontName','Times New Roman','FontSize',12);
xlabel('$x/\rm{m}$','interpreter','Latex');
ylabel('$y/\rm{m}$','interpreter','Latex');
plot(xy(1,optRoute),xy(2,optRoute),'b','linewidth',1);
grid on
% 绘图:迭代曲线
xmax = length(distHistory);
figure('name','迭代曲线','color',[1,1,1]);
plot(distHistory,'b','linewidth',1);
xlim([1,xmax]);
set(gca,'FontName','Times New Roman','FontSize',12);
xlabel('迭代次数','FontName','宋体');
ylabel('$d/\rm{m}$','interpreter','Latex');
grid on
计算结果:
迭代曲线: