遗传算法解决旅行商(TSP)问题
遗传算法解决旅行商问题
作为NP难的经典问题,旅行商问题有多种算法可以解决。
我学习的过程中,首先看到了模拟退火算法解决旅行商问题的过程,模拟退火算法可以保证100%的找到全局最小值。
在我研究遗传算法的过程中,我突然想试一下怎样用遗传算法中选择、交叉的变异的思路来解决这个问题。
以52城的题目为例
使用遗传算法进行解题
首先考虑如何初始化种群,我选择用randperm(52)直接生成一个1到52的随机序列,作为我的一个个体。种群的规模为200.
然后考虑遗传算法的适应值怎么确定,这里取每一个个体的总路径的倒数作为适应度。
我用下面这段程序求目标函数和适应度,并用模拟退火方法求出的最优解代入,以确定代码是正确的。
clc;
clear all;
w=[565 575;25 185;345 750;945 685;845 655;880 660;25 230;525 1000;580 1175;650 1130;1605 620;1220 580;1465 200;1530 5;845 680;725 370;145 665;415 635;510 875;560 365;300 465;520 585;480 415;835 625;975 580;1215 245;1320 315; %坐标输入1250 400;660 180;410 250;420 555;575 665;1150 1160;700 580;685 595;685 610;770 610;795 645;720 635;760 650;475 960;95 260;875 920;700 500;555 815;830 485;1170 65;830 610;605 625;595 360;1340 725;1740 245];
a=w(:,1); %x坐标
b=w(:,2); %y坐标
ctamount=size(w,1);
d=zeros(ctamount,ctamount);
for i=1:ctamountfor j=1:ctamountd(i,j)=sqrt((a(i)-a(j)).^2+(b(i)-b(j)).^2); %求出两城之间的距离矩阵end
end
a=[17 21 42 7 2 30 23 20 50 29 16 46 44 34 35 36 39 ...40 37 38 48 24 5 15 6 4 25 12 28 27 26 47 13 14 ...52 11 51 33 43 10 9 8 41 19 45 32 49 1 22 31 18 3];
e=0;
for i=1:ctamount-1e=e+d(a(i),a(i+1));
end
f=e+d(a(ctamount),a(1)); %最后求解出的结果是7554,和模拟退火的结果一致,说明目标函数的求解方法是正确的
syd=1/f;
当然,重要的部分是如何产生新种群的过程
选择方式
我的思路是对于规模为200的种群,每次选四个个体,其中最优的被选择,最差的被淘汰,且最优的替代最差的。
交叉方式
交叉方式我是参考这篇文章:
https://blog.csdn.net/woaixuexihhh/article/details/83826256
这是二交叉的方法,代码也比较好实现。
变异方式
变异方式也是参考以上链接,随机产生两个变异位,将两变异位之间的序列进行倒序。
代码如下:(求距离矩阵的代码在最上面,就不重复啦)
popsize=200;
sydmax=0;
xbest=ones(1,ctamount); %初始化
genmax=100000;
generation=1;
for k=1:popsizee=0;U(k,:)=randperm(ctamount); %产生第一组规模为200 的种群for i=1:ctamount-1e=e+d(U(k,i),U(k,i+1)); endf=e+d(U(k,ctamount),U(1));syd=1/f;W(k)=syd;
end
[sydmax,plan]=max(W) %将这个种群的适应度和最优解保存下来
xbest=U(plan,:);
下面开始迭代啦
while generation<=genmaxfor k=1:4:popsize-3 %每次取四个个体M=W(k:k+3);[maxom,maxnum]=max(M);[minom,minnum]=min(M);Umax=U(maxnum+k-1,:); %最大的那个直接保留Umin=U(minnum+k-1,:); %最优的代替最差的;M(maxnum)=0;M(minnum)=0;[maxom2,maxnum2]=max(M);M(maxnum2)=0;[minom2,minnum2]=max(M); %代码到现在其实是在对四个适应度值进行排序,然后把适应度值对应的W矩阵的索引取出注意:取M的索引就错啦,因为M的索引只能是1到4long=zeros(2,ctamount);long(1,:)=U(maxnum2+k-1,:); %适应度值居中的两个个体进行交叉long(2,:)=U(minnum2+k-1,:); %用long矩阵来表示需要进行交叉的两个个体size(long);u=sj(ctamount); %随机产生两个介于0,52的不同的数,作为交叉点,sj函数代码附在后面short=zeros(2,max(u)-min(u)+1);short(1,:)=long(1,min(u):max(u));short(2,:)=long(2,min(u):max(u)); %将原个体介于交叉点之间的序列保存在short矩阵里size(short);for i=min(u):max(u)long(:,i)=0; %先把long交叉点之间的序列清零endtep=long(1,:);long(1,:)=long(2,:); %除中间字串之外的对位交换long(2,:)=tep;for j=1:ctamountpanduan=long(1,j);while ismember(panduan,short(2,:)) tep=find(short(2,:)==long(1,j)); %然后把short矩阵里面的数交叉赋值给long的全0段long(1,j)=short(1,tep);endendfor j=1:ctamountwhile ismember(long(2,j),short(1,:)) % 用ismember函数来保证交叉之后的数不与中间序列重复tep=find(short(1,:)==long(2,j)); % 如果重复就把另一个个体中与重复位对应的数值取过来long(1,j)=short(2,tep);endendlong(1,min(u):max(u))=short(2,:);long(2,min(u):max(u))=short(1,:); %产生交叉后的群体U(k,:)=bianyi(Umax);U(k+3,:)=bianyi(Umax);U(k+1,:)=bianyi(long(1,:)); %每个个体都有一定概率的变异率,所以小于变异概率的就认为该个体发生变异。U(k+2,:)=bianyi(long(2,:)); %bianyi函数附在后面end for m=1:popsizee=0;for i=1:ctamount-1e=e+d(U(m,i),U(m,i+1));endf=e+d(U(m,ctamount),U(1));syd=1/f;W(m)=syd;end[sydnew,plannew]=max(W);if sydnew>sydmaxsydmax=sydnewxbest=U(plannew,:) %最后就是把每次迭代中的最优值保存下来与当前最优值作比较。endsydzhi(generation)=sydmax;generation=generation+1;
end
pathleast=1/sydmax
x=1:genmax; %我这里把迭代过程中最优值得变化做了一个图
plot(x,sydzhi,'x')
下面是子函数
1.变异函数
function v=bianyi(Q)
ctamount=size(Q,2);
pby=0.1;
r=rand;
if r<pbyu=sjby(ctamount);%产生两个随机变异位tep=Q(min(u):max(u));Q(min(u):max(u))=fliplr(tep);
end
v=Q;
2.随机产生两个交叉点,且非头尾两点
function u=sj(ctamount)
count =1;
f=[1,ctamount];
while count<=2u(count)=ceil(rand*ctamount);if ~ismember(u(count),f)count=count+1;end
end
3.随机产生两个变异位函数
function u=sjby(ctamount)
count =1;
f=[1,ctamount];
while count<=2u(count)=ceil(rand*ctamount);if ~ismember(u(count),f)count=count+1;end
end
运行以上代码得结果为:在迭代19700次的时候找到最优。迭代次数还是挺多的,这说明选择的产生新种群的办法还有待优化。
最终求出来52城的最小路径为:7846.8。
对52城的问题模拟退火算法为7544.4,还有更小的解7542。
说明这个结果还有待优化。
接下来调整参数,因为种群规模一般选0-100,我选的200明显太大了,种群规模大容易造成结果难收敛且浪费。
最后选的种群数量是80 ,结果为7670 。
但是就先这样吧,我去啃别的算法啦
遗传算法解决旅行商(TSP)问题相关推荐
- 模拟退火(SA, Simulated Annealing)算法解决旅行商TSP问题
01 什么是旅行商问题(TSP)? TSP问题(Traveling Salesman Problem,旅行商问题),由威廉哈密顿爵士和英国数学家克克曼T.P.Kirkman于19世纪初提出.问题描述如 ...
- 分支限界解决旅行商tsp问题
本人的算法大作业 参考博客: http://blog.csdn.net/qq_32400847/article/details/51813606 http://www.cnblogs.com/ciel ...
- 【Tsinghua】旅行商(TSP)
关于这道题,我要说两句,这道题我觉得我用拓扑排序的思路肯定是没错的,而且也对了几组数据,但是其他几组却超时,肯定是哪里的代码优化的不够好...... 最后只得了40分... 旅行商(TSP) 描述 S ...
- 鲸鱼优化算法WOA求解旅行商TSP优化问题(2022.6.2)
鲸鱼优化算法WOA求解旅行商TSP优化问题(2022.6.2) 引言 1.鲸鱼优化算法WOA 1.1 WOA算法原理介绍 1.1.1 包围猎物 1.1.2 气泡网式攻击猎物(开发阶段) 1.1.3 寻 ...
- 【路径规划】基于灰狼算法求解旅行商TSP问题matlab源码
一.旅行商问题 TSP问题即旅行商问题,经典的TSP可以描述为:一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地.应如何选择行进路线,以使总的行程最短.从图 ...
- Solve TSP with dynamic programming——动态规划解决旅行商(邮递员)问题
无向简单图的TSP算法 小规模精确解: 算法思想: 小规模精确解的算法中心思想是动态规划思想. 假设给定顶点集合V为{0,1,2,3,4,... .n}.由于图为无向完全图,我们可以很自然地将0视为输 ...
- MATLAB实战系列(十九)-遗传算法解决TSP(旅行商)问题-应用及解析(文末附MATLAB源码)
接上篇MATLAB实战系列(十八)-遗传算法解决TSP(旅行商)问题-算法原理 https://wenyusuran.blog.csdn.net/article/details/114060030 感 ...
- matlab算法大全 pdf_遗传模拟退火算法求解旅行商(TSP)问题
hello大家好,很高兴又和大家见面了.在之前的遗传算法(GA)求解旅行商问题(TSP)MATLAB代码讲解和模拟退火(SA)算法求解旅行商 (TSP)问题MATLAB代码讲解这两篇推文中,分别讲解了 ...
- 遗传算法解决tsp问题(基于python)
目录 1.遗传算法简要介绍 2.tsp问题简要介绍 3.遗传算法解决tsp问题的几个特殊点 4.源码 1.遗传算法简要介绍 简单来说,遗传算法是用于解决最优化问题的一种搜索算法.其核心基于自然界种群进 ...
最新文章
- 【SLAM建图和导航仿真实例】(三)- 使用RTAB-MAP进行SLAM建图和导航
- Spring Boot Web 开发相关总结
- head()函数python_Python中的Pandas DataFrame head()方法
- PLSQL 之类型、变量和结构
- 台达plc控制伺服电机编程实例_PLC控制伺服电机:控制脉冲的相关计算
- ClassNotFoundException: INameEnvironment
- c语言10000以内最大的质数,for语句计算输出10000以内最大素数怎么搞最简单??各位大神们...
- k8s token 过期了怎么加入worker 节点
- emmet工具使用和技巧
- C#俄罗斯方块代码完整版带部分注释
- android 9.0 安装xpose框架
- 计算机检索中常用的截断方式,文献检索方法与检索策略制定
- 根据MAC地质反查IP工具-LanHelper
- 【干货】在拉斯维加斯,程序员如何靠bandits算法干掉老虎机
- 2013年第三季度总结报告
- editor.md中markdown编辑器的实现
- C prime plus 第六版 课后编程练习 第4章
- Android P 如何挂载system镜像到根目录
- HyperMesh 2D网格划分
- nyoj541 最强DE 战斗力 (大数问题)