模拟退火算法解决TSP问题.docx
- 文档编号:25240100
- 上传时间:2023-06-06
- 格式:DOCX
- 页数:19
- 大小:279.13KB
模拟退火算法解决TSP问题.docx
《模拟退火算法解决TSP问题.docx》由会员分享,可在线阅读,更多相关《模拟退火算法解决TSP问题.docx(19页珍藏版)》请在冰豆网上搜索。
模拟退火算法解决TSP问题
智能优化方法
课题报告
专业班级:
电子信息科学与技术12-3班
课题名称:
模拟退火算法解决TSP问题
指导教师:
姚睿
学生姓名:
蒋文斌
学号:
08123453
(课题设计时间:
2015年3月28日——2015年4月13日)
中国矿业大学计算机学院
一、问题描述
旅行商问题(TravelingmonituihuolesmanProblem,简称TSP)又名货郎担问题,是威廉·哈密尔顿爵士和英国数学家克克曼(T.P.Kirkman)于19世纪初提出的一个数学问题,也是著名的组合优化问题。
问题是这样描述的:
一名商人要到若干城市去推销商品,已知城市个数和各城市间的路程(或旅费),要求找到一条从城市1出发,经过所有城市且每个城市只能访问一次,最后回到城市1的路线,使总的路程(或旅费)最小。
TSP刚提出时,不少人认为这个问题很简单。
后来人们才逐步意识到这个问题只是表述简单,易于为人们所理解,而其计算复杂性却是问题的输入规模的指数函数,属于相当难解的问题。
这个问题数学描述为:
假设有n个城市,并分别编号,给定一个完全无向图G=(V,E),V={1,2,…,n},n>1。
其每一边(i,j)
E有一非负整数耗费Ci,j(即上的权记为Ci,j,i,j
V)。
并设
G的一条巡回路线是经过V中的每个顶点恰好一次的回路。
一条巡回路线的耗费是这条路线上所有边的权值之和。
TSP问题就是要找出G的最小耗费回路。
人们在考虑解决这个问题时,一般首先想到的最原始的一种方法就是:
列出每一条可供选择的路线(即对给定的城市进行排列组合),计算出每条路线的总里程,最后从中选出一条最短的路线。
假设现在给定的4个城市分别为A、B、C和D,各城市之间的耗费为己知数,如图1-1所示。
我们可以通过一个组合的状态空间图来表示所有的组合,如图1-2所示。
图1-1顶点带权图图1-2TSP问题的解空间树
1.模拟退火是什么?
首先,让我们看看模拟退火是如何工作的,以及为什么它是善于解决旅行商问题。
模拟退火(SimulatedAnnealing,简称monituihuo)是一种通用概率算法,用来在一个大的搜寻空间内找寻命题的最优解。
该算法是源于对热力学中退火过程的模拟,在某一给定初温下,通过缓慢下降温度参数,使算法能够在多项式时间内给出一个近似最优解。
退火与冶金学上的“退火”相似,而与冶金学的淬火有很大区别,前者是温度缓慢下降,后者是温度迅速下降。
我们将热力学的理论套用到统计学上,将搜寻空间内每一点想像成空气内的分子;分子的能量,就是它本身的动能;而搜寻空间内的每一点,也像空气分子一样带有“能量”,以表示该点对命题的合适程度。
算法先以搜寻空间内一个任意点作起始:
每一步先选择一个“邻居”,然后再计算从现有位置到达“邻居”的概率。
2.模拟退火的优点
先来说下爬山算法:
爬山算法是一种简单的贪心搜索算法,该算法每次从当前解的临近解空间中选择一个最优解作为当前解,直到达到一个局部最优解。
爬山算法实现很简单,其主要缺点是会陷入局部最优解,而不一定能搜索到全局最优解。
如图1-3所示:
假设C点为当前解,爬山算法搜索到A点这个局部最优解就会停止搜索,因为在A点无论向那个方向小幅度移动都不能得到更优的解。
爬山法是完完全全的贪心法,每次都鼠目寸光的选择一个当前最优解,因此只能搜索到局部的最优值。
图1-3爬山算法
模拟退火其实也是一种贪心算法,但是它的搜索过程引入了随机因素。
模拟退火算法以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解。
以图1-3为例,模拟退火算法在搜索到局部最优解A后,会以一定的概率接受到E的移动。
也许经过几次这样的不是局部最优的移动后会到达D点,于是就跳出了局部最大值A。
3.模拟退火算法描述:
若J(Y(i+1))>=J(Y(i))(即移动后得到更优解),则总是接受该移动。
若J(Y(i+1)) 这里的“一定的概率”的计算参考了金属冶炼的退火过程,这也是模拟退火算法名称的由来。 根据热力学的原理,在温度为T时,出现能量差为dE的降温的概率为P(dE),表示为: P(dE)=exp(dE/(kT)) 其中k是一个常数,exp表示自然指数,且dE<0。 这条公式说白了就是: 温度越高,出现一次能量差为dE的降温的概率就越大;温度越低,则出现降温的概率就越小。 又由于dE总是小于0(否则就不叫退火了),因此dE/kT<0,所以P(dE)的函数取值范围是(0,1)。 随着温度T的降低,P(dE)会逐渐降低。 我们将一次向较差解的移动看做一次温度跳变过程,我们以概率P(dE)来接受这样的移动。 关于爬山算法与模拟退火,有一个有趣的比喻: 爬山算法: 兔子朝着比现在高的地方跳去。 它找到了不远处的最高山峰。 但是这座山不一定是珠穆朗玛峰。 这就是爬山算法,它不能保证局部最优值就是全局最优值。 模拟退火: 兔子喝醉了。 它随机地跳了很长时间。 这期间,它可能走向高处,也可能踏入平地。 但是,它渐渐清醒了并朝最高方向跳去。 这就是模拟退火。 4.接受函数 接受函数决定选择哪一个解决方案,从而可以避免掉一些局部最优解。 首先我们检查如果相邻的解决方案是比我们目前的解决方案好,如果是,我们接受它。 否则的话,我们需要考虑的几个因素: 1)相邻的解决方案有多不好; 2)当前的温度有多高。 在高温系统下更有可能接受较糟糕的解决方案。 这里是简单的数学公式: exp((solutionEnergy–neighbourEnergy)/temperature),即上面的 P(dE)=exp(dE/(kT)) 5.模拟退火的基本思想 它可以分解为解空间、目标函数和初始解三部分。 (1)初始化: 初始温度T(充分大),初始解状态S(是算法迭代的起点),每个T值的迭代次数L (2)对k=1,……,L做第(3)至第6步: (3)产生新解S′ (4)计算增量Δt′=C(S′)-C(S),其中C(S)为评价函数 (5)若Δt′<0则接受S′作为新的当前解,否则以概率exp(-Δt′/T)接受S′作为新的当前解. (6)如果满足终止条件则输出当前解作为最优解,结束程序。 终止条件通常取为连续若干个新解都没有被接受时终止算法。 (7)T逐渐减少,且T>0,然后转第2步。 6.模拟退火算法的流程 7.算法过程描述 (1)首先,需要设置初始温度和创建一个随机的初始解。 (2)然后开始循环,直到满足停止条件。 通常系统充分冷却,或找到一个足够好的解决方案。 (3)把当前的解决方案做一些小的改变,然后选择一个新的相邻的方案。 (4)决定是否移动到相邻的解决方案。 (5)降低温度,继续循环 二、程序代码实现 1.City类,用来描述城市的基本坐标信息,以及计算两城市之间的距离。 packagemonituihuo; publicclassCity{ intx;//保存城市的X坐标 inty;//保存城市的Y坐标 Stringname;//保存城市的名称 //生成一个随机的城市 publicCity(){ this.x=(int)(Math.random()*200); this.y=(int)(Math.random()*200); this.name=null; } //初始化一个城市的坐标 publicCity(intx,inty,Stringname){ this.x=x; this.y=y; this.name=name; } //获取城市的X坐标 publicintgetX(){ returnthis.x; } //获取城市的Y坐标 publicintgetY(){ returnthis.y; } //计算两个城市之间的距离 publicdoubledistanceTo(Citycity){ intxDistance=Math.abs(getX()-city.getX()); intyDistance=Math.abs(getY()-city.getY()); doubledistance=Math.sqrt((xDistance*xDistance)+(yDistance*yDistance)); returndistance; } //重写toString方法 @Override publicStringtoString(){ returngetX()+","+getY()+""+name;; } } 2.Tour类,用来初始化旅行商路径,完成路径的解决方案。 packagemonituihuo; importjava.util.ArrayList; importjava.util.Collections; publicclassTour{ //保存城市的列表 privateArrayListtour=newArrayList //保存距离 privateintdistance=0; //生成一个空的路径 publicTour(){ for(inti=0;i tour.add(null); } } //复杂路径 publicTour(ArrayListtour){ this.tour=(ArrayList)tour.clone(); } //获取路径 publicArrayListgetTour(){ returntour; } //Createsarandomindividual publicvoidgenerateIndividual(){ for(intcityIndex=0;cityIndex setCity(cityIndex,SimulatedAnnealing.allCitys.get(cityIndex)); } //随机的打乱 Collections.shuffle(tour); } //获取一个城市 publicCitygetCity(inttourPosition){ return(City)tour.get(tourPosition); } publicvoidsetCity(inttourPosition,Citycity){ tour.set(tourPosition,city); //重新计算距离 distance=0; } //获得当前的总距离 publicintgetDistance(){ if(distance==0){ inttourDistance=0; for(intcityIndex=0;cityIndex CityfromCity=getCity(cityIndex); CitydestinationCity; if(cityIndex+1 destinationCity=getCity(cityIndex+1); } else{ destinationCity=getCity(0); } tourDistance+=fromCity.distanceTo(destinationCity); } distance=tourDistance; } returndistance; } //获得当前路径中城市的数量 publicinttourSize(){ returntour.size(); } publicStringtoString(){ StringprintString="|"; for(inti=0;i printString+=getCity(i)+"|"; } returnprintString; } } 3.SimulatedAnnealing主类,是算法的实现类,也是模拟退火算法解决TSP问题相应的测试。 packagemonituihuo; importjava.util.ArrayList; importjava.util.List; publicclassSimulatedAnnealing{ publicstaticList //计算接受的概率(依据热力学原理P(dE)=exp(dE/(kT))) publicstaticdoubleacceptanceProbability(intenergy,intnewEnergy,doubletemperature) { //如果新的解决方案较优,就接受 if(newEnergy { return1.0; } returnMath.exp((energy-newEnergy)/temperature); } publicstaticvoidmain(String[]args){ //创建所有的城市列表 init(); Tourbest=monituihuo(); System.out.println("Finalsolutiondistance: "+best.getDistance()); System.out.println("Tour: "+best); } //返回近似的最佳旅行路径 privatestaticTourmonituihuo(){ //设置初始化温度 doubletemp=10000; //设置冷却概率 doublecoolingRate=0.003; //初始化解决方案 TourcurrentSolution=newTour(); currentSolution.generateIndividual(); System.out.println("Initialsolutiondistance: "+currentSolution.getDistance()); //设置当前为最优的方案 Tourbest=newTour(currentSolution.getTour()); //循环直到系统冷却 while(temp>1){ //生成一个邻居 TournewSolution=newTour(currentSolution.getTour()); //获取随机位置 inttourPos1=(int)(newSolution.tourSize()*Math.random()); inttourPos2=(int)(newSolution.tourSize()*Math.random()); CitycitySwap1=newSolution.getCity(tourPos1); CitycitySwap2=newSolution.getCity(tourPos2); //交换两个城市 newSolution.setCity(tourPos2,citySwap1); newSolution.setCity(tourPos1,citySwap2); //获得新的解决方案的总路程 intcurrentEnergy=currentSolution.getDistance(); intneighbourEnergy=newSolution.getDistance(); //决定是否接受新的方案 if(acceptanceProbability(currentEnergy,neighbourEnergy,temp)>Math.random()){ currentSolution=newTour(newSolution.getTour()); } //更新最优方案 if(currentSolution.getDistance() best=newTour(currentSolution.getTour()); } //冷却(即更新当前系统温度) temp*=1-coolingRate; } returnbest; } //初始化20个城市,并将他们保存到allCitys。 privatestaticvoidinit(){ Citycity=newCity(60,200,"北京"); allCitys.add(city); Citycity2=newCity(180,200,"上海"); allCitys.add(city2); Citycity3=newCity(80,180,"广州"); allCitys.add(city3); Citycity4=newCity(140,180,"深圳"); allCitys.add(city4); Citycity5=newCity(20,160,"长沙"); allCitys.add(city5); Citycity6=newCity(100,160,"武汉"); allCitys.add(city6); Citycity7=newCity(200,160,"南京"); allCitys.add(city7); Citycity8=newCity(140,140,"重庆"); allCitys.add(city8); Citycity9=newCity(40,120,"西安"); allCitys.add(city9); Citycity10=newCity(100,120,"徐州"); allCitys.add(city10); Citycity11=newCity(180,100,"成都"); allCitys.add(city11); Citycity12=newCity(60,80,"天津"); allCitys.add(city12); Citycity13=newCity(120,80,"苏州"); allCitys.add(city13); Citycity14=newCity(180,60,"南昌"); allCitys.add(city14); Citycity15=newCity(20,40,"郑州"); allCitys.add(city15); Citycity16=newCity(100,40,"大连"); allCitys.add(city16); Citycity17=newCity(200,40,"海口"); allCitys.add(city17); Citycity18=newCity(20,20,"香港"); allCitys.add(city18); Citycity19=newCity(60,20,"澳门"); allCitys.add(city19); Citycity20=newCity(160,20,"台湾"); allCitys.add(city20); } } *运行结果: (一)Java运行结果 (1)Initialsolutiondistance: 2101 Finalsolutiondistance: 919 Tour: |80,180广州|100,160武汉|140,180深圳|180,200上海|200,160南京|140,140重庆|180,100成都|180,60南昌|200,40海口|160,20台湾|120,80苏州|100,120徐州|100,40大连|60,20澳门|20,20香港|20,40郑州|60,80天津|40,120西安|20,160长沙|60,200北京| (2)Initialsolutiondistance: 2178 Finalsolutiondistance: 906 Tour: |100,40大连|160,20台湾|200,40海口|180,60南昌|180,100成都|140,140重庆|200,160南京|180,200上海|140,180深圳|100,160武汉|80,180广州|60,200北京|20,160长沙|40,120西安|100,120徐州|120,80苏州|60,80天津|20,40郑州|20,20香港|60,20澳门| (2)MATLAB运行结果 (1) 优化前的路径与优化后的路径 (2) 优化前的路径与优化后的路径 (3) 优化前的路径与优化后的路径 3、体会与总结 1.在使用模拟退火算法求解TSP问题时,遇到了几个问题,这也是模拟退火算法需要注意的地方: (1)温度的设定及其变化函数; (2)在每个温度值下,进行尝试的次数的选择; (3)评估函数如何选取的问题。 这三个问题我觉得需要经过不断的实验得出一个最优值,目前我们小组的研究及实验都很有限,得出这几个结论未必全面且正确。 同时,由于我们目前还没有找到自认为比较合理的解决方案,所以还在更深一步的探讨中。 2.模拟退火算法的优缺点 (1)优点: 模拟退火算法在搜索最优解时,不但往好的方向搜索,也往坏的方向搜索,从而使得该算法可以跳出局部最优解的陷阱,搜索岛全局最优解,在模拟退火算法执行期间,随着温度控制参数的减小,该算法返回全局最优解的概率增大,返回非全局最优解的概率单调减小。 模拟退火算法与初始值无关,即算法求得的解与初始值的选取无关模,拟退火算法具有渐进收敛性,并已在理论上被证明是一种以概率为1收敛于全局最优解的全局优化算法。 而且,模拟退火算法的计算过程简单,通用
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 模拟 退火 算法 解决 TSP 问题
![提示](https://static.bdocx.com/images/bang_tan.gif)