1 遗传算法总体设计

  • Step1: 初始化参数(种群数、进化次数、变异概率,此次实验并未用到交叉概率,交叉由保留的父代随机进行);

  • Step2: 初始种群由贪婪算法求得的个体以及其他随机生成的个体构成,评价每一个个体的适配值(路径里程决定);

  • Step3: 判断算法的收敛准则是否满足(此处为迭代次数)。若满足收敛准则,则输出搜索结果,否则执行Step(4~8);

  • Step4: 执行选择操作根据个体适配值随机选择作为父代;

  • Step5: 父代两两个体随机进行交叉操作生成子代;

  • Step6: 父代变异,子代按概率变异,只有变异后的个体优于变异前的个体才接受该个体变异;

  • Step7: 更新种群个体(变异后的父代+子代)对应的适配值,更新当前最优解;

  • Step8: 返回Step3 判断是否进行下一次迭代;

==注:==以下算法需要用到的数据均和禁忌搜索算法中的处理一致,因此这里不再阐述。

2 算子设计

2.1 选择算子

将种群个体按照里程由小到大排列,排列后的种群个体的适应度:[MathProcessingError]fitness=1−位次种群规模[Math Processing Error]fitness = 1-\frac{位次}{种群规模}[MathProcessingError]fitness=1−种群规模位次​。

采用random库中的random方法,随机生成0~1·之间的数p,若p<fitness则将该个体作为父代保留。

  • 代码实现
def selection(population):'''选出父代个体'''M = population_sizeparents = []for i in range(M):if random.random() < (1 - i/M):parents.append(population[i])return parents

2.2 交叉算子

POSITION BASED CROSSOVER(PX)与CYCLE CROSSOVER(CX)的混合。

  • POSITION BASED CROSSOVER

Step1: 从parent1中随机选择N个点

Step2: 在child1中的相同位置复制这N个点,其余位置为空。

Step3:将在parent2但未在child1中的点按照在parent2中的相对顺序填充到child1中的空位中。

Step4: parent1与parent2交换角色,重复以上步骤,得出child2。

==例:==路径parent1=【1、2、3、4、5、6、7、8、9】,parent2=【5、4、6、3、1、9、2、7、8】

从parent1中随机选取4个点如【2、5、6、9】

parent1:

复制选中的点到child1:

parent2:

将在parent2但未在child1中的点【4、3、1、7、6】按照在parent2中的相对顺序填充到child1中的空位中。

  • CYCLE CROSSOVER

CX交叉方法与PX交叉方法的主要不同点就是第一步选点方式的不同,因此这里只介绍CX的选点方式,交叉方式同PX。

Step1: P1中的第一个点为起点start,P2中的第一个点为end,将start添加到cross_points中。

Step2:找寻P1中end的位置position,令P2中position对应的点为end

Step3:将end添加到cross_points中

Step4:重复step2,3直到end=start

  • 交叉算法流程图:

  • 代码实现
def CPX(parent1,parent2):'''交叉繁殖:CX与PX的混合双亲产生两个子代'''cycle = [] #交叉点集start = parent1[0]cycle.append(start)end = parent2[0]while end != start:cycle.append(end)end = parent2[parent1.index(end)]child = parent1[:]cross_points = cycle[:]if len(cross_points) < 2 :cross_points = random.sample(parent1,2)k = 0for i in range(len(parent1)):if child[i] in cross_points:continueelse:for j in range(k,len(parent2)):if parent2[j] in cross_points:continueelse:child[i] = parent2[j]k = j + 1break   return child

2.3 变异算子

采用inversion方法:随机选择两个索引为变异位点,将两个位点之间的数据倒置。

如:child = 【1、2、3、4、5、6、7、8、9】

选择变异位点为【2,5】

变异后:

算法思想:对子代的每一个个体进行概率性变异。若生成的随机数小于设定的变异率,则进行变异。若变异后的个体劣于变异前的个体,则拒绝该个体的变异,保持原状(接受法则)。

代码实现:

def mutation(children,mutation_rate):'''子代变异'''for i in range(len(children)):if random.random() < mutation_rate:child = children[i]new_child = child[:]index = sorted(random.sample(indexs,2))L = index[1] - index[0] + 1for j in range(L):new_child[index[0]+j] = child[index[1]-j]path = [origin] + child + [origin]a,b = index[0] + 1,index[1] + 1d1 = dis[path[a-1]-1][path[a]-1] + dis[path[b]-1][path[b+1]-1]d2 = dis[path[a-1]-1][path[b]-1] + dis[path[a]-1][path[b+1]-1]if d2 < d1:children[i] = new_childreturn children

此外,在程序中父代将进行整体变异(mutation_rate=1),变异仍然遵守接受法则。

2.4 将种群的个体按照里程排序,并返回当前种群中的最优个体及其里程

def get_best_current(population):'''将种群的个体按照里程排序,并返回当前种群中的最优个体及其里程'''graded = [[route_mile_cost(x),x] for x in population]graded = sorted(graded)population = [x[1] for x in graded]return graded[0][0],graded[0][1],population

2.5 设置种群数,变异概率及其进化次数

population_size = 100 #种群数
mutation_rate = 0.2 #变异概率
iter_count = 1000 #进化次数

2.6 主函数

  • 流程图

  • 代码实现
def main(iter_count):#初始化种群population = [greedy_initial_route(remain_cities)]# population = []for i in range(population_size-1):#随机生成个体individual  = remain_cities[:]random.shuffle(individual)population.append(individual)mile_cost,result,population = get_best_current(population)record = [mile_cost] #记录每一次繁殖的最优值i = 0while i < iter_count:#选择繁殖个体群parents = selection(population)#交叉繁殖target_count = population_size - len(parents) #需要繁殖的数量(保持种群的规模)children = []while len(children) < target_count:parent1,parent2 = random.sample(parents,2)child1 = CPX(parent1,parent2)child2 = CPX(parent2,parent1)children.append(child1)children.append(child2)#父代变异parents = mutation(parents,1)#子代变异children = mutation(children,mutation_rate)#更新种群population = parents + children#更新繁殖结果mile_cost,result,population = get_best_current(population) record.append(mile_cost) #记录每次繁殖后的最优解i += 1route = [origin] + result + [origin]return route,mile_cost,record
  • 绘制进化过程图
def fig():time_start = time.time()N = 1000 #进化次数satisfactory_solution,mile_cost,record = main(N)time_end = time.time()time_cost = time_end - time_startprint('time cost:',time_cost)print("优化里程成本:%d" %(int(mile_cost)))print("优化路径:\n",satisfactory_solution)#绘制路线图X = []Y = []for i in satisfactory_solution:x = city_location[i-1][0]y = city_location[i-1][1]X.append(x)Y.append(y)plt.plot(X,Y,'-o')plt.title("satisfactory solution of TS:%d"%(int(mile_cost)))plt.show()#绘制迭代过程图A = [i for i in range(N+1)]#横坐标B = record[:] #纵坐标plt.xlim(0,N)plt.xlabel('进化次数',fontproperties="SimSun")plt.ylabel('路径里程',fontproperties="SimSun")plt.title("solution of GA changed with evolution")plt.plot(A,B,'-')plt.show()

3 实验结果

对berlin52,在不同的种群数和进化次数下每组做10次重复实验,得出组内平均gap值以及程序平均运行时间如下:

平均gap值 程序平均运行时间

结果分析:在进化次数相同的情况下,随着种群数的增加,GA的最终结果往往更趋近于最优解。种群数相同的情况下,进化次数的增加并不一定能够改善GA结果。这意味着在进化后期,算法陷入了局部最优。当然,无论种群数的增加还是进化次数的增加都会导致程序运行时间的增加。

以ch150为例,以下结果为GA运算中得出的ch150算例最好的满意解gap值为1.52%

GA搜索路径结果 GA进化过程

结果分析:GA算法中目标函数值(路径里程)刚开始下降得非常迅速,后期趋于平稳下降,随着进化次数的增加,目标函数值逐渐降低。而GA进化过程图呈现阶梯状的形式,表明在一定的进化代数内,程序陷入了局部最优。GA算法的效果与选择算子,交叉算子和变异算子密切相关,我曾尝试交叉算子采用OX,但是进化效果却远远不如本次实验最终采用的CPX。此外算法的效果还受到种群数和进化次数的影响。

遗传算法求解TSP问题python实现相关推荐

  1. 基于遗传算法求解TSP问题(旅游路径规划,Python实现,超详细,可视化,结果分析)

    ps:作者是很用心写的,如果觉得不错,请给作者一点鼓励噢!(点赞收藏评论噢) 基于遗传算法求解TSP问题 摘要 巡回旅行商问题(TSP)是组合优化中的经典问题.常见的TSP问题求解算法例如穷举法.贪心 ...

  2. 人工智能导论——遗传算法求解TSP问题实验

    一.实验目的: 熟悉和掌握遗传算法的原理.流程和编码策略,并利用遗传算法求解组合优化问题,理解求解TSP问题的流程并测试主要参数对结果的影响. 二.实验原理: 旅行商问题,即TSP问题(Traveli ...

  3. 局部搜索、模拟退火和遗传算法求解TSP问题

    模拟退火和遗传算法求解TSP问题 源代码传送门:GITHUB 数据传送门:TSPLIB 文章目录 模拟退火和遗传算法求解TSP问题 摘要 1 导言 1.1 问题重述 1.2 TSP问题选择 1.3 思 ...

  4. 【建模算法】基于遗传算法求解TSP问题(matlab求解)

    [建模算法]基于遗传算法求解TSP问题(matlab求解) TSP (traveling salesman problem,旅行商问题)是典型的NP完全问题,即其最坏情况下的时间复杂度随着问题规模的增 ...

  5. 【老生谈算法】matlab实现遗传算法求解TSP问题——TSP问题

    遗传算法求解TSP问题MATLAB实现 1.文档下载: 本算法已经整理成文档如下,有需要的朋友可以点击进行下载 序号 文档(点击下载) 本项目文档 [老生谈算法]遗传算法求解TSP问题MATLAB实现 ...

  6. 【运筹优化】GA遗传算法求解TSP问题(Java实现)

    文章目录 代码 Genome基因类 GeneticAlgorithm_TSP遗传算法类 运行结果 代码 Genome基因类 import lombok.Data; import lombok.NoAr ...

  7. 【Matlab】 遗传算法求解TSP问题

    [Matlab] 遗传算法求解TSP问题 文章目录 [Matlab] 遗传算法求解TSP问题 前言 一.问题描述 二.实验设计 1.问题案例 2.读入数据 3.适应度计算 4. 选择子代 5. 结果输 ...

  8. 基于遗传算法求解TSP问题(JAVA)

    一.TSP问题 TSP问题(Travelling Salesman Problem)即旅行商问题,又译为旅行推销员问题.货郎担问题,是数学领域中著名问题之一.假设有一个旅行商人要拜访n个城市,他必须选 ...

  9. 遗传算法求解TSP问题(python版)

    简介 改进和实现遗传算法,用以对旅行商问题(TSP问题)进行建模和近似求解,从而深入对启发式算法的理解. 算法流程 遗传算法解决TSP的流程是以下几部分:初始化种群.计算适应度函数.选择.交叉.变异然 ...

  10. 【人工智能导论】遗传算法求解TSP问题(含源码github)

    源程序:Github链接 Symmetric traveling salesman problem (TSP) Given a set of n nodes and distances for eac ...

最新文章

  1. 链表问题3——删除链表的a/b处的节点(进阶)
  2. R语言ggplot2可视化将X轴置于ggplot2图表顶部实战
  3. Linux C编程--线程操作1--线程概述和简单的线程操作
  4. 监控利器之 Prometheus
  5. 查看电脑python虚拟环境-手把手教你在Linux系统下使用Python虚拟环境
  6. 【1024程序员节】都有什么?现场亲历者告诉你...
  7. Day 27: Restify —— 在Node.js中构建正确的REST Web服务
  8. python监控web扩张时间脚本
  9. iOS开发之如何跳到系统设置里的各种设置界面
  10. 数据类型转换_注意事项
  11. playframework 打包在tomcat里部署
  12. 文字方向不见了_数字化工厂是工厂变革的方向
  13. Ajax动态滚动加载数据
  14. maven-将依赖的 jar包一起打包到项目 jar 包中
  15. 给兆芯出主意:开发一批新指令,交叉授权
  16. EasyPR转qt5-vs2013
  17. c语言电脑写程序的软件,c语言编程软件下载电脑版
  18. matlab 谐波生成模块,simulink 谐波分析_matlab谐波分析_simulink中sign模块
  19. Excel表格合并单元格丢失边框
  20. 火狐浏览器设置深色主题

热门文章

  1. linux配置串口驱动程序,[Linux 驱动] -- Linux 驱动之串口(UART)
  2. 多元统计分析最短距离法_多元统计分析方法 -
  3. python训练神经网络模型_bp神经网络python 训练
  4. 微型计算机原理及应用课程复习与考研指导,微机原理及应用课程复习.doc
  5. 新萝卜家园 Ghost XP SP3 电脑城装机专用版 10.5
  6. 北京市昌平区卫星地图离线包下载
  7. 大智慧专业财务数据服务器文件,大智慧财务数据指标公式
  8. 江西省吉安市永丰县市政花园(市政服务大楼[厅])工程质量问题简述报告
  9. 暗黑2纯Linux服务器构建
  10. Android 视频直播 ( 从快播到直播,从高清到无码 )十年视频开发项目