遗传算法解决旅行商问题

作为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)问题相关推荐

  1. 模拟退火(SA, Simulated Annealing)算法解决旅行商TSP问题

    01 什么是旅行商问题(TSP)? TSP问题(Traveling Salesman Problem,旅行商问题),由威廉哈密顿爵士和英国数学家克克曼T.P.Kirkman于19世纪初提出.问题描述如 ...

  2. 分支限界解决旅行商tsp问题

    本人的算法大作业 参考博客: http://blog.csdn.net/qq_32400847/article/details/51813606 http://www.cnblogs.com/ciel ...

  3. 【Tsinghua】旅行商(TSP)

    关于这道题,我要说两句,这道题我觉得我用拓扑排序的思路肯定是没错的,而且也对了几组数据,但是其他几组却超时,肯定是哪里的代码优化的不够好...... 最后只得了40分... 旅行商(TSP) 描述 S ...

  4. 鲸鱼优化算法WOA求解旅行商TSP优化问题(2022.6.2)

    鲸鱼优化算法WOA求解旅行商TSP优化问题(2022.6.2) 引言 1.鲸鱼优化算法WOA 1.1 WOA算法原理介绍 1.1.1 包围猎物 1.1.2 气泡网式攻击猎物(开发阶段) 1.1.3 寻 ...

  5. 【路径规划】基于灰狼算法求解旅行商TSP问题matlab源码

    一.旅行商问题 TSP问题即旅行商问题,经典的TSP可以描述为:一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地.应如何选择行进路线,以使总的行程最短.从图 ...

  6. Solve TSP with dynamic programming——动态规划解决旅行商(邮递员)问题

    无向简单图的TSP算法 小规模精确解: 算法思想: 小规模精确解的算法中心思想是动态规划思想. 假设给定顶点集合V为{0,1,2,3,4,... .n}.由于图为无向完全图,我们可以很自然地将0视为输 ...

  7. MATLAB实战系列(十九)-遗传算法解决TSP(旅行商)问题-应用及解析(文末附MATLAB源码)

    接上篇MATLAB实战系列(十八)-遗传算法解决TSP(旅行商)问题-算法原理 https://wenyusuran.blog.csdn.net/article/details/114060030 感 ...

  8. matlab算法大全 pdf_遗传模拟退火算法求解旅行商(TSP)问题

    hello大家好,很高兴又和大家见面了.在之前的遗传算法(GA)求解旅行商问题(TSP)MATLAB代码讲解和模拟退火(SA)算法求解旅行商 (TSP)问题MATLAB代码讲解这两篇推文中,分别讲解了 ...

  9. 遗传算法解决tsp问题(基于python)

    目录 1.遗传算法简要介绍 2.tsp问题简要介绍 3.遗传算法解决tsp问题的几个特殊点 4.源码 1.遗传算法简要介绍 简单来说,遗传算法是用于解决最优化问题的一种搜索算法.其核心基于自然界种群进 ...

最新文章

  1. 【SLAM建图和导航仿真实例】(三)- 使用RTAB-MAP进行SLAM建图和导航
  2. Spring Boot Web 开发相关总结
  3. head()函数python_Python中的Pandas DataFrame head()方法
  4. PLSQL 之类型、变量和结构
  5. 台达plc控制伺服电机编程实例_PLC控制伺服电机:控制脉冲的相关计算
  6. ClassNotFoundException: INameEnvironment
  7. c语言10000以内最大的质数,for语句计算输出10000以内最大素数怎么搞最简单??各位大神们...
  8. k8s token 过期了怎么加入worker 节点
  9. emmet工具使用和技巧
  10. C#俄罗斯方块代码完整版带部分注释
  11. android 9.0 安装xpose框架
  12. 计算机检索中常用的截断方式,文献检索方法与检索策略制定
  13. 根据MAC地质反查IP工具-LanHelper
  14. 【干货】在拉斯维加斯,程序员如何靠bandits算法干掉老虎机
  15. 2013年第三季度总结报告
  16. editor.md中markdown编辑器的实现
  17. C prime plus 第六版 课后编程练习 第4章
  18. Android P 如何挂载system镜像到根目录
  19. HyperMesh 2D网格划分
  20. nyoj541 最强DE 战斗力 (大数问题)

热门文章

  1. 【论文笔记】Feature Pyramid Networks for Object Detection
  2. C语言编辑个人信息,C语言实现的个人信息管理系统
  3. 怎么玩闲鱼月入过万?【副业干货】
  4. Win10 1903 运行安卓模拟器蓝屏解决方案
  5. Photoshop CC 2017 安装与激活(Mac 版)(仅供学习研究,勿作商业用途)
  6. 帝国CMS简单的列表或公共模板自定义文字导航高亮显示当前栏目名称教程
  7. 10. java之多态
  8. POJ 2718 贪心
  9. python list 转数组assay
  10. 建筑概论丨三、民用建筑构造