遗传算法和蚂蚁算法求解TSPJava版.docx
- 文档编号:12648878
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:37
- 大小:176.47KB
遗传算法和蚂蚁算法求解TSPJava版.docx
《遗传算法和蚂蚁算法求解TSPJava版.docx》由会员分享,可在线阅读,更多相关《遗传算法和蚂蚁算法求解TSPJava版.docx(37页珍藏版)》请在冰豆网上搜索。
遗传算法和蚂蚁算法求解TSPJava版
河北工业大学
《人工智能》课程实验
实验报告
题目:
使用遗传算法和蚂蚁算法解决TSP问题
专业:
软件工程
班级:
软件122班
姓名:
姚陈堃
学号:
122590
完成日期:
2015.5.19
目录
一、实验内容1
二、实验目的1
三、实验原理1
四、源代码7
五、实验结果25
六、实验分析29
一、实验内容
旅行商问题,即TSP问题(TravelingSalesmanProblem)是数学领域中著名问题之一。
假设有一个旅行商人要拜访N个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。
路径的选择目标是要求得的路径路程为所有路径之中的最小值。
本次实验要求利用遗传算法和蚂蚁算法分别对TSP问题求解,并要求求解时间和求解结果均在可接受范围内。
二、实验目的
掌握遗传算法和蚂蚁算法的基本思想,并能结合实际问题对算法进行相应调整,最终解决问题。
三、实验原理
1.遗传算法
遗传算法是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。
遗传算法是从代表问题可能潜在的解集的一个种群开始的,而一个种群则由经过基因编码的一定数目的个体组成。
每个个体实际上是染色体带有特征的实体。
染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现,如黑头发的特征是由染色体中控制这一特征的某种基因组合决定的。
因此,在一开始需要实现从表现型到基因型的映射即编码工作。
由于仿照基因编码的工作很复杂,我们往往进行简化,如二进制编码,初代种群产生之后,按照适者生存和优胜劣汰的原理,逐代演化产生出越来越好的近似解,在每一代,根据问题域中个体的适应度大小选择个体,并借助于自然遗传学的遗传算子进行组合交叉和变异,产生出代表新的解集的种群。
这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码,可以作为问题近似最优解。
下面是简单遗传算法的求解结构:
需要指出的是,适应度函数、选择、交叉和变异操作均要根据实际问题进行灵活变更,并非固定模式。
针对本次实验的TSP问题,下面给出我在遗传算法中采用的方法。
(1)适应度函数
该函数是算法的关键,通过它对这个繁衍出来的后代进行评估打分。
在TSP问题中,路径越短,分数越高,故而适应度函数可设置为
,不同的计算方法会影响算法的收敛速度,直接影响结果和性能。
(2)选择操作
利用轮盘赌的方式选出优秀的物种,进入下一代。
选择概率的计算公式为
,其中i表示种群中的任一物种;选择过程示意如下图所示。
考虑到优化算法性能,我加入了“精英保留策略”,即并非所有物种均参与赌轮,而是事先选出适应度最高的物种,复制若干进入下一代后,再让剩余的物种参与赌轮,最终形成新种群。
这样避免了因为概率原因,使得优秀物种沧海遗珠的情况发生,但这样做也容易陷入局部最优。
(3)交叉操作
物种基因的编码形式是以“城市编号”为元素的,在实现交叉操作时首先任选一个位置作为起点,交换两个物种的后半段基因。
但需考虑的是,交换后的基因可能与物种已有的基因重复,故而需要再加上冲突处理操作。
交叉操作示意如下图所示。
(4)变异操作
“变异”是跳出局部最优解的一个重要法宝。
我采用的是随机两个位置,逆转其之间的城市编号,即随机产生1和n之间的两相异整数k和m,若k 变为 ;若k>m,则交换两者数值后实行之前同样的操作。 2.蚂蚁算法 蚂蚁算法是一种用来在图中寻找优化路径的机率型算法。 它由MarcoDorigo于1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为,其示意图如下图所示。 蚂蚁算法的主要原理有以下几点: (1)蚂蚁在寻找食物源时,能在其走过的路上释放一种特殊的分泌物——信息素(随着时间的推移该物质会逐渐挥发),后来的蚂蚁选择该路径的概率与当时这条路径上该物质的强度成正比。 (2)当一定路径上通过的蚂蚁越来越多时,其留下的信息素轨迹也越来越多,后来蚂蚁选择该路径的概率也越高,从而更增加了该路径的信息素强度。 (3)强度大的信息素会吸引更多的蚂蚁,从而形成一种正反馈机制,通过这种正反馈机制,蚂蚁最终可以发现最短路径。 (4)特别地,当蚂蚁巢穴与食物源之间出现障碍物时,蚂蚁不仅可以绕过障碍物,而且通过蚁群信息素轨迹在不同路径上的变化,经过一段时间的正反馈,最终收敛到最短路径上。 蚂蚁算法的基本求解步骤如下图所示: 四、源代码 根据伪代码及流程图,采用Java语言,在eclipse平台上分别编程实现利用遗传算法和蚂蚁算法解决TSP问题的程序。 1.遗传算法 采用面向对象思想实现,分别建立了GeneticAlgorithm遗传算法类,SpeciesList种群链表类,SpeciesNode物种结点类,Constant常量类,Main主类,。 (1)GeneticAlgorithm遗传算法类 publicclassGeneticAlgorithm ( //开始遗传 SpeciesNoderun(SpeciesListlist) ( //创建初始种群 createBeginningSpecies(list); for(inti=1;i<=Constant.DEVELOP_NUM;i++) ( //选择 select(list); //交叉 crossover(list); //变异 mutate(list); } returngetBest(list); } //创建初始种群 voidcreateBeginningSpecies(SpeciesListlist) ( //100%随机 intrandomNum=(int)(Constant.SPECIES_NUM); for(inti=1;i<=randomNum;i++) ( SpeciesNodespecies=newSpeciesNode();//创建结点 species.createByRandomGenes();//初始种群基因 list.add(species);//添加物种 } } //计算每一物种被选中的概率 voidcalRate(SpeciesListlist) ( //计算总适应度 floattotalFitness=0.0f; list.speciesNum=0; SpeciesNodepoint=list.head.next;//游标 while(point! =null)//寻找表尾结点 ( point.calFitness();//计算适应度 totalFitness+=point.fitness; list.speciesNum++; point=point.next; } //计算选中概率 point=list.head.next;//游标 while(point! =null)//寻找表尾结点 ( point.rate=point.fitness/totalFitness; point=point.next; } } //选择优秀物种(轮盘赌) voidselect(SpeciesListlist) ( //计算适应度 calRate(list); //找出最大适应度物种 floattalentDis=Float.MAX_VALUE; SpeciesNodetalentSpecies=null; SpeciesNodepoint=list.head.next;//游标 while(point! =null) ( if(talentDis>point.distance) ( talentDis=point.distance; talentSpecies=point; } point=point.next; } //将最大适应度物种复制talentNum个 SpeciesListnewSpeciesList=newSpeciesList(); inttalentNum=(int)(list.speciesNum/4); for(inti=1;i<=talentNum;i++) ( //复制物种至新表 SpeciesNodenewSpecies=talentSpecies.clone(); newSpeciesList.add(newSpecies); } //轮盘赌list.speciesNum-talentNum次 introundNum=list.speciesNum-talentNum; for(inti=1;i<=roundNum;i++) ( //产生0-1的概率 floatrate=(float)Math.random(); SpeciesNodeoldPoint=list.head.next;//游标 while(oldPoint! =null&&oldPoint! =talentSpecies)//寻找表尾结点 ( if(rate<=oldPoint.rate) ( SpeciesNodenewSpecies=oldPoint.clone(); newSpeciesList.add(newSpecies); break; } else ( rate=rate-oldPoint.rate; } oldPoint=oldPoint.next; } if(oldPoint==null||oldPoint==talentSpecies) ( //复制最后一个 point=list.head;//游标 while(point.next! =null)//寻找表尾结点 point=point.next; SpeciesNodenewSpecies=point.clone(); newSpeciesList.add(newSpecies); } } list.head=newSpeciesList.head; } //交叉操作 voidcrossover(SpeciesListlist) ( //以概率pcl~pch进行 floatrate=(float)Math.random(); if(rate>Constant.pcl&&rate ( SpeciesNodepoint=list.head.next;//游标 Randomrand=newRandom(); intfind=rand.nextInt(list.speciesNum); while(point! =null&&find! =0)//寻找表尾结点 ( point=point.next; find--; } if(point.next! =null) ( intbegin=rand.nextInt(Constant.CITY_NUM); //取point和point.next进行交叉,形成新的两个染色体 for(inti=begin;i ( //找出point.genes中与point.next.genes[i]相等的位置fir //找出point.next.genes中与point.genes[i]相等的位置sec intfir,sec; for(fir=0;! point.genes[fir].equals(point.next.genes[i]);fir++); for(sec=0;! point.next.genes[sec].equals(point.genes[i]);sec++); //两个基因互换 Stringtmp; tmp=point.genes[i]; point.genes[i]=point.next.genes[i]; point.next.genes[i]=tmp; //消去互换后重复的那个基因 point.genes[fir]=point.next.genes[i]; point.next.genes[sec]=point.genes[i]; } } } } //变异操作 voidmutate(SpeciesListlist) ( //每一物种均有变异的机会,以概率pm进行 SpeciesNodepoint=list.head.next; while(point! =null) ( floatrate=(float)Math.random(); if(rate ( //寻找逆转左右端点 Randomrand=newRandom(); intleft=rand.nextInt(Constant.CITY_NUM); intright=rand.nextInt(Constant.CITY_NUM); if(left>right) ( inttmp; tmp=left; left=right; right=tmp; } //逆转left-right下标元素 while(left ( Stringtmp; tmp=point.genes[left]; point.genes[left]=point.genes[right]; point.genes[right]=tmp; left++; right--; } } point=point.next; } } //获得适应度最大的物种 SpeciesNodegetBest(SpeciesListlist) ( floatdistance=Float.MAX_VALUE; SpeciesNodebestSpecies=null; SpeciesNodepoint=list.head.next;//游标 while(point! =null)//寻找表尾结点 ( if(distance>point.distance) ( bestSpecies=point; distance=point.distance; } point=point.next; } returnbestSpecies; } } (2)SpeciesNode物种结点 publicclassSpeciesNode ( String[]genes;//基因序列 floatdistance;//路程 floatfitness;//适应度 SpeciesNodenext; floatrate; SpeciesNode() ( //初始化 this.genes=newString[Constant.CITY_NUM]; this.fitness=0.0f; this.distance=0.0f; this.next=null; rate=0.0f; } //初始物种基因(随机) voidcreateByRandomGenes() ( //初始化基因为1-CITY_NUM序列 for(inti=0;i ( genes[i]=Integer.toString(i+1); } //获取随机种子 Randomrand=newRandom(); for(intj=0;j ( intnum=j+rand.nextInt(genes.length-j); //交换 Stringtmp; tmp=genes[num]; genes[num]=genes[j]; genes[j]=tmp; } } //初始物种基因(贪婪) voidcreateByGreedyGenes() ( Randomrand=newRandom(); inti=rand.nextInt(Constant.CITY_NUM);//随机产生一个城市作为起点 genes[0]=Integer.toString(i+1); intj;//终点 intcityNum=0; do ( cityNum++; //选出单源最短城市 floatminDis=Integer.MAX_VALUE; intminCity=0; for(j=0;j ( if(j! =i) ( //判是否和已有重复 booleanrepeat=false; for(intn=0;n ( if(Integer.parseInt(genes[n])==j+1) ( repeat=true;//重了 break; } } if(repeat==false)//没重 ( //判长度 if(Constant.disMap[i][j] ( minDis=Constant.disMap[i][j]; minCity=j; } } } } //加入到染色体 genes[cityNum]=Integer.toString(minCity+1); i=minCity; }while(cityNum } //计算物种适应度 voidcalFitness() ( floattotalDis=0.0f; for(inti=0;i ( intcurCity=Integer.parseInt(this.genes[i])-1; intnextCity=Integer.parseInt(this.genes[(i+1)%Constant.CITY_NUM])-1; totalDis+=Constant.disMap[curCity][nextCity]; } this.distance=totalDis; this.fitness=1.0f/totalDis; } //深拷贝 publicSpeciesNodeclone() ( SpeciesNodespecies=newSpeciesNode(); //复制值 for(inti=0;i species.genes[i]=this.genes[i]; species.distance=this.distance; species.fitness=this.fitness; returnspecies; } //打印路径 voidprintRoute() ( System.out.print("最短路线: "); for(inti=0;i System.out.print(genes[i]+"->"); System.out.print(genes[0]+"\n"); System.out.print("最短长度: "+distance); } } (3)SpeciesList种群链表类 publicclassSpeciesList ( SpeciesNodehead;//头结点 intspeciesNum;//物种数量 SpeciesList() ( head=newSpeciesNode(); speciesNum=Constant.SPECIES_NUM; } //添加物种 voidadd(SpeciesNodespecies) ( SpeciesNodepoint=head;//游标 while(point.next! =null)//寻找表尾结点 point=point.next; point.next=species; } } (4)Constant常量类 publicclassConstant ( staticintCITY_NUM;//城市数 staticfinalintSPECIES_NUM=2000;//种群数 staticfinalintDEVELOP_NUM=100;//进化代数 staticfinalfloatpcl=0.6f,pch=0.95f;//交叉概率 staticfinalfloatpm=0.4f;//变异概率 staticfinalfloat[][]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 遗传 算法 蚂蚁 求解 TSPJava