遗传算法TSP问题举例
遗传算法解决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问题举例相关推荐
- 计算智能——遗传算法解决TSP问题实验
遗传算法解决TSP问题 定义 遗传算法 TSP问题 算法流程 参数说明 代码 主程序 main.m 染色体的路程代价函数 mylength.m 适应度函数 fit.m 交叉操作函数 cross.m 变 ...
- Matlab遗传算法与TSP问题的结合
Matlab遗传算法与TSP问题的结合 目录 Matlab遗传算法与TSP问题的结合 准备 遗传算法+TSP问题 TSP问题 邻接矩阵 遗传算法 种群初始化和计算初始种群适应度 计算适应度 个体选择 ...
- 【计算智能】关于遗传算法解决TSP城市问题的初步学习
文章目录 概述 遗传算法 TSP问题描述 参数测试 种群规模 唯一参数改变,其余参数不变 结论 城市个数 唯一参数改变,其余参数不变 结论 交叉概率 唯一参数改变,其余参数不变 结论 变异概率 唯一参 ...
- 模拟退火算法解决TSP(python实现 110+行代码)【gif生成】
简述 代码我是基于我之前写的两篇,一篇是遗传算法TSP的Python实现,一篇是模拟退火算法的解决TSP的C++实现. 模拟退火算法理论+Python解决函数极值+C++实现解决TSP问题 遗传算法解 ...
- 遗传算法经典实例代码_经典算法研究系列 之 深入浅出遗传算法
关注数学,关注AI,关注我们公众号ID:Math-AI 经典算法研究系列 遗传算法 1 初探遗传算法 Ok,先看维基百科对遗传算法所给的解释: 遗传算法是计算数学中用于解决最优化的搜索算法,是进化算法 ...
- 经典算法研究系列:七、深入浅出遗传算法,透析GA本质【转载】
本文由July 发表在他的博客中,原文参见http://blog.csdn.net/v_JULY_v/archive/2011/01/12/6132775.aspx,对遗传算法分析的很透彻,是学习算法 ...
- 经典算法研究系列:七、深入浅出遗传算法
经典算法研究系列:七.深入浅出遗传算法 作者:July 二零一一年一月十二日. 本文参考:维基百科 华南理工大学电子讲义 互联网 ----------------- ...
- 旅行商问题的近似最优解(局部搜索、模拟退火、遗传算法)
旅行商问题的近似最优解(局部搜索.模拟退火.遗传算法) 关键字:旅行商问题,TSP,局部搜索,模拟退火,遗传算法 TSP问题(Traveling Salesman Problem)是一个组合优化问题. ...
- 一个matlab遗传算法源程序
遗传算法实例: 也是自己找来的,原代码有少许错误,本人都已更正了,调试运行都通过了的. 对于初学者,尤其是还没有编程经验的非常有用的一个文件 遗传算法实例 % 下面举例说明遗传算法 % % 求下列函数 ...
- 现代优化算法(五): 蚁群算法
组合优化算法系列: 现代优化算法 (一):模拟退火算法 及应用举例 现代优化算法 (二): 遗传算法 及应用举例 现代优化算法(三):禁忌搜索算法 现代优化算法(四):改进的遗传算法 现代优化算法(五 ...
最新文章
- ae中英文切换_AE技巧,AE CC软件如何切换中英文版
- 一分钟了解阿里云产品:对象存储OSS概述
- 【Python-ML】SKlearn库性能指标ROC-AUC
- [业界资讯]竟不知道,计世网改版了
- APR分析-共享内存篇
- SAP Spartacus 读取payment detail数据的API
- vue 判断两对象是否一致_你的.vue文件就已经是你的文档了
- 蓝桥杯第八届省赛JAVA真题----k倍区间
- 杀毒软件“驱逐舰”序列号、组件和病毒库升级下载地址
- linux平台下MongoDB安装和环境搭建及踩过的坑
- c语言中区别一般变量,C语言中,为了区别一般的变量,符号常量必须用
- 手把手教你用Spring Cloud和Docker构建微服务
- python多进程编程实例_[python] Python多进程编程技术实例分析
- redis开发与运维笔记
- 山寨手机给正规手机仅仅是冲突吗?相互学习,正规国产机就不愁翻身。
- 浙大玉泉校区-武林门民航售票处-萧山机场
- 2021-2027全球与中国自动卡车装卸系统市场现状及未来发展趋势
- 问题 F: 解救小哈
- 七大排序----SevenSort(希尔排序)
- 支付宝公众服务接口和微信公众平台接口的区别