遗传算法解决TSP问题(C++)
实验六:遗传算法求解TSP问题实验2篇
实验六:遗传算法求解TSP问题实验2篇第一篇:遗传算法的原理与实现1. 引言旅行商问题(TSP问题)是一个典型的组合优化问题,它要求在给定一组城市和每对城市之间的距离后,找到一条路径,使得旅行商能够在所有城市中恰好访问一次并回到起点,并且总旅行距离最短。
遗传算法作为一种生物启发式算法,在解决TSP问题中具有一定的优势。
本实验将运用遗传算法求解TSP问题,以此来探讨和研究遗传算法在优化问题上的应用。
2. 遗传算法的基本原理遗传算法是模拟自然界生物进化过程的一种优化算法。
其基本原理可以概括为:选择、交叉和变异。
(1)选择:根据问题的目标函数,以适应度函数来评估个体的优劣程度,并按照适应度值进行选择,优秀的个体被保留下来用于下一代。
(2)交叉:从选出的个体中随机选择两个个体,进行基因的交换,以产生新的个体。
交叉算子的选择及实现方式会对算法效果产生很大的影响。
(3)变异:对新生成的个体进行基因的变异操作,以保证算法的搜索能够足够广泛、全面。
通过选择、交叉和变异操作,不断迭代生成新一代的个体,遗传算法能够逐步优化解,并最终找到问题的全局最优解。
3. 实验设计与实施(1)问题定义:给定一组城市和每对城市之间的距离数据,要求找到一条路径,访问所有城市一次并回到起点,使得旅行距离最短。
(2)数据集准备:选择适当规模的城市数据集,包括城市坐标和每对城市之间的距离,用于验证遗传算法的性能。
(3)遗传算法的实现:根据遗传算法的基本原理,设计相应的选择、交叉和变异操作,确定适应度函数的定义,以及选择和优化参数的设置。
(4)实验流程:a. 初始化种群:随机生成初始种群,每个个体表示一种解(路径)。
b. 计算适应度:根据适应度函数,计算每个个体的适应度值。
c. 选择操作:根据适应度值选择一定数量的个体,作为下一代的父代。
d. 交叉操作:对父代进行交叉操作,生成新的个体。
e. 变异操作:对新生成的个体进行变异操作,以增加搜索的多样性。
利用遗传算法求解TSP问题
利⽤遗传算法求解TSP问题⼀、摘要TSP问题是指给定平⾯上N个点及每点的坐标,求⼀条路径,遍历所有的点并回到起点,使这条路径长度最⼩。
TSP问题是⼀个组合优化问题。
该问题可以被证明具有NPC计算复杂性。
因此,任何能使该问题的求解得以简化的⽅法,都将受到⾼度的评价和关注。
遗传算法是⼈⼯智能⽅法的⼀种,⽤于求解各种传统⽅法不⽅便求解或耗时很长的问题。
下⾯给出遗传算法求解TSP问题的步骤。
在传统遗传算法求解TSP的基础上,提出了⼀种新的编码⽅式,并且讨论了⼀种优化⽅法的可⾏性。
本次实验的程序⾸先在matlab上验证了基本的算法,然⽽由于matlab运⾏较慢,故⼜移植到C++平台上,经过测试,实验结果良好。
⼆、算法实现遗传算法的实现主要包括编码、选择、交叉、编译、将个体放⼊新种群这么⼏个步骤,经过很多代的编译求解,以逼近最优解。
下⾯讨论每⼀个步骤的实现,其中编码⽅式是我在考虑了传统编码⽅式不利于计算的缺点下,重新设计的⼀种全新的编码⽅式。
编码在传统TSP问题中,编码可以直接采⽤⼆进制编码或⾃然编码的形式,⽐如直接把城市转化成(2,5,4,1,3,6)的形式,表⽰从2到5到4到1到3到6最后回到起点。
但是在求解TSP问题时,如果直接采⽤此种编码⽅式,会导致在交叉或变异时出现冲突的情况。
如(2,5,4,1,3,6)和(3,5,6,1,2,4)交换后变成了(2,5,6,1,2,6)和(3,5,4,1,3,4),显然路径出现了冲突的现象,传统的解决⽅式是通过逐步调整的⽅法来消除冲突,但是这种⽅法增加了编码的复杂度,不利于问题的求解,根据问题的特点,提出了采⽤⼀种插⼊序号的编码⽅式。
假设6个城市(1,2,3,4,5,6)现在有编码(1,1,2,2,1,3),让第n个编码表⽰n放在第⼏个空格处。
那么⽣成路径的规则是⾸先取1放在第⼀个(1),然后取2放在第⼀个空格处(2,1),然后取3放在第⼆个空格处(2,3,1),然后取4放在第⼆个空格处(2,4,3,1)然后取5放在第⼀个空格处(5,2,4,3,1)最后取6放在第3个空格处(5,2,6,4,3,1)。
利用遗传算法解决TSP问题课件
给每个城市一个固定的基因编号,例如10个城市为 0 1 2 3 4 5 6 7 8 9 ,随机地组成一个染色体(以下所有情况都以10个城市为例说明)。 约定这10个城市之间的行走路线为: 0123456789 (其余基因序列的路线同样道理)
两个城市间的距离(用r[i][j]表示)
轮盘选择
for(mem=0;mem<PopSize;mem++) sum+=population[mem].fitness; for(mem=0;mem<PopSize;mem++) //使小的选中的可能性大 x[mem]=sum-population[mem].fitness; sum=0.0; for(mem=0;mem<PopSize;mem++) sum+=x[mem]; /* Calculate relative fitness */ for(mem=0;mem<PopSize;mem++) population[mem].rfitness=x[mem]/sum;
仿真结果
仿真结果
一个完整路线的长度
例如基因序列为:0 8 2 9 7 5 6 4 1 3,存放在gene[0]~gene[9]中。 表示行旅行路线为: 0829756413 总路程为: r[gene[0]][gene[1]]+r[gene[1]][gene[2]]~ +r[gene[9]gene[0]]
交叉
例如一个基因序列为: 0 2 5 6 9 8 1 3 4 7 产生两个0~9的int型随机数,如得到2和6,将gene[2]和gene[6]之间的基因反序,得到: 0 2 1 8 9 6 5 3 4 7
(完整word版)遗传算法求解TSP问题实验报告
人工智能实验报告实验六遗传算法实验II一、实验目的:熟悉和掌握遗传算法的原理、流程和编码策略,并利用遗传求解函数优化问题,理解求解TSP问题的流程并测试主要参数对结果的影响。
二、实验原理:旅行商问题,即TSP问题(Traveling Salesman Problem)是数学领域中著名问题之一。
假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路经的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。
路径的选择目标是要求得的路径路程为所有路径之中的最小值。
TSP问题是一个组合优化问题。
该问题可以被证明具有NPC计算复杂性。
因此,任何能使该问题的求解得以简化的方法,都将受到高度的评价和关注。
遗传算法的基本思想正是基于模仿生物界遗传学的遗传过程。
它把问题的参数用基因代表,把问题的解用染色体代表(在计算机里用二进制码表示),从而得到一个由具有不同染色体的个体组成的群体。
这个群体在问题特定的环境里生存竞争,适者有最好的机会生存和产生后代。
后代随机化地继承了父代的最好特征,并也在生存环境的控制支配下继续这一过程。
群体的染色体都将逐渐适应环境,不断进化,最后收敛到一族最适应环境的类似个体,即得到问题最优的解。
要求利用遗传算法求解TSP问题的最短路径。
三、实验内容:1、参考实验系统给出的遗传算法核心代码,用遗传算法求解TSP的优化问题,分析遗传算法求解不同规模TSP问题的算法性能。
2、对于同一个TSP问题,分析种群规模、交叉概率和变异概率对算法结果的影响。
3、增加1种变异策略和1种个体选择概率分配策略,比较求解同一TSP问题时不同变异策略及不同个体选择分配策略对算法结果的影响。
4、上交源代码。
四、实验报告要求:1、画出遗传算法求解TSP问题的流程图。
2、分析遗传算法求解不同规模的TSP问题的算法性能。
规模越大,算法的性能越差,所用时间越长。
3、对于同一个TSP问题,分析种群规模、交叉概率和变异概率对算法结果的影响。
用于求解TSP问题的遗传算法改进
用于求解TSP问题的遗传算法改进遗传算法是一种常用于解决旅行商问题(TSP)的优化算法。
TSP问题是指在给定一组城市和其之间的距离,找到一条最短路径,使得每个城市只访问一次并最终返回起始城市。
传统的遗传算法在解决TSP问题时存在一些缺点,例如收敛速度慢、易于陷入局部最优解等问题。
对遗传算法进行改进以提高求解TSP问题的效果和效率尤为重要。
改进初始化的方法。
传统的遗传算法一般采用随机生成的方法来初始化种群,但这样会导致种群的多样性不足、容易陷入局部最优解。
可以采用相邻交换法、插入法等启发式方法来生成初始化种群,增加种群的多样性,有助于全局搜索。
改进交叉和变异的操作。
传统的遗传算法中,交叉和变异操作一般是均匀随机进行的,但这样可能会导致交叉和变异带来的新个体的子路径中出现重复的城市,从而违反了TSP问题的约束条件。
可以采用部分映射交叉(PMX)等方法来保证交叉后子路径不会出现重复的城市,同时保持了种群的多样性;可以采用2-opt、3-opt等局部搜索方法来修复变异带来的子路径中出现的重复的城市,提高种群的质量。
可以引入自适应权重的选择策略。
传统的遗传算法中,选择策略一般是基于个体适应度的排序或轮盘赌选择的。
但这种选择策略可能会导致选择压力过大或过小,使种群收敛速度过快或过慢。
可以采用自适应权重的选择策略,根据种群适应度的分布情况动态调整选择概率,使得适应度较高的个体能够更有机会被选中,增加种群的多样性,提高全局搜索能力。
可以引入一些启发式的局部搜索方法。
传统的遗传算法中,局部搜索往往仅在变异操作中进行,但这样可能局部搜索的范围有限,难以跳出局部最优解。
可以在种群进化的过程中,根据种群的适应度情况,选择某些个体进行局部搜索,以进一步改善个体的质量。
对于求解TSP问题的遗传算法改进,可以从初始化方法、交叉和变异操作、选择策略和局部搜索等方面进行改进,以提高算法的效果和效率。
通过引入合适的启发式方法,增加种群的多样性,改善交叉和变异的操作,优化选择策略,加强局部搜索,可以有效地提高遗传算法在求解TSP问题中的性能。
遗传算法求解TSP问题
遗传算法求解TSP问题⼀、简介遗传算法是基于达尔⽂的⽣物进化论,是⼈⼯智能算法的的重要分⽀,主要⽤于解决⼀类求最优解问题。
如旅⾏商(TSP)问题。
遗传算法是将状态当成染⾊体,状态⾥的每⼀个决策都是染⾊体上的⼀个基因。
然后根据实际情况⽣成⼀个适应度函数,计算每⼀串染⾊体对环境的适应度。
让适应度⾼的遗传到下⼀代,适应度低的淘汰掉,另外在实现的过程中也许会发⽣变异,导致⼀些决策改变。
除此之外,遗传算法是随机性近似算法,所以当我们运⽤该算法时必须采取措施使其收敛到全局最优解,并且尽量提⾼达到最优解的概率。
遗传算法除了设计适应度函数以外,还有很重要的三个部分:选择,交叉,变异。
⼆、遗传算法实现步骤1.评估每条染⾊体所对应个体的适应度。
2.遵照适应度越⾼,选择概率越⼤的原则,从种群中选择两个个体作为⽗⽅和母⽅。
3.抽取⽗母双⽅的染⾊体,进⾏交叉,产⽣⼦代。
4.对⼦代的染⾊体进⾏变异。
5.重复2,3,4步骤,直到新种群的产⽣。
三、遗传算法求解TSP实现步骤1.确定影响因素城市序列、城市个数N、种群个数M、交叉概率Pc、变异概率Pmutation等;2.初始化数据2.1初始化影响因素:城市序列、城市个数N、种群个数M、交叉概率Pc、变异概率Pmutation2.2 初始化数据:读⼊数据源,将坐标转换为距离矩阵(标准化欧式距离)3.计算种群适应度已知任意两个城市之间的距离,每个染⾊体可计算出总距离,因此可以将⼀个随机全排列的总距离的倒数作为适应度函数,即距离越短,适应度函数越好。
4.迭代选择算⼦:赌轮选择策略挑选下⼀代个体。
交叉运算:在交叉概率的控制下,对群体中的个体两两进⾏交叉。
变异运算:在变异概率的控制下,对群体中的个体两两进⾏变异,即对某⼀个体的基因进⾏随机调整。
计算新的种群适应度以及个体累积概率,并更新最优解。
将新种群复制到旧种群中,准备下⼀代进化(迭代)。
5.输出输出迭代过程中产⽣的最短路径长度以及最短路径。
遗传算法(GA)解决TSP问题
遗传算法(GA)解决TSP问题 遗传算法解决TSP问题遗传算法遗传算法的基本原理是通过作⽤于染⾊体上的基因寻找好的染⾊体来求解问题,它需要对算法所产⽣的每个染⾊体进⾏评价,并基于适应度值来选择染⾊体,使适应性好的染⾊体有更多的繁殖机会,在遗传算法中,通过随机⽅式产⽣若⼲个所求解问题的数字编码,即染⾊体,形成初始种群;通过适应度函数给每个个体⼀个数值评价,淘汰低适应度的个体,选择⾼适应度的个体参加遗传操作,经过遗产操作后的个体集合形成下⼀代新的种群,对这个新的种群进⾏下⼀轮的进化。
TSP问题TSP问题即旅⾏商问题,经典的TSP可以描述为:⼀个商品推销员要去若⼲个城市推销商品,该推销员从⼀个城市出发,需要经过所有城市后,回到出发地。
应如何选择⾏进路线,以使总的⾏程最短。
从图论的⾓度来看,该问题实质是在⼀个带权完全⽆向图中,找⼀个权值最⼩的哈密尔顿回路。
遗传算法解决TSP问题概念介绍:种群 ==> 可⾏解集个体 ==> 可⾏解染⾊体 ==> 可⾏解的编码基因 ==> 可⾏解编码的分量基因形式 ==> 遗传编码适应度 ==> 评价的函数值(适应度函数)选择 ==> 选择操作交叉 ==> 编码的交叉操作变异 ==> 可⾏解编码的变异遗传操作:就包括优选适应性强的个体的“选择”;个体间交换基因产⽣新个体的“交叉”;个体间的基因突变⽽产⽣新个体的“变异”。
其中遗传算法是运⽤遗传算⼦来进⾏遗传操作的。
即:选择算⼦、变异算⼦、交叉算⼦。
遗传算法的基本运算过程(1)种群初始化:个体编码⽅法有⼆进制编码和实数编码,在解决TSP问题过程中个体编码⽅法为实数编码。
对于TSP问题,实数编码为1-n的实数的随机排列,初始化的参数有种群个数M、染⾊体基因个数N(即城市的个数)、迭代次数C、交叉概率Pc、变异概率Pmutation。
(2)适应度函数:在TSP问题中,对于任意两个城市之间的距离D(i,j)已知,每个染⾊体(即n个城市的随机排列)可计算出总距离,因此可将⼀个随机全排列的总距离的倒数作为适应度函数,即距离越短,适应度函数越好,满⾜TSP要求。
遗传算法解决TSP问题【精品毕业设计】(完整版)
GA(Fitness,Fitness_threshold,p,r,m)
Fitness:适应度评分函数,为给定假设赋予一个评估分数
Fitness_threshold:指定终止判据的阈值
p:群体中包含的假设数量
r:每一步中通过交叉取代群体成员的比例
m:变异率
初始化群体:P←随机产生的p个假设
在本程序的TSP问题中一共有20个城市,也就是在图模型中有20个顶点,因此一个染色体的长度为20。
3.3适应函数f(i)
对具有n个顶点的图,已知各顶点之间( , )的边长度d( , ),把 到 间的一条通路的路径长度定义为适应函数:
对该最优化问题,就是要寻找解 ,使f( )值最小。
3.4选择操作
选择作为交叉的双亲,是根据前代染色体的适应函数值所确定的,质量好的个体,即从起点到终点路径长度短的个体被选中的概率较大。
(2)交叉(Crossover):对于选中进行繁殖的两个染色体X,Y,以X,Y为双亲作交叉操作,从而产生两个后代X1,Y1.
(3)变异(Mutation):对于选中的群体中的个体(染色体),随机选取某一位进行取反运算,即将该染色体码翻转。
用遗传算法求解的过程是根据待解决问题的参数集进行编码,随机产生一个种群,计算适应函数和选择率,进行选择、交叉、变异操作。如果满足收敛条件,此种群为最好个体,否则,对产生的新一代群体重新进行选择、交叉、变异操作,循环往复直到满足条件。
3.变异:使用均匀的概率从Ps中选择m%的成员.对于选出的每个成员,在它表示中随机选择一个为取反
4.更新:P←Ps
5.评估:对于P中的每个h计算Fitness(h)
从P中返回适应度最高的假设
3.
3.1 TSP问题的图论描述
遗传算法的C语言实现(二)-----以求解TSP问题为例
遗传算法的C语⾔实现(⼆)-----以求解TSP问题为例上⼀次我们使⽤遗传算法求解了⼀个较为复杂的多元⾮线性函数的极值问题,也基本了解了遗传算法的实现基本步骤。
这⼀次,我再以经典的TSP问题为例,更加深⼊地说明遗传算法中选择、交叉、变异等核⼼步骤的实现。
⽽且这⼀次解决的是离散型问题,上⼀次解决的是连续型问题,刚好形成对照。
⾸先介绍⼀下TSP问题。
TSP(traveling salesman problem,旅⾏商问题)是典型的NP完全问题,即其最坏情况下的时间复杂度随着问题规模的增⼤按指数⽅式增长,到⽬前为⽌还没有找到⼀个多项式时间的有效算法。
TSP问题可以描述为:已知n个城市之间的相互距离,某⼀旅⾏商从某⼀个城市出发,访问每个城市⼀次且仅⼀次,最后回到出发的城市,如何安排才能使其所⾛的路线最短。
换⾔之,就是寻找⼀条遍历n个城市的路径,或者说搜索⾃然⼦集X={1,2,...,n}(X的元素表⽰对n个城市的编号)的⼀个排列P(X)={V1,V2,....,Vn},使得Td=∑d(V i,V i+1)+d(V n,V1)取最⼩值,其中,d(V i,V i+1)表⽰城市V i到V i+1的距离。
TSP问题不仅仅是旅⾏商问题,其他许多NP完全问题也可以归结为TSP问题,如邮路问题,装配线上的螺母问题和产品的⽣产安排问题等等,也使得TSP问题的求解具有更加⼴泛的实际意义。
再来说针对TSP问题使⽤遗传算法的步骤。
(1)编码问题:由于这是⼀个离散型的问题,我们采⽤整数编码的⽅式,⽤1~n来表⽰n个城市,1~n的任意⼀个排列就构成了问题的⼀个解。
可以知道,对于n个城市的TSP问题,⼀共有n!种不同的路线。
(2)种群初始化:对于N个个体的种群,随机给出N个问题的解(相当于是染⾊体)作为初始种群。
这⾥具体采⽤的⽅法是:1,2,...,n作为第⼀个个体,然后2,3,..n分别与1交换位置得到n-1个解,从2开始,3,4,...,n分别与2交换位置得到n-2个解,依次类推。
遗传算法解决TSP问题,C++版(带注释)
//遗传算法解决简单TSP问题,(VC6.0)//一、定义头文件(defines.h)#ifndef DEFINES_H#define DEFINES_H///////////////////////////////// DEFINES /////////////////////////////////////// //窗口定义大小#define WINDOW_WIDTH 500#define WINDOW_HEIGHT 500//城市数量及城市在窗口显示的大小#define NUM_CITIES 20#define CITY_SIZE 5//变异概率,交叉概率及种群数量#define MUTATION_RATE 0.2#define CROSSOVER_RATE 0.75#define POP_SIZE 40//倍数#define NUM_BEST_TO_ADD 2//最小容许误差#define EPSILON 0.000001#endif//二、一些用得到的小函数(utils.h)// utils.h: interface for the Cutils class.//头文件名//////////////////////////////////////////////////////////////////////#ifndef UTILS_H#define UTILS_H#include <stdlib.h>#include <math.h>#include <sstream>#include <string>#include <iostream>using namespace std;//--------定义一些随机函数--------//----定义随机整数,随机[x,y]之间的整数---inline int RandInt(int x, int y){return rand()%(y-x+1)+x;}//--------------随机产生0到1之间的小数----------inline float RandFloat(){return rand()/(RAND_MAX + 1.0);}//-----------------随机产生0和1-------------inline bool RandBool(){if (RandInt(0,1))return true;elsereturn false;}//-----定义一些方便的小功能包括:整形转字符型,浮点型转字符型--- string itos(int arg);//converts an float to a std::stringstring ftos (float arg);//限制大小void Clamp(double &arg, double min, double max);void Clamp(int &arg, int min, int max);#endif//三、地图头文件(CmapTSP)#ifndef CMAPTSP_H#define CMAPTSP_H//如果没有定义那么就定义////////////////////////////////////////////////////类名:CmapTSP.h////描述:封装地图数据、城市坐标以及适应度计算。
遗传算法解决TSP问题
(1 3 4 | 5 2 9 | 8 6 7) (1 7 6 | 9 5 2 | 4 3 8)
通过两点交叉可得到子代染色体为 (1 3 4 | 9 5 2| 8 6 7) (1 7 6 | 5 2 9 | 4 3 8)
遗传算法解决TSP问题(二)
遗传算法解决TSP问题(二)
用交概率Pc,变异概率Pm.
(1)生成原始染色体种群
采用实数编码,以N个城市的序号作为一条可能的
路径。
例如对8个城市,可生成如下的染色体
代表一条路径,8,6,4,2,7,5,3,1.重复操作生成数目等
于n的染色体种群。
遗传算法解决TSP问题(二)
实际编程(采用48城市数据集,最优解10628)
1 .遗传变量
遗传算法解决TSP问题(三)
2.遗传方法
遗传算法解决TSP问题(三)
3 运行截图
遗传算法解决TSP问题(三)
遗传算法解决TSP问题(三)
谢谢观看
遗传算法解决TSP问题Algorithm)是模拟达尔文生物进化论的自然选择 和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜 索最优解的方法。遗传算法是从代表问题可能潜在的解集的一个种群 (population)开始的,而一个种群则由经过基因(gene)编码的一定数 目的个体(individual)组成。每个个体实际上是染色体(chromosome)带有 特征的实体。染色体作为遗传物质的主要载体,即多个基因的集合,其内部 表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现,如黑 头发的特征是由染色体中控制这一特征的某种基因组合决定的。因此,在一 开始需要实现从表现型到基因型的映射即编码工作。由于仿照基因编码的工 作很复杂,我们往往进行简化,如二进制编码,初代种群产生之后,按照适 者生存和优胜劣汰的原理,逐代(generation)演化产生出越来越好的近似 解,在每一代,根据问题域中个体的适应度(fitness)大小选择 (selection)个体,并借助于自然遗传学的遗传算子(genetic operators) 进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的 种群。这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于 环境,末代种群中的最优个体经过解码(decoding),可以作为问题近似 最优解。
遗传算法解决TSP问题
算法设计技巧与分析题目遗传算法解决TSP问题学院电子工程学院专业智能科学与技术学生姓名教师姓名摘要根据TSP 问题的特征信息并借鉴邻域搜索算法的有关思想,提出了一种基于近邻策略的TSP 问题求解算法,该算法首先依据TSP 问题的特殊性求出相应的近邻模式,再将近邻模式用于初始种群的生成,而后在进化过程中随机引入这类模式。
该算法可以大大缩短遗传进程,提高进化效率。
通过仿真实验,验证了该算法的有效性,并且随着城市数目的增加其优越性更为明显。
关键字:近邻策略;遗传算法;旅行商问题1.引言遗传算法(Genetic Algorithm ,GA )是一种借鉴生物界中自然选择和进化机制发展起来的随机、自适应全局搜索算法,由Holland 教授于1975 年提出。
Goldberg 总结了一种统一的最基本的遗传算法的形式SGA (Simple Genetic Algorithms )。
SGA 在选定了染色体编码方案后,随机生成初始群体,再通过选择、交叉、变异三种遗传算子的作用对种群不断实行优化,直至找到问题的最优解或近似最优解。
遗传算法具有很强的全局搜索能力,但是对于大型旅行商问题(TSP ),它存在收敛速度过慢的缺点。
TSP 是一个著名的NP 难的组合优化问题,对称TSP 问题可描述为:给定n 个城市和每两个城市之间的距离,求一条经过所有城市一次且仅一次的长度最短的回路。
TSP 问题的数学表述:寻找一条遍历n 个城市的最短路径,或者说搜索到自然数集X={1,2,3,…,n}(X 中元素表示对n 个城市的编号)的一个全排列π(X )={v1,v2,…,vn},使Td = (vi ,vi +1)+d (v1,vn )n −1i=1取最小值,式中的d(vi,vi+1)表示城市vi到城市vi+1的距离。
对于n 个城市的TSP,其所有的旅程路线组合数目是(n-1)! /2。
当城市数目n 增加时,可能的路径数将呈指数级增长。
遗传算法解决tsp问题算法流程
遗传算法解决tsp问题算法流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。
文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor. I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!遗传算法解决 TSP 问题的算法流程。
1. 初始化群体。
遗传算法解决TSP问题
遗传算法解决TSP问题姓名:学号:专业:问题描叙TSP问题即路径最短路径问题,从任意起点出发(或者固定起点),依次经过所有城市,一个城市只能进入和出去一次,所有城市必须经过一次,经过终点再到起点,从中寻找距离最短的通路。
通过距离矩阵可以得到城市之间的相互距离,从距离矩阵中的到距离最短路径,解决TSP问题的算法很多,如模拟退火算法,禁忌搜索算法,遗传算法等等,每个算法都有自己的优缺点,遗传算法收敛性好,计算时间少,但是得到的是次优解,得不到最有解。
算法设计遗传算法属于进化算法的一种,它通过模仿自然界的选择与遗传的机理来寻找最优解.遗传算法有三个基本算子:选择、交叉和变异。
数值方法求解这一问题的主要手段是迭代运算。
一般的迭代方法容易陷入局部极小的陷阱而出现"死循环"现象,使迭代无法进行。
遗传算法很好地克服了这个缺点,是一种全局优化算法。
生物在漫长的进化过程中,从低等生物一直发展到高等生物,可以说是一个绝妙的优化过程。
这是自然环境选择的结果。
人们研究生物进化现象,总结出进化过程包括复制、杂交、变异、竞争和选择。
一些学者从生物遗传、进化的过程得到启发,提出了遗传算法。
算法中称遗传的生物体为个体,个体对环境的适应程度用适应值(fitness)表示。
适应值取决于个体的染色体,在算法中染色体常用一串数字表示,数字串中的一位对应一个基因。
一定数量的个体组成一个群体。
对所有个体进行选择、交叉和变异等操作,生成新的群体,称为新一代遗传算法计算程序的流程可以表示如下:第一步准备工作(1)选择合适的编码方案,将变量(特征)转换为染色体(数字串,串长为m)。
通常用二进制编码。
(2)选择合适的参数,包括群体大小(个体数M )、交叉概率PC和变异概率Pm。
(3)确定适应值函数f (x)。
f(x)应为正值。
第二步形成一个初始群体(含M个个体)。
在边坡滑裂面搜索问题中,取已分析的可能滑裂面组作为初始群体。
第三步对每一染色体(串)计算其适应值fi,同时计算群体的总适应值。
遗传算法解决TSP问题
遗传算法解决旅行商(TSP)问题旅行商问题(traveling saleman problem,简称tsp):已知N个城市之间的相互距离,现有一个推销员必须遍访这n个城市,并且每个城市只能访问一次,最后又必须返回出发城市。
如何安排他对这些城市的访问次序,可使其旅行路线的总长度最短?本程序使用MATLAB软件,利用遗传算法解决TSP问题。
程序使用如下:gatsp 为主程序,cityNum为城市个数,在此程序中可以设置为30、50和70。
Inn是种群个数,gnmax是最大迭代次数,pc是交叉概率,pm是变异概率。
算法程序运行结果如下:算法程序如下(不同的function需放在不同的.m文件中):注:红色部分不属于算法内容,仅作间隔标致。
-------------------------------------------------------------------------------------------------------%主程序:%遗传算法求解tspfunction gaTSPCityNum=30;[dislist,Clist]=tsp(CityNum);inn=100; %初始种群大小gnmax=1000; %最大代数pc=0.9; %交叉概率pm=0.08; %变异概率%产生初始种群for i=1:inns(i,:)=randperm(CityNum);end[f,p]=objf(s,dislist);gn=1;while gn<gnmax+1for j=1:2:innseln=sel(s,p); %选择操作scro=cro(s,seln,pc); %交叉操作scnew(j,:)=scro(1,:);scnew(j+1,:)=scro(2,:);smnew(j,:)=mut(scnew(j,:),pm); %变异操作smnew(j+1,:)=mut(scnew(j+1,:),pm);ends=smnew; %产生了新的种群[f,p]=objf(s,dislist); %计算新种群的适应度%记录当前代最好和平均的适应度[fmax,nmax]=max(f);ymean(gn)=1000/mean(f);ymax(gn)=1000/fmax;%记录当前代的最佳个体x=s(nmax,:);drawTSP(Clist,x,ymax(gn),gn,0);gn=gn+1;%pause;endgn=gn-1;figure(2);plot(ymax,'r'); hold on;plot(ymean,'b');grid;title('搜索过程');legend('最优解','平均解');string1=['最终度',num2str(ymax(gn))];gtext(string1);End----------------------------------------------------------------- %交叉程序:function scro=cro(s,seln,pc);bn=size(s,2);pcc=pro(pc); %根据交叉概率决定是否进行交叉操作,1则是,0则否scro(1,:)=s(seln(1),:);scro(2,:)=s(seln(2),:);if pcc==1c1=round(rand*(bn-2))+1; %在[1,bn-1]范围内随机产生一个交叉位c2=round(rand*(bn-2))+1;chb1=min(c1,c2);chb2=max(c1,c2);middle=scro(1,chb1+1:chb2);scro(1,chb1+1:chb2)=scro(2,chb1+1:chb2);scro(2,chb1+1:chb2)=middle;for i=1:chb1while find(scro(1,chb1+1:chb2)==scro(1,i))zhi=find(scro(1,chb1+1:chb2)==scro(1,i));y=scro(2,chb1+zhi);scro(1,i)=y;endwhile find(scro(2,chb1+1:chb2)==scro(2,i))zhi=find(scro(2,chb1+1:chb2)==scro(2,i));y=scro(1,chb1+zhi);scro(2,i)=y;endendfor i=chb2+1:bnwhile find(scro(1,1:chb2)==scro(1,i))zhi=find(scro(1,1:chb2)==scro(1,i));y=scro(2,zhi);scro(1,i)=y;endwhile find(scro(2,1:chb2)==scro(2,i))zhi=find(scro(2,1:chb2)==scro(2,i));y=scro(1,zhi);scro(2,i)=y;endendendEnd----------------------------------------------------------------- %变异程序:function snnew=mut(snew,pm);bn=size(snew,2);snnew=snew;pmm=pro(pm); %根据变异概率决定是否进行变异操作,1则是,0则否if pmm==1c1=round(rand*(bn-2))+1; %在[1,bn-1]范围内随机产生一个变异位c2=round(rand*(bn-2))+1;chb1=min(c1,c2);chb2=max(c1,c2);x=snew(chb1+1:chb2);snnew(chb1+1:chb2)=fliplr(x);endend----------------------------------------------------------------- %适应度计算:function [f,p]=objf(s,dislist);inn=size(s,1); %读取种群大小for i=1:innf(i)=caldist(dislist,s(i,:)); %计算函数值,即适应度endf=1000./f';%计算选择概率fsum=0;for i=1:innfsum=fsum+f(i)^15;endfor i=1:innps(i)=f(i)^15/fsum;end%计算累积概率p(1)=ps(1);for i=2:innp(i)=p(i-1)+ps(i);endp=p';end----------------------------------------------------------------- %选着个体程序:function seln=sel(s,p);inn=size(p,1);%从种群中选择两个个体for i=1:2r=rand; %产生一个随机数prand=p-r;j=1;while prand(j)<0j=j+1;endseln(i)=j; %选中个体的序号endend-----------------------------------------------------------------%城市坐标:function [DLn,cityn]=tsp(n)if n==10city10=[0.4 0.4439;0.2439 0.1463;0.1707 0.2293;0.2293 0.761;0.5171 0.9414;0.8732 0.6536;0.6878 0.5219;0.8488 0.3609;0.6683 0.2536;0.6195 0.2634];%10 cities d'=2.691for i=1:10for j=1:10DL10(i,j)=((city10(i,1)-city10(j,1))^2+(city10(i,2)-city10(j,2))^ 2)^0.5;endendDLn=DL10;cityn=city10;endif n==30city30=[41 94;37 84;54 67;25 62;7 64;2 99;68 58;71 44;54 62;83 69;64 60;18 54;22 60;83 46;91 38;25 38;24 42;58 69;71 71;74 78;87 76;18 40;13 40;82 7;62 32;58 35;45 21;41 26;44 35;4 50];%30 cities d'=423.741 by D B Fogelfor i=1:30for j=1:30DL30(i,j)=((city30(i,1)-city30(j,1))^2+(city30(i,2)-city30(j,2))^ 2)^0.5;endendDLn=DL30;cityn=city30;endif n==50city50=[31 32;32 39;40 30;37 69;27 68;37 52;38 46;31 62;30 48;21 47;25 55;16 57;17 63;42 41;17 33;25 32;5 64;8 52;12 42;7 38;5 25; 10 77;45 35;42 57;32 22;27 23;56 37;52 41;49 49;58 48;57 58;39 10;46 10;59 15;51 21;48 28;52 33;58 27;61 33;62 63;20 26;5 6;13 13;21 10;30 15;36 16;62 42;6369;52 64;43 67];%50 cities d'=427.855 by D B Fogelfor i=1:50for j=1:50DL50(i,j)=((city50(i,1)-city50(j,1))^2+(city50(i,2)-city50(j,2))^ 2)^0.5;endendDLn=DL50;cityn=city50;endif n==75city75=[48 21;52 26;55 50;50 50;41 46;51 42;55 45;38 33;33 34;45 35;40 37;50 30;55 34;54 38;26 13;15 5;21 48;29 39;33 44;15 19;16 19;12 17;50 40;22 53;21 36;20 30;26 29;40 20;36 26;62 48;67 41;62 35;65 27;62 24;55 20;35 51;30 50;45 42;21 45;36 6;6 25;11 28;26 59;30 60;22 22;27 24;30 20;35 16;54 10;50 15;44 13;35 60;40 60;40 66;31 76;47 66;50 70;57 72;55 65;2 38;7 43;9 56;15 56;10 70;17 64;55 57;62 57;70 64;64 4;59 5;50 4;60 15;66 14;66 8;43 26];%75 cities d'=549.18 by D B Fogelfor i=1:75for j=1:75DL75(i,j)=((city75(i,1)-city75(j,1))^2+(city75(i,2)-city75(j,2))^ 2)^0.5;endendDLn=DL75;cityn=city75;endend----------------------------------------------------------------- %根据交叉概率决定是否进行交叉操作:function pcc=pro(pc);test(1:100)=0;l=round(100*pc);test(1:l)=1;n=round(rand*99)+1;pcc=test(n);end----------------------------------------------------------------- %计算城市距离矩阵:function F=caldist(dislist,s)distan=0;n=size(s,2);for i=1:n-1distan=distan+dislist(s(i),s(i+1));enddistan=distan+dislist(s(n),s(1));F=distan;----------------------------------------------------------------- %作图:function m=drawTSP(Clist,BSF,bsf,p,f)CityNum=size(Clist,1);for i=1:CityNum-1plot([Clist(BSF(i),1),Clist(BSF(i+1),1)],[Clist(BSF(i),2),Clist(B SF(i+1),2)],'ms-','LineWidth',2,'MarkerEdgeColor','k','MarkerFace Color','g');hold on;endplot([Clist(BSF(CityNum),1),Clist(BSF(1),1)],[Clist(BSF(CityNum), 2),Clist(BSF(1),2)],'ms-','LineWidth',2,'MarkerEdgeColor','k','Ma rkerFaceColor','g');title([num2str(CityNum),'城市TSP']);if f==0text(1.5,1.5,['第',int2str(p),' 步',' 最短距离为',num2str(bsf)]);elsetext(1,1,['最终搜索结果:最短距离 ',num2str(bsf)]);endhold off;pause(0.05)-----------------------------------------------------------------。
遗传算法解决旅行商问题(TSP)
遗传算法解决旅⾏商问题(TSP)这次的⽂章是以⼀份报告的形式贴上来,代码只是简单实现,难免有漏洞,⽐如循环输⼊的控制条件,说是要求输⼊1,只要输⼊⾮0就⾏。
希望会帮到以后的同学(*^-^*)⼀、问题描述旅⾏商问题(Traveling-Salesman Problem,TSP)。
设有n个互相可直达的城市,某推销商准备从其中的A城出发,周游各城市⼀遍,最后⼜回到A城。
要求为该旅⾏商规划⼀条最短的旅⾏路线。
⼆、⽬的为了解决旅⾏商问题,⽤了遗传算法,模拟染⾊体的遗传过程,进⾏求解。
为了直观的更有⽐较性的观察到程序的运⾏效果,我这⾥程序⾥给定了10个城市的坐标,并计算出其任意两个的欧⽒距离,10个点的位置排布见图1。
程序的理想最优距离为20.485281,即绕三⾓形⼀圈,⽽且路程起点不固定,因为只要满⾜点围着三⾓形⼀圈即为最短距离,最优解。
所以问题转换为,求图中10 个点的不重复点的闭环序列的距离最⼩值。
图 1三、原理1、内部变量介绍程序总体围绕了遗传算法的三个主要步骤:选择--复制,交叉,变异。
给定了10个种群,即10条染⾊体,每条染⾊体都是除⾸位外不重复的点组成,⾸尾相同保证路线是闭合的,所以⼀条染⾊体包含11个点。
种群由⼀个结构体group表⽰,内含城市的序列int city[11]、种群的适应度double fit、该种群适应度占总群体适应度的⽐例double p,和为了应⽤赌轮选择机制的积累概率 double jlleigailv。
程序还包括⼀个始终记录所有种群中的最优解的城市序列数组groupbest[11],记录最优解的适应度,即最⼤适应度的变量 double groupbestfit。
种群的最⼤繁衍代数设置为1000,⽤户能够输⼊繁衍代数,但必须在1000以内。
10个点的不同排列序列有10!种,即3628800中排列可能,其中各代之间可能产⽣重复,不同种群间也会出现重复,学⽣觉得1000左右应该能验证程序的性能了,就定为1000。
遗传算法求解TSP问题
遗传算法求解TSP问题1、遗传算法前⼀篇遗传算法的基本内容在之前的博客已经应⽤过了之前遗传算法解决的是函数优化问题,即求解最⼤值或最⼩值问题;此次要解决的是组合优化问题中的TSP问题,即旅⾏商问题。
这边先介绍⼀下TSP问题TSP问题(Traveling Salesman Problem),即旅⾏商问题,⼜译为旅⾏推销员问题、货郎担问题,是数学领域中著名问题之⼀。
假设有⼀个旅⾏商⼈要拜访n个城市,他必须选择所要⾛的路径,路径的限制是每个城市只能拜访⼀次,⽽且最后要回到原来出发的城市。
路径的选择⽬标是要求得的路径路程为所有路径之中的最⼩值。
简单地说,TSP问题就是要找到图中的最短哈密尔顿回路,即全局最短路径。
然后遗传算法可以模仿⽣物进化,然后可以找到⼀个近似最优解,但其不⼀定是全局最优解。
2、实验原理1)产⽣初始种群;随机⽣成N个个体作为初始群体popm,随机选择⼀个种群;2)适应度函数;个体评价计算P(t)中各个个体的适应度,遗传算法在进化搜索中基本不利⽤外部信息,仅以适应度函数为依据,利⽤种群中每个个体的适应度值来进⾏搜索。
TSP的⽬标是路径总长度为最短3)选择运算;将使适应度较⼤(优良)个体有较⼤的存在机会,⽽适应度较⼩(低劣)的个体继续存在的机会也较⼩。
简单遗传算法采⽤赌轮选择机制4)交叉运算将交叉算⼦作⽤于群体;5)变异运算将变异算⼦作⽤于群体,并通过以上运算得到下⼀代群体P(t + 1);6)终⽌条件输出解。
3、代码实现1.city.m:随机⽣成N个城市的坐标并保存2.plot_route.m:实现连点画图3.染⾊体的路程代价函数 mylength.m4.适应度函数fit.m5.交叉操作函数 cross.m6.变异函数 Mutation.m7.main函数3、结果分析调整参数并分析运⾏结果(1)对于city_25.mat⽂件中的城市序列,参数ITER=2000,m=2,Pc=0.8,Pm=0.05保持不变,调整种群个数M的值,观察其结果变化:M=50M=100M=500由运⾏结果可知当M=100时得到TSP的最短路径长度均⼩于M=50和M=500运⾏得出的最短路径长度。
遗传算法解决TSP问题(C++)
遗传算法解决TSP问题(C++版)遗传算法流程:交叉,编译,计算适应度,保存最优个体。
其中交叉过程是选择最优的两个染色体进行交叉操作,本文采用的是轮盘赌算法。
#include<iostream>#include<cstdlib>#include<ctime>using namespace std;#define population 200//种群数量#define pc 0.9//交叉的概率#define pm 0.1//变异的概率#define count 200//迭代的次数#define num 10//城市的数量int** city;//存放每个个体的访问顺序int path[10][10] = {//0, 1, 2, 3, 4, 5, 6, 7, 8, 9{ 0, 23, 93, 18, 40, 34, 13, 75, 50, 35 },//0{ 23, 0, 75, 4, 72, 74, 36, 57, 36, 22 },//1{ 93, 75, 0, 64, 21, 73, 51, 25, 74, 89 },//2{ 18, 4, 64, 0, 55, 52, 8, 10, 67, 1 }, //3{ 40, 72, 21, 55, 0, 43, 64, 6, 99, 74 }, //4{ 34, 74, 73, 52, 43, 0, 43, 66, 52, 39 },//5{ 13, 36, 51, 8, 64, 43, 0, 16, 57, 94 },//6{ 75, 57, 25, 10, 6, 66, 16, 0, 23, 11 }, //7{ 50, 36, 74, 67, 99, 52, 57, 23, 0, 42 },//8{ 35, 22, 89, 1, 74, 39, 94, 11, 42, 0 }//9};int* dis;//存放每个个体的访问顺序下的路径长度double* fitness;//存放灭个个体的适应度int min_dis = 1000000;int min_index = -1;int* min_path;//初始化种群void init(){int *a = new int[num];for (int i = 0; i<num; i++){a[i] = i;}city = new int*[population];for (int i = 0; i<population; i++){city[i] = new int[num];}for (int i = 0; i<population; i++){for (int j = num - 1; j >= 0; j--){int n = rand() % (j + 1);//产出的数是0-j,保证交换的后面的数不会再被交换swap(a[j], a[n]);//保证a里面全是0-(num-1)的数,无重复的数,只是顺序颠倒city[i][j] = a[j];}}delete[]a;dis = new int[population];fitness = new double[population];min_path = new int[num];}//计算适应度void compute(){//cout << "do compute now. " << endl;double total = 0;for (int i = 0; i<population; i++){//计算每种情况下,路径的长度dis[i] = 0;int a = city[i][0], b;for (int j = 1; j<num; j++){b = city[i][j];dis[i] += path[a][b];a = b;}dis[i] += path[b][city[i][0]];fitness[i] = 1.0 / dis[i];//以距离的倒数作为适应度函数值total += fitness[i];}}//选择适应度高的物种,采用轮盘赌算法int select(){double total = 0;for (int i = 0; i<population; i++){total += fitness[i];}double size = rand() / (double)RAND_MAX * total;//保证不产生0//cout << "size " << size << endl;double sum = 0;int i = 0;while (sum <= size&&i<population){sum += fitness[++i];}return --i;//返回被选中的个体}int getMinDis(){int result = dis[0];int index = 0;for (int i = 1; i<population; i++){if (result > dis[i]){result = dis[i];index = i;}}return index;}int getMaxDis(){int result = dis[0];int index = 0;for (int i = 1; i<population; i++){if (result < dis[i]){result = dis[i];index = i;}}return index;}void save(){int current_min_index = getMinDis();int current_max_index = getMaxDis();if (dis[current_min_index] < min_dis){min_dis = dis[current_min_index];for (int i = 0; i < num; i++){min_path[i] =city[current_min_index][i];}//cout << "current min dis is: " << min_dis << endl;}else{for (int i = 0; i<num; i++){city[current_max_index][i] = min_path[i];}dis[current_max_index] = min_dis;fitness[current_max_index] = 1.0 / min_dis;}}//最优保存算法bool isExist(int value, int* array, int len){for (int i = 0; i<len; i++){if (value == array[i])return true;}return false;}void convert(int p1, int p2, int* src, int* dst){int len = p2 - p1 + 1;int* temp = new int[len];for (int i = p1; i <= p2; i++){temp[i - p1] = src[i];}int j = (p2 + 1) % num;for (int i = 1; i <= num; i++){int index = (i + p2) % num;if (!isExist(dst[index], temp, len)){dst[j] = dst[index];j = (j + 1) % num;}}for (int i = p1; i <= p2; i++){dst[i] = src[i];}delete[]temp;}//交叉,采用次序交叉算法void cross(){//cout << "do cross now. " << endl;for (int k = 0; k<population; k += 2){int a = select();int b = select();while (a == b){b = select();//保证被选中的个体不是一样的//cout << "same " << b << endl;}//cout << "choose popuilation" << a << " " << b << endl;double p = rand() / double(RAND_MAX);//cout << "cross rate is " << p << endl;int* a1 = new int[num];int* a2 = new int[num];int* b1 = new int[num];int* b2 = new int[num];for (int i = 0; i<num; i++){a1[i] = city[a][i];a2[i] = city[b][i];b1[i] = a2[i];b2[i] = a1[i];}if (p<pc)//满足交叉条件{//选择交叉的两点,并保证p1<p2int p1 = -1;int p2 = -1;while (p1 == p2){p1 = rand() % num;p2 = rand() % num;if (p1>p2){swap(p1, p2);}}//cout << "choose pos " << p1 << " " << p2 << endl;//开始交叉convert(p1, p2, a1, b1);convert(p1, p2, a2, b2);for (int i = 0; i<num; i++){city[k][i] = b1[i];city[k + 1][i] = b2[i];}}else{for (int i = 0; i<num; i++){city[k][i] = a1[i];city[k + 1][i] = a2[i];}}delete[]a1;delete[]a2;delete[]b1;delete[]b2;}}//变异,采用对换操作进行变异void morphis(){//cout << "do morphis now. " << endl;for (int i = 0; i<population; i++){double p = rand() / double(RAND_MAX);//cout << "morphis rate is " << p << endl;if (p<pm)//执行变异{int a = -1, b = -1;while (a == b){a = rand() % num;b = rand() % num;}swap(city[i][a], city[i][b]);}}}int getdis(){//compute();int result = dis[0];int index = 0;for (int i = 1; i<population; i++){if (result > dis[i]){result = dis[i];index = i;}}return result;}//释放申请的数组的空间void dispose(){for (int i = 0; i<population; i++){delete[]city[i];}delete[]city;delete[]dis;delete[]fitness;}int main(){init();//初始化种群int i = 0;srand(time(0));compute();while (i<count){cross();//交叉morphis();//变异compute();//计算适应度save();//保存当前最优的个体//cout << "count " << i++ << endl;cout << getdis() << " ";//输出结果//cout << min_index << " ";if (++i % 10 == 0)cout << endl;}compute();cout << "min distance is: " << min_dis << endl;for (int i = 0; i<num; i++)cout << min_path[i] << " ";cout << endl;dispose();//释放空间return 0;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
遗传算法解决TSP问题(C++版)
遗传算法流程:
交叉,编译,计算适应度,保存最优个体。
其中交叉过程是选择最优的两个染色体进行交叉操作,本文采用的是轮盘赌算法。
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
#define population 200//种群数量
#define pc 0.9//交叉的概率
#define pm 0.1//变异的概率
#define count 200//迭代的次数
#define num 10//城市的数量
int** city;//存放每个个体的访问顺序
int path[10][10] = {
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9
{ 0, 23, 93, 18, 40, 34, 13, 75, 50, 35 },//0
{ 23, 0, 75, 4, 72, 74, 36, 57, 36, 22 },//1
{ 93, 75, 0, 64, 21, 73, 51, 25, 74, 89 },//2
{ 18, 4, 64, 0, 55, 52, 8, 10, 67, 1 }, //3
{ 40, 72, 21, 55, 0, 43, 64, 6, 99, 74 }, //4
{ 34, 74, 73, 52, 43, 0, 43, 66, 52, 39 },//5
{ 13, 36, 51, 8, 64, 43, 0, 16, 57, 94 },//6
{ 75, 57, 25, 10, 6, 66, 16, 0, 23, 11 }, //7
{ 50, 36, 74, 67, 99, 52, 57, 23, 0, 42 },//8
{ 35, 22, 89, 1, 74, 39, 94, 11, 42, 0 }//9
};
int* dis;//存放每个个体的访问顺序下的路径长度
double* fitness;//存放灭个个体的适应度
int min_dis = 1000000;
int min_index = -1;
int* min_path;
//初始化种群
void init()
{
int *a = new int[num];
for (int i = 0; i<num; i++)
{
a[i] = i;
}
city = new int*[population];
for (int i = 0; i<population; i++)
{
city[i] = new int[num];
}
for (int i = 0; i<population; i++)
{
for (int j = num - 1; j >= 0; j--)
{
int n = rand() % (j + 1);//产出的数是0-j,保证交换的后面的数不会再被交换
swap(a[j], a[n]);//保证a里面全是0-(num-1)的数,无重复的数,只是顺序颠倒
city[i][j] = a[j];
}
}
delete[]a;
dis = new int[population];
fitness = new double[population];
min_path = new int[num];
}
//计算适应度
void compute()
{
//cout << "do compute now. " << endl;
double total = 0;
for (int i = 0; i<population; i++)
{
//计算每种情况下,路径的长度
dis[i] = 0;
int a = city[i][0], b;
for (int j = 1; j<num; j++)
{
b = city[i][j];
dis[i] += path[a][b];
a = b;
}
dis[i] += path[b][city[i][0]];
fitness[i] = 1.0 / dis[i];//以距离的倒数作为适应度函数值
total += fitness[i];
}
}
//选择适应度高的物种,采用轮盘赌算法
int select()
{
double total = 0;
for (int i = 0; i<population; i++)
{
total += fitness[i];
}
double size = rand() / (double)RAND_MAX * total;//保证不产生0
//cout << "size " << size << endl;
double sum = 0;
int i = 0;
while (sum <= size&&i<population)
{
sum += fitness[++i];
}
return --i;//返回被选中的个体。