粒子群算法解决TSP问题.docx
《粒子群算法解决TSP问题.docx》由会员分享,可在线阅读,更多相关《粒子群算法解决TSP问题.docx(15页珍藏版)》请在冰豆网上搜索。
粒子群算法解决TSP问题
河南理工大学
计算机科学与技术学院
课程设计报告
2014—2015学年第一学期
课程名称Java语言程序设计
设计题目禾U用粒子群算法解决TSP问题
姓名朱超琦
学号3613090102
专业班级计科合13
指导教师刘志中
2015年1月2日
一.课程设计内容2
(一)课程设计题目2...
(二)课程设计目的2...
(三)课程设计要求2...
二.算法相关知识2
(一)粒子群算法简介2...
(二)人工生命简介3...
(三)粒子群算法的流程图及伪代码:
4..
3.算法的JAVA实现5
四.课程设计的总结体会14
五.参考文献14
.课程设计内容
(一)课程设计题目
应用粒子群算法(ParticleSwarmOptimization)求解旅行商问题(TSP);旅行商问题:
即TSP问题(TravellingSalesmanProblem)又译为旅行推销员问题、
货郎担问题,是数学领域中著名问题之一。
假设有一个旅行商人要拜访n个
城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。
路径的选择目标是要求得的路径路程为所有路径之中的最小值
(二)课程设计目的
1.训练应用算法求解实际问题;
2训练应用Java语言实现具体问题的求解算法;
3.到达理解java语言的应用特点以及熟练应用java语言的目标。
(三)课程设计要求
1.读懂算法,理解算法计算过程中每一步操作是如何实现的;
2.设计函数优化的编码格式;
3.采用java语言编程实现算法的求解过程;
4.掌握粒子群算法的基本原理,了解在JAVA环境中实现粒子群算法的过
程。
二.算法相关知识
(一)粒子群算法简介
粒子群算法简称PSQ它的基本思想是模拟鸟群的捕食行为。
设想这样一个场景:
一群鸟在随机搜索食物。
在这个区域里只有一块食物。
所有的鸟都不知道食物在那里。
但是他们知道当前的位置离食物还有多远。
那么找到食物的最优策略是什么呢。
最简单有效的就是搜寻目前离食物最近的鸟的周围区域。
PSQ从这种模型中得到启示并用于解决优化问题。
PSQ中,每个优化问题的解都是搜索空间中的一只鸟。
我们称之为“粒子”。
所有的粒子都有一个由被优化的函数决定的适应值(fitnessvalue),每个粒子还有一个速度决定他们飞翔的方向和距离。
然后粒子们就追随当前的最优粒子在解空间中搜索。
PSO初始化为一群随机粒子(随机解)。
然后通过迭代找到最优解。
在每一次迭代中,粒子通过跟踪两个"极值"来更新自己。
第一个就是粒子本身所找到的最优解,这个解叫做个体极值pBest。
另一个极值是整个种群目前找到的最优解,这个极值是全局极值gBest。
另外也可以不用整个种群而只是用其中一部分作为粒子的邻居,那么在所有邻居中的极值就是局部极值。
粒子公式:
在找到这两个最优值时,粒子根据如下的公式来更新自己的速度和新的位置:
v[i]=w*v[i]+cl*rand()*(pbest[i]-present[i])+c2*rand()*
(gbest-present[i])
present[i]=present[i]+v[i]
其中v[i]代表第i个粒子的速度,w代表惯性权值,c1和c2表示学习参数,rand()表示在0-1之间的随机数,pbest[i]代表第i个粒子搜索到的最优值,gbest代表整个集群搜索到的最优值,present[i]代表第i个粒子的当前位置。
(二)人工生命简介
"人工生命"是来研究具有某些生命基本特征的人工系统。
两方面内容
1.研究如何利用计算技术研究生物现象
2.研究如何利用生物技术研究计算问题
我们现在关注的是第二部分的内容。
现在已经有很多源于生物现象的计算技巧•
例如,人工神经网络是简化的大脑模型。
遗传算法是模拟基因进化过程的•
社会系统。
现在我们讨论另一种生物系统-社会系统。
更确切的是,在由简单个体组成的群落与环境以及个体之间的互动行为。
也可称做"群智能"(swarmintelligenee).
这些模拟系统利用局部信息从而可能产生不可预测的群体行为例如floys和birds他们都用来模拟鱼群和鸟群的运动规律,主要用于计算机视觉和计算机辅助设计。
在计算智能(computationalintelligenee)领域有两种基于群智能的算法.蚁群
算法(antcolonyoptimization)和PSO粒子群算法(particleswarm
optimization).前者是对蚂蚁群落食物采集过程的模拟。
已经成功运用在很多离
散优化问题上。
粒子群优化算法(PSO)也是起源对简单社会系统的模拟。
最初设
想是模拟鸟群觅食的过程•但后来发现PSC是一种很好的优化工具
(三)粒子群算法的流程图及伪代码:
1.流程图:
2•伪代码:
Foreachparticle
Initializeparticle
END
Do
Foreachparticle
Calculatefitnessvalue
Ifthefitnessvalueisbetterthanthebestfitnessvalue(pBest)inhistory
setcurrentvalueasthenewpBest
End
ChoosetheparticlewiththebestfitnessvalueofalltheparticlesasthegBest
Foreachparticle
Calculateparticlevelocityaccordingequation(a)
Updateparticlepositionaccordingequation(b)
End
Whilemaximumiterationsorminimumerrorcriteriaisnotattained
3.PSO的参数设置:
从上面的例子我们可以看到应用PSO解决优化问题的过程中有两个重要的步骤:
问题解的编码和适应度函数。
PSO的一个优势就是采用实数编码,不需要像遗传算法一样是二进制编码(或者采用针对实数的遗传操作。
例如对于问题f(x)=x1A2+x2A2+x3A2求解,粒子可以直接编码为
(x1,x2,x3),而适应度函数就是f(x)o
接着我们就可以利用前面的过程去寻优•这个寻优过程是一个叠代过程,中止条件一般为设置为达到最大循环数或者最小错误PSO中并没有许多需要调节的参数,下面列出了这
些参数以及经验设置
粒子数:
一般取20-40.其实对于大部分的问题10个粒子已经足够可以取得好的结果,不过对于比较难的问题或者特定类别的问题,粒子数可以取到100或200
粒子的长度:
这是由优化问题决定,就是问题解的长度粒子的范围:
由优化问题决定,每一维可是设定不同的范围
Vmax:
最大速度,决定粒子在一个循环中最大的移动距离,通常设定为粒子的范围宽度,
例如上面的例子里,粒子(x1,x2,x3)x1属于[-10,10],那么Vmax的大小就是20学习因子:
c1和c2通常等于2.不过在文献中也有其他的取值•但是一般c1等于c2
并且范围在0和4之间。
中止条件:
最大循环数以及最小错误要求•例如,在上面的神经网络训练例子中,最小
错误可以设定为1个错误分类,最大循环设定为2000,这个中止条件由具体的问题确定全局PSO和局部PSO:
我们介绍了两种版本的粒子群优化算法:
全局版和局部版•前者
速度快不过有时会陷入局部最优•后者收敛速度慢一点不过很难陷入局部最优•在实际
应用中,可以先用全局PSO找到大致的结果,再有局部PSO进行搜索•
三•算法的JAVA实现
代码实现:
packagenoah;
publicclassSO{
privateintx;
privateinty;
publicSO(intx,inty){
this.x=x;
this.y=y;
}
publicintgetX(){
returnx;
}
publicvoidsetX(intx){
this.x=x;
publicintgetY(){returny;
}
publicvoidsetY(inty){this.y=y;
}
publicvoidprint()
{System.out.println("x:
"+this.x+"y:
"+this.y);
}}packagenoah;
importjava.io.BufferedReader;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.InputStreamReader;importjava.util.ArrayList;
importjava.util.Random;
publicclassPSO{
privateintbestNum;
privatefloatw;
privateintMAX_GEN;//迭代次数
privateintscale;//种群规模
privateintcityNum;//城市数量,编码长度
privateintt;//当前代数
privateint[][]distance;//距离矩阵
privateint[][]oPopulation;//粒子群
privateArrayList>listV;//每科粒子的初始交换序列
privateint[][]Pd;//privateint[]vPd;//privateint[]Pgd;//记住自己搜索到的最好解
privateintvPgd;//privateintbestT;//privateint[]fitness;//
一颗粒子历代中出现最好的解,
解的评价值
整个粒子群经历过的的最好的解,每个粒子都能
最好的解的评价值
最佳出现代数
种群适应度,表示种群中各个个体的适应度
privateRandomrandom;
publicPSO(){
}
publicPSO(intn,intg,ints,floatw){this.cityNum=n;this.MAX_GEN=g;this.scale=s;
this.w=w;
}
*初始化PSO算法类
*@paramfilename数据文件名,该文件存储所有城市节点坐标数据
*@throwsIOException
*/
privatevoidinit(Stringfilename)throwsIOException{
//读取数据
int[]x;
int[]y;
Stringstrbuff;
BufferedReaderdata=newBufferedReader(new
InputStreamReader(
newFileInputStream(filename)));
distance=newint[cityNum][cityNum];
x=newint[cityNum];
y=newint[cityNum];
for(inti=0;i//读取一行数据,数据格式167341453
strbuff=data.readLine();
//字符分割
String[]strcol=strbuff.split("");
x[i]=Integer.valueOf(strcol[1]);//x坐标
y[i]=Integer.valueOf(strcol[2]);//y坐标
}
//计算距离矩阵
//,针对具体问题,距离计算方法也不一样,此处用的是att48作为案例,它有48个城市,距离计算方法为伪欧氏距离,最优值为10628for(inti=0;idistance[i][i]=0;//对角线为0
for(intj=i+1;j.sqrt(((x[i]-x[j])*(x[i]-x[j])+(y[i]-
y[j])
*(y[i]-y[j]))/10.0);
//四舍五入,取整
inttij=(int)Math.round(rij);
if(tijdistance[i][j]=tij+1;
distance[j][i]=distance[i][j];
}else{distance[i][j]=tij;distance[j][i]=distance[i][j];
}
}
}distance[cityNum-1][cityNum-1]=0;
oPopulation=newint[scale][cityNum];fitness=newint[scale];
Pd=newint[scale][cityNum];
vPd=newint[scale];
Pgd=newint[cityNum];
vPgd=Integer.MAX_VALUE;
bestT=0;
t=0;
random=newRandom(System.currentTimeMillis());
}
//初始化种群,多种随机生成办法
voidinitGroup(){
inti,j,k;
for(k=0;koPopulation[k][0]=random.nextInt(65535)%cityNum;for(i=1;ioPopulation[k][i]=random.nextInt(65535)%cityNum;for(j=0;j
}
}
if(j==i){i++;
}
}
}
}
voidinitListV(){
intra;
intraA;
intraB;
listV=newArrayList>();
for(inti=0;iArrayListlist=newArrayList();ra=random.nextInt(65535)%cityNum;for(intj=0;jraA=random.nextInt(65535)%cityNum;
raB=random.nextInt(65535)%cityNum;while(raA==raB){
raB=random.nextInt(65535)%cityNum;}
//raA与raB不一样
SOs=newSO(raA,raB);list.add(s);
}
listV.add(list);
}
}
publicintevaluate(int[]chr){
//0123
intlen=0;
//编码,起始城市,城市1,城市2...城市nfor(inti=1;ilen+=distance[chr[i-1]][chr[i]];
}
//城市n,起始城市
len+=distance[chr[cityNum-1]][chr[0]];
returnlen;
}
//求一个基本交换序列作用于编码arr后的编码publicvoidadd(int[]arr,ArrayListlist){
inttemp=-1;
SOs;
for(inti=0;is=list.get(i);
temp=arr[s.getX()];
arr[s.getX()]=arr[s.getY()];
arr[s.getY()]=temp;
}
}
//求两个编码的基本交换序列,如A-B=SSpublicArrayListminus(int[]a,int[]b){
int[]temp=b.clone();
/*
*int[]temp=newint[L];for(inti=0;i*/
intindex;
//交换子
SOs;
//交换序列
ArrayListlist=newArrayList();
for(inti=0;i=temp[i]){
//在temp中找出与a[i]相同数值的下标indexindex=findNum(temp,a[i]);
//在temp中交换下标i与下标index的值changeIndex(temp,i,index);
//记住交换子s=newSO(i,index);
//保存交换子list.add(s);
}
}returnlist;
}
//在arr数组中查找num返回num的下标
publicintfindNum(int[]arr,intnum){
intindex=-1;
for(inti=0;i}
}
returnindex;
}
//将数组arr下标index1与下标index2的值交换publicvoidchangeIndex(int[]arr,intindex1,intindex2){inttemp=arr[index1];arr[index1]=arr[index2];
arr[index2]=temp;
}
//二维数组拷贝publicvoidcopyarray(int[][]from,int[][]to){for(inti=0;ifor(intj=0;j}
}
}
//一维数组拷贝
publicvoidcopyarrayNum(int[]from,int[]to){for(inti=0;ito[i]=from[i];
}
}
publicvoidevolution(){
inti,j,k;
intlen=0;
floatra=0f;
ArrayListVi;
//迭代一次
for(t=0;t//对于每颗粒子
for(i=0;iVii=newArrayList();
//System.out.println("");
//更新速度
//Vii=wVi+ra(Pid-Xid)+rb(Pgd-Xid)
Vi=listV.get(i);
//wVi+表示获取Vi中size*w取整个交换序列
len=(int)(Vi.size()*w);
//越界判断//if(len>cityNum)len=cityNum;
//System.out.println("w:
"+w+"len:
"+len+"Vi.size():
"+Vi.size());
for(j=0;jVii.add(Vi.get(j));
}
ArrayLista=minus(Pd[i],oPopulation[i]);ra=random.nextFloat();
len=(int)(a.size()*ra);
//越界判断for(j=0;jVii.add(a.get(j));
}
ArrayListb=minus(Pgd,oPopulation[i]);ra=random.nextFloat();
//ra(Pid-Xid)+
len=(int)(b.size()*ra);
//越界判断
for(j=0;jSOtt=b.get(j);
Vii.add(tt);
}
listV.add(i,Vii);
add(oPopulation[i],Vii);
}
//计算新粒子群适应度,Fitness[max],选出最好的解
for(k=0;kfitness[k]=evaluate(oPopulation[k]);
if(vPd[k]>fitness[k]){
vPd[k]=fitness[k];copyarrayNum(oPopulation[k],Pd[k]);bestNum=k;
}
if(vPgd>vPd[k]){
System.out.println("最佳长度"+vPgd+"代数:
"+bestT);
bestT=t;
vPgd=vPd[k];
copyarrayNum(Pd[k],Pgd);
}
}
}
}
publicvoidsolve(){inti;
intk;
initGroup();
initListV();
//每颗粒子记住自己最好的解copyarray(oPopulation,Pd);
//计算初始化种群适应度,