遗传算法解决TSP问题举例

一、算法实现步骤

1、初始化

初始化数据:读入数据源,将坐标转换为距离矩阵(标准化欧式距离)
初始化对象:种群规模m、运行代数n、变异概率
初始化种群:生成m条路径(编码方式:符号编码)
说明:种群初始化的编码方式有多种,常见的有二进制编码、格雷码编码、实数编码和符号编码。编码方式具有启发性,缺乏理论基础来判断各种编码的好坏,常根据实际问题和经验来确定,本算法采用符号编码。

2、计算种群适应度

适应度函数f=1/〖distance(x)〗^15
说明:适应度函数会影响选择压,选择压过大,会造成几个较好的可行解迅速占满整个群体,选择压过小,会让算法变成纯粹的随机行为。本算法对适应度函数进行15次方的尺度变换,就是为了避免选择压太小,轮盘赌的选择失去意义变成等概率随机选择

3、计算累计概率

计算每个个体适应度占适应度总和的比例并计算累计概率

4、迭代

1、选择算子:运用轮盘赌选择法,与传统轮盘赌选择法不同的是,本算法不选择重复个体充当父母,即如果选择出来的个体已经被选过一次,下一次再选到它就直接抛弃。这样最后选出来的个体数量m1<=m。

2、交叉算子:从轮盘赌选择出来的父母中随机选择两个不同个体充当父母,随机产生两个变异位置,交换两个交叉点之间基因形成两个新的子代放入种群中,直到种群数量恢复到初始种群数目m

3、变异运算:对种群中的每一个个体来说,产生一个随机数,若该随机数小于变异概率即产生变异。变异的方法是在染色体上产生两个变异点,将变异点间的基因片段倒序即完成变异。

4、更新最优解。

5、将新种群复制到旧种群中,准备下一代进化(迭代)

5、实验数据

第一列为地点名称,第二,三列为地点的经纬度

地点名称
ps:程序具有泛化性,将这两个文件里的内容修改即可得到不同地方的旅游路径规划

6、初始设定

先根据经验值(种群大小:20 ~ 100,迭代次数:500,变异概率:0.0001~0.1)对初始化参数进行设定取种群大小100,迭代次数500,变异概率0.1,选择51个城市,设置方案数量为1,运行20次

7、调参

调整参数,观察实验结果随参数的变化,通过反复尝试获得51个城市路径近似最优解

根据实验规划得到的最优路径为475.1153
具体实验情况如下图所示:
运行程序,点击需要旅游的城市和需要输出的方案数量,这里选择了51个城市,输出一个方案,程序最后运行完会给出一条路径规划路线。

8、程序的交互性

用户还可以根据自己想法选择旅游城市
下面列举2种选择方案
第一种:

第二种

可以看出,当选择城市数量不是很多时,可以找到最优解

二、代码

%GA.py
%遗传算法求解最短路径部分
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import math
import randommatplotlib.rcParams['font.family'] = 'STSong'   #字体为华文宋体# 载入数据
site_name = []
site_coordinate = []
with open('11.txt', 'r') as f:lines = f.readlines()for line in lines:line = line.split('\n')[0]line = line.split(' ')site_name.append(line[0])site_coordinate.append([float(line[2]), float(line[1])])
site_coordinate = np.array(site_coordinate)# 两两地点之间的距离矩阵
site_count = len(site_name)
Distance = np.zeros([site_count, site_count])
for i in range(site_count):for j in range(site_count):Distance[i][j] = math.sqrt((site_coordinate[i][0] - site_coordinate[j][0]) ** 2 + (site_coordinate[i][1] - site_coordinate[j][1]) ** 2)# 种群数
count = 200
# 进化次数
itter_time = 600
# 变异率
mutation_rate = 0.1#51个地点与数字对应的字典   地点1:0 .......
site_index_dict = {}
i = 0
for site in site_name:site_index_dict[site] = ii += 1#51个数字与地点对应的字典   0:地点1
index_site_dict = {}
i = 0
for site in site_name:index_site_dict[i] = site i += 1# 获得起点
def get_origin(select_site):global site_index_dictorigin = site_index_dict[select_site[0]]  #将选择的地点中的第一个设为起点地点select_site_index = []for site in select_site:select_site_index.append(site_index_dict[site]) #将选择的地点转换为地点对应的序号select_site_index.remove(origin)return origin,select_site_index# 一个个体的总距离
def get_total_distance(x,origin):distance = 0distance += Distance[origin][x[0]]for i in range(len(x)):if i == len(x) - 1:distance += Distance[origin][x[i]]      breakelse:distance += Distance[x[i]][x[i + 1]]return distance# 初始化种群
def generate_population(select_site_index):population = []for i in range(count):# 随机生成个体x = select_site_index.copy()random.shuffle(x)   #随机排序population.append(x)return population# 自然选择    轮盘赌算法
def selection(population,origin): graded = [[get_total_distance(x,origin), x] for x in population]   #计算适应度fit_value = []#存储每个个体的适应度for i in range(len(graded)):fit_value.append( 1/graded[i][0]**15)# 适应度总和total_fit = 0for i in range(len(fit_value)):total_fit += fit_value[i]#计算每个适应度占适应度总和的比例newfit_value = []  #储存每个个体轮盘选择的概率for i in range(len(fit_value)):newfit_value.append(fit_value[i] / total_fit)# 计算累计概率t = 0for i in range(len(newfit_value)):t = t + newfit_value[i]newfit_value[i] = t#生成随机数序列用于选择和比较ms = []#随机数序列for i in range(len(population)):ms.append(random.random())ms.sort()#轮盘赌选择法i = 0j = 0parents = []while i < len(population):#选择--累积概率大于随机概率if(ms[i] < newfit_value[j]):if population[j] not in parents:parents.append(population[j])i = i + 1#不选择--累积概率小于随机概率else:j = j + 1return parents# 交叉繁殖
def crossover(parents):# 生成子代的个数,以此保证种群稳定child_count = count - len(parents)# 孩子列表children = []while len(children) < child_count:#随机选择父母mother_index = random.randint(0, len(parents) - 1)father_index = random.randint(0, len(parents) - 1)if mother_index != father_index:mother = parents[mother_index]father = parents[father_index]#随机选择交叉点left = random.randint(0, len(mother) - 2)right = random.randint(left + 1, len(mother) - 1)# 交叉片段gene1 = mother[left:right]gene2 = father[left:right]child1_c = mother[right:] + mother[:right]child2_c = father[right:] + father[:right]child1 = child1_c.copy()child2 = child2_c.copy()for o in gene2:child1_c.remove(o)for o in gene1:child2_c.remove(o)child1[left:right] = gene2child2[left:right] = gene1child1[right:] = child1_c[0:len(child1) - right]child1[:left] = child1_c[len(child1) - right:]child2[right:] = child2_c[0:len(child1) - right]child2[:left] = child2_c[len(child1) - right:]children.append(child1)children.append(child2)return children# 变异    基因次序片段交换
def mutation(children):for i in range(len(children)):if random.random() < mutation_rate:child = children[i]u = random.randint(0,len(child) - 2)v = random.randint(u+1,len(child) - 1)child_x = child[u+1:v]child_x.reverse()           child = child[0:u+1] + child_x + child[v:]# 得到最佳纯输出结果
def get_result(population,origin):graded = [[get_total_distance(x,origin), x] for x in population]graded = sorted(graded)return graded#画图
def draw(origin,result_path,distance):global site_coordinateglobal site_name#34个地点散点图plt.scatter(site_coordinate[:,0],site_coordinate[:,1])site_name1 = []      with open('22.txt', 'r') as f:lines = f.readlines()for line in lines:site_name1.append(line)for i in range(51):plt.text(site_coordinate[i,0],site_coordinate[i,1],site_name1[i],fontsize="8")X = []Y = []X.append(site_coordinate[origin, 0])Y.append(site_coordinate[origin, 1])i = 0   for index in result_path:X.append(site_coordinate[index, 0])Y.append(site_coordinate[index, 1])plt.plot(X,Y,'-')plt.text((X[0]+X[1])/2,(Y[0]+Y[1])/2,i,fontsize='small')plt.title("distance = "+str(distance))del(X[0])del(Y[0])i += 1X.append(site_coordinate[origin, 0])Y.append(site_coordinate[origin, 1])plt.text((X[0]+X[1])/2,(Y[0]+Y[1])/2,i,fontdict={"size":12})     #给这个线段表上序号plt.plot(X,Y,'-')#起点特别标注
plt.scatter(site_coordinate[origin,0],site_coordinate[origin,1],s=150)

三、总结

1.种群规模过小,容易出现早熟现象,规模过大耗时又比较长,所以在选取种群规模大小时应该选择结果差不多的最小种群大小;

2.随着种群规模的增大和变异率的增加,必须增大迭代次数才能保证收敛;

3.在一定范围内变异率越高越有利于找到最优解,但如果变异率太高高阶模式被破坏的概率也随之增大;

4.收敛时间、进化代数、全局优化概率这三个性能指标是难以同时达到最优,所以在解决问题时需要确定以哪一个为主要评价指标。

————————————————
资料来源:CSDN博主「鸡丝米线」的原创文章
原文链接:https://blog.csdn.net/qq_43659401/article/details/117337861

遗传算法TSP问题举例相关推荐

  1. 计算智能——遗传算法解决TSP问题实验

    遗传算法解决TSP问题 定义 遗传算法 TSP问题 算法流程 参数说明 代码 主程序 main.m 染色体的路程代价函数 mylength.m 适应度函数 fit.m 交叉操作函数 cross.m 变 ...

  2. Matlab遗传算法与TSP问题的结合

    Matlab遗传算法与TSP问题的结合 目录 Matlab遗传算法与TSP问题的结合 准备 遗传算法+TSP问题 TSP问题 邻接矩阵 遗传算法 种群初始化和计算初始种群适应度 计算适应度 个体选择 ...

  3. 【计算智能】关于遗传算法解决TSP城市问题的初步学习

    文章目录 概述 遗传算法 TSP问题描述 参数测试 种群规模 唯一参数改变,其余参数不变 结论 城市个数 唯一参数改变,其余参数不变 结论 交叉概率 唯一参数改变,其余参数不变 结论 变异概率 唯一参 ...

  4. 模拟退火算法解决TSP(python实现 110+行代码)【gif生成】

    简述 代码我是基于我之前写的两篇,一篇是遗传算法TSP的Python实现,一篇是模拟退火算法的解决TSP的C++实现. 模拟退火算法理论+Python解决函数极值+C++实现解决TSP问题 遗传算法解 ...

  5. 遗传算法经典实例代码_经典算法研究系列 之 深入浅出遗传算法

    关注数学,关注AI,关注我们公众号ID:Math-AI 经典算法研究系列 遗传算法 1 初探遗传算法 Ok,先看维基百科对遗传算法所给的解释: 遗传算法是计算数学中用于解决最优化的搜索算法,是进化算法 ...

  6. 经典算法研究系列:七、深入浅出遗传算法,透析GA本质【转载】

    本文由July 发表在他的博客中,原文参见http://blog.csdn.net/v_JULY_v/archive/2011/01/12/6132775.aspx,对遗传算法分析的很透彻,是学习算法 ...

  7. 经典算法研究系列:七、深入浅出遗传算法

    经典算法研究系列:七.深入浅出遗传算法              作者:July    二零一一年一月十二日. 本文参考:维基百科  华南理工大学电子讲义  互联网 ----------------- ...

  8. 旅行商问题的近似最优解(局部搜索、模拟退火、遗传算法)

    旅行商问题的近似最优解(局部搜索.模拟退火.遗传算法) 关键字:旅行商问题,TSP,局部搜索,模拟退火,遗传算法 TSP问题(Traveling Salesman Problem)是一个组合优化问题. ...

  9. 一个matlab遗传算法源程序

    遗传算法实例: 也是自己找来的,原代码有少许错误,本人都已更正了,调试运行都通过了的. 对于初学者,尤其是还没有编程经验的非常有用的一个文件 遗传算法实例 % 下面举例说明遗传算法 % % 求下列函数 ...

  10. 现代优化算法(五): 蚁群算法

    组合优化算法系列: 现代优化算法 (一):模拟退火算法 及应用举例 现代优化算法 (二): 遗传算法 及应用举例 现代优化算法(三):禁忌搜索算法 现代优化算法(四):改进的遗传算法 现代优化算法(五 ...

最新文章

  1. ae中英文切换_AE技巧,AE CC软件如何切换中英文版
  2. 一分钟了解阿里云产品:对象存储OSS概述
  3. 【Python-ML】SKlearn库性能指标ROC-AUC
  4. [业界资讯]竟不知道,计世网改版了
  5. APR分析-共享内存篇
  6. SAP Spartacus 读取payment detail数据的API
  7. vue 判断两对象是否一致_你的.vue文件就已经是你的文档了
  8. 蓝桥杯第八届省赛JAVA真题----k倍区间
  9. 杀毒软件“驱逐舰”序列号、组件和病毒库升级下载地址
  10. linux平台下MongoDB安装和环境搭建及踩过的坑
  11. c语言中区别一般变量,C语言中,为了区别一般的变量,符号常量必须用
  12. 手把手教你用Spring Cloud和Docker构建微服务
  13. python多进程编程实例_[python] Python多进程编程技术实例分析
  14. redis开发与运维笔记
  15. 山寨手机给正规手机仅仅是冲突吗?相互学习,正规国产机就不愁翻身。
  16. 浙大玉泉校区-武林门民航售票处-萧山机场
  17. 2021-2027全球与中国自动卡车装卸系统市场现状及未来发展趋势
  18. 问题 F: 解救小哈
  19. 七大排序----SevenSort(希尔排序)
  20. 支付宝公众服务接口和微信公众平台接口的区别

热门文章

  1. linux禁止访问国外ip,Shell脚本实现防止国外ip访问服务器
  2. 算法——排序——归并排序图解动画
  3. Java、对字符串中的字符排序
  4. Visual Studio 打开C语言编译器
  5. 格式化日期为xxxx-xx-xx hh:mm:ss
  6. PHP开源旅游网站程序,PHP开源旅游网站源码下载
  7. python编写简单漏洞扫描器(通过实别服务版本号)
  8. Windows 下OpenGL的基本安装与配置(基于Visual Studio 2019 与 MinGW)
  9. ListView 优化
  10. WPE封包外挂教程(下)