理论基础
问题导入
MATLAB程序实现及结果分析
总结与扩展
TSP (traveling salesman problem,旅行商问题)是典型的NP完全问题,即其最坏情况下的时间复杂度随着问题规模的增大按指数方式增长,到目前为止还未找到一个多项式时间的有效算法。
TSP问题可描述为: 已知有 n 个城市,各城市之间互相联通,且城市间的距离已知,某一旅行商从某个城市出发访问每个城市一次且仅一次,最后回到出发城市,如何安排才使其所走路线最短。简言之,就是寻找一条最短的遍历n个城市的路径,或者说搜索自然子集X={1,2,…,n}(X的元素表示对n个城市的编号)的一个排列n(X)={Vi,V ,…,Vn},使
取最小值,其中d(Vi,Vi+1)表示城市Vi,到城市Vi+1的距离。
目前,随着人工智能的迅速发展,人们已经提出了许多智能优化算法并应用于TSP问题,如模拟退火算法、蚁群优化算法、遗传算法、神经网络算法等。本文将采用遗传算法进行求解,遗传算法理论基础以及代码实现在遗传算法详解及其MATLAB实现中进行了详细介绍,感兴趣的伙伴可以去学习一下,这里就不再阐述了。
假定某配送中心及其服务客户分布在二维坐标内,服务客户的位置坐标如下所列,寻找一条最短的遍历14个服务客户的路径。
(看步骤时可以配合对应程序,本文完整程序在文章末尾获得)
1)初始化
对于n个不同地点,首先初始化种群,定义种群规模为m(m个个体),其取值视地点规模大小而确定,一般在50~200之间浮动。对于个体,采用整数排列的编码方式,个体染色体长度为n段,每一段对应一个地点的编号,如对5个地点的TSP问题{1,2,3,4,5},则|1|3|4|2|5|就是一个染色体。
2)定义适应度函数
对于x1|x2…|xi|…|xn|这样一个染色体,Dxixj为地点xi到xj的距离,则个体的适应度可定义为
该适应度可解释为:走完x1|x2…|xi|…|xn|这个染色体的路径,再回到出发地点的距离的倒数,优化即是选择使得适应度尽可能大的染色体。
3)选择、交叉、变异算法更新染色体
选择
选择即尽可能将适应度高的个体保留,将适应度低的个体舍弃,保证种群向适应度高的方向进化。本文通过轮盘赌来设计选择算子:从种群中选择m次,每次选择1个个体,某个体在其中一次选择中的被选择概率为该个体适应度值与种群m个个体适应度之和之比。通过上述算法能选出m个优秀个体,再进行交叉、变异操作。
交叉
采用部分映射杂交,从m个个体中选择交叉的父代,两两组队,以交叉概率Pc对每对个体进行随机位置的交叉,具体过程如下:(假设地点有10处)
① 产生两个[1,10]区间内的随机整数r1和r2,确定两整数位置,对两位置的中间数据进行交叉,如r1=4,r2=7。
② 交叉后,若同一个个体存在重复的基因,则将有重复的基因(带*位置)采用中间段的对应关系进行映射(即从另一个交叉个体的交叉区间中寻找和自己交叉后交叉段位没有重复的基因)。结果为
变异后为
4)进化逆转
为改善遗传算法的局部搜索能力,在选择、交叉、变异之后引进连续多次的进化逆转操作。这里的“进化”是指逆转算子的单方向性,即只有经逆转后,适应度值有提高的才接受下来,否则逆转无效。
产生两个[1,10]区间的随机整数r1和r2,将其对换位置,如r1=4,r2=7
进化逆转后
5)循环
初始化种群后,然后计算其适应度,选择适应度大的个体进行交叉变异以及进化逆转,循环,若未达到最大遗传代数,则跳入适应度计算,若达到,则终止。
本文的基于遗传算法的TSP优化算法流程如下。
clear
clc
close all
%% 加载数据
load('CityPosition1.mat')
D=Distanse(X); %生成距离矩阵
N=size(D,1); %城市个数
%% 遗传参数
NIND=100; %种群大小
MAXGEN=100; %最大遗传代数
Pc=0.9; %交叉概率
Pm=0.05; %变异概率
GGAP=0.9; %代沟
%% 初始化种群
Chrom=InitPop(NIND,N);
%% 画出随机解的路径图
DrawPath(Chrom(1,:),X)
pause(0.0001)
%% 输出随机解的路径和总距离
disp('初始种群中的一个随机值:')
OutputPath(Chrom(1,:));
Rlength=PathLength(D,Chrom(1,:));
disp(['总距离:',num2str(Rlength)]);
disp('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
%% 优化
gen=0;
figure;
hold on;box on
xlim([0,MAXGEN])
title('优化过程')
xlabel('代数')
ylabel('最优值')
ObjV=PathLength(D,Chrom); %计算路径长度
preObjV=min(ObjV);
while gen<MAXGEN
%% 计算适应度
ObjV=PathLength(D,Chrom); %计算路径长度
% fprintf('%d %1.10f\n',gen,min(ObjV))
line([gen-1,gen],[preObjV,min(ObjV)]);pause(0.0001)
preObjV=min(ObjV);
FitnV=Fitness(ObjV);
%% 选择
SelCh=Select(Chrom,FitnV,GGAP);
%% 交叉操作
SelCh=Recombin(SelCh,Pc);
%% 变异
SelCh=Mutate(SelCh,Pm);
%% 逆转操作
SelCh=Reverse(SelCh,D);
%% 重插入子代的新种群
Chrom=Reins(Chrom,SelCh,ObjV);
%% 更新迭代次数
gen=gen+1 ;
end
%% 画出最优解的路径图
ObjV=PathLength(D,Chrom); %计算路径长度
[minObjV,minInd]=min(ObjV);
DrawPath(Chrom(minInd(1),:),X)
%% 输出最优解的路径和总距离
disp('最优解:')
p=OutputPath(Chrom(minInd(1),:));
disp(['总距离:',num2str(ObjV(minInd(1)))]);
disp('-------------------------------------------------------------')
本文利用遗传算法优化了TSP路径,得到了不错的效果,并且该方法不仅能应用于TSP问题,也能用于生产安排等问题。
同时,本文使用的遗传算法较之于传统方法,作了2方面改进,其一使用了精英策略,保证子代个体最优不会比父代差,其次使用进化逆转操作,一方面其能维持种群多样性,但另一方面它不利于子代继承亲代较多信息。
本文完整程序
链接:https://pan.baidu.com/s/1cP4nAb80I3bB-PgvWFQwag
提取码:1111
感兴趣的朋友可以关注公众号:川子凯 ,作者不定时分享各类代码/日常