1、粒子群算法
(1)起源
该算法最初是受到飞鸟集群活动的规律性启发,进而利用群体智能建立的一个简化模型。
(2)概念
粒子群算法,也称粒子群优化算法鸟群觅食算法(Particle Swarm Optimization),缩写为 PSO,是一种全局优化算法。鸟群在整个搜寻的过程中,通过相互传递各自的信息,让其他的鸟知道自己的位置,通过这样的协作,来判断自己找到的是不是最优解,同时也将最优解的信息传递给整个鸟群,最终,整个鸟群都能聚集在食物源周围,即找到了最优解。在PSO中,每只鸟的位置都是优化问题解空间中的一个解。我们称之为“粒子”。所有的粒子都有一个由被优化的函数决定的适应值(fitness value),每个粒子还有一个速度决定它们飞翔的方向和速率。然后,粒子们就追随当前的最优粒子在解空间中搜索。在初始化阶段,PSO生成一群随机粒子(即随机解),然后通过迭代找到最优解。在每一次迭代中,粒子通过跟踪两个"极值"来更新自己。第一个极值就是粒子本身所找到的历史最优解,这个解叫做个体极值pBest。另一个极值是整个种群找到的历史最优解,这个极值是全局极值gBest

(3)粒子公式

公式(1)的第①部分称为【记忆项】,表示上次速度大小和方向的影响;第②部分称为【自身认知项】,是从当前点指向粒子自身最好点的一个矢量,表示粒子的动作来源于自己经验的部分;第③部分称为【群体认知项】,是一个从当前点指向种群最好点的矢量,反映了粒子间的协同合作和知识共享。粒子就是通过自己的经验和同伴中最好的经验来决定下一步的运动。

以上面两个公式为基础,再来看一个公式

公式(2)和(3)被视为标准的PSO算法

注:
(1)当c_1=0时,则粒子没有了认知能力,变为只有社会模型。此时的PSO称为全局PSO算法。粒子有扩展搜索空间的能力,具有较快的收敛速度,但由于缺少局部搜索,对于复杂问题比标准PSO 更易陷入局部最优
(2)当c_2=0时,则粒子之间没有社会信息,模型变为只有认知模型。此时的PSO称为局部PSO算法。由于个体之间没有信息的交流,整个群体相当于多个粒子进行盲目的随机搜索,收敛速度慢,因而得到最优解的可能性小

(4)流程
**第一步:**初始化一群粒子(群体规模为N),包括随机位置和速度;
**第二步:**评价每个粒子的适应度;
**第三步:**对每个微粒,将其适应值与其经过的最好位置pbest作比较,如果较好,则将其作为当前的最好位置pbest;
**第四步:**对每个微粒,将其适应值与其经过的最好位置gbest作比较,如果较好,则将其作为当前的最好位置gbest;
**第五步:**根据公式(2)、(3)调整微粒速度和位置;
**第六步:**未达到结束条件则转第二步。

:终止条件根据具体问题一般选为最大迭代次数或(和)微粒群迄今为止搜索到的最优位置满足预定最小适应阈值

(5)流程图

(6)简单实例
下面用PSO算法求解函数y=-x*(x-2) 在[0,2]上最大值(最大值在x=1取到,为1)

package cn.chb;public class PSO {public int n;//粒子个数,这里为了方便演示,我们只取两个,观察其运动方向public int c1;//学习因子public int c2;//学习因子public double vmax;//粒子的最大速度public double[]x;//粒子的x坐标public double[]y;//粒子的x坐标public double[]v;//粒子的速度public double[]pbest;//粒子的历史最优解public double gbest;//群体最优解//初始化public void init() {n=2;c1=2;c2=2;vmax=0.1;x=new double[n];x[0]=0.0;x[1]=2.0;y=new double[n];caculateFitness();v=new double[n];v[0]=0.01;v[0]=0.02;pbest=new double[n];for (int i = 0; i < n; i++) {pbest[i]=y[i];if(pbest[i]>gbest) {gbest=pbest[i];}}System.out.println("算法开始,起始最优解:"+gbest);System.out.println();}//适应度计算函数,每个粒子都有它的适应度public void caculateFitness() {for (int i = 0; i < n; i++) {y[i]=-1*x[i]*(x[i]-2);}}//去两个数的最大值public double getMAX(double a,double b){return a>b?a:b;}//粒子群算法public void Pso(int max) {for (int i = 0; i < max; i++) {double w=0.4;for (int j = 0; j < n; j++) {//更新位置和速度,就是公式(2)和(3)v[j]=w*v[j]+c1*Math.random()*(pbest[j]-x[j])+c2*Math.random()*(gbest-x[j]);if(v[j]>vmax) {v[j]=vmax;//控制速度不超过最大值}x[j]+=v[j];//越界判断,范围限定在[0, 2]if(x[j]>2) {x[j]=2;}if(x[j]<0) {x[j]=0;}}caculateFitness();//更新个体极值和群体极值for (int j = 0; j < n; j++) {pbest[j]=getMAX(y[j],pbest[j]);if(pbest[j]>gbest) {gbest=pbest[j];}System.out.println("粒子n"+j+": x = "+x[j]+"  "+"v = "+v[j]);}System.out.println("第"+(i+1)+"次迭代,全局最优解 gbest = "+gbest);System.out.println();}}public static void main(String[] args) {PSO pso=new PSO();pso.init();pso.Pso(10);//为了方便演示,我们暂时迭代10次}
}

运行结果:

算法开始,起始最优解:0.0粒子n0: x = 0.008  v = 0.008
粒子n1: x = 0.0  v = -4.477087151378778
第1次迭代,全局最优解 gbest = 0.015936粒子n0: x = 0.032543190251566295  v = 0.02454319025156629
粒子n1: x = 0.0  v = -1.7808210799382407
第2次迭代,全局最优解 gbest = 0.06402732127138296粒子n0: x = 0.08231990967327549  v = 0.049776719421709185
粒子n1: x = 0.0  v = -0.6430831068179309
第3次迭代,全局最优解 gbest = 0.15786325181793476粒子n0: x = 0.1823199096732755  v = 0.1
粒子n1: x = 0.0  v = -0.18916117763913753
第4次迭代,全局最优解 gbest = 0.33139926988327967粒子n0: x = 0.28231990967327547  v = 0.1
粒子n1: x = 0.1  v = 0.1
第5次迭代,全局最优解 gbest = 0.4849352879486245粒子n0: x = 0.38231990967327545  v = 0.1
粒子n1: x = 0.2  v = 0.1
第6次迭代,全局最优解 gbest = 0.6184713060139694粒子n0: x = 0.4823199096732754  v = 0.1
粒子n1: x = 0.30000000000000004  v = 0.1
第7次迭代,全局最优解 gbest = 0.7320073240793143粒子n0: x = 0.5823199096732754  v = 0.1
粒子n1: x = 0.4  v = 0.1
第8次迭代,全局最优解 gbest = 0.8255433421446592粒子n0: x = 0.6823199096732754  v = 0.1
粒子n1: x = 0.5  v = 0.1
第9次迭代,全局最优解 gbest = 0.899079360210004粒子n0: x = 0.7823199096732754  v = 0.1
粒子n1: x = 0.6  v = 0.1
第10次迭代,全局最优解 gbest = 0.952615378275349

当迭代次数较大时,能找到最优解:

2、求解TSP
同样是求解att48实例(最优解为10628)
代码结构:

其中Data类表示定义数据、变量初始化和读取数据的类

package com.chb.Tabu;import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;public class Data {public static int cityNum=48;//城市数量,手动设置public static final int MAX_GEN=5000;//运行代数public static final float w=0.5f;//权重public static int bestNum;public static int scale=30;//种群规模public static int t;//当前代数public static int point[][]=new int[cityNum][2];//每个城市的坐标public static int dist[][]=new int[cityNum][cityNum];//距离矩阵public static int oppulation[][]=new int[scale][cityNum];//粒子群public static ArrayList<ArrayList<SO>>listV;//每个粒子的初始交换序列public static int[][]Pd=new int[scale][cityNum];//一个粒子历代中出现的最好的解public static int[]vPd=new int[scale];//粒子的评价值public static int[]Pgd=new int[cityNum];//整个粒子群经历过的最好的解,每个粒子都能记住自己搜索到的最好解public static int vPgd;//最后的解的评价值public static int bestT;//最佳出现代数public static int[]fitness=new int[scale];//种群适应度,表示种群中各个个体的适应度public static Random random;//读取数据并初始化public static void read_data(String filepath) throws FileNotFoundException {String line=null;String substr[]=null;Scanner cin=new Scanner(new BufferedReader(new FileReader(filepath)));for (int i = 0; i < cityNum; i++) {line=cin.nextLine();line.trim();substr=line.split(" ");point[i][0]=Integer.parseInt(substr[1]);//x坐标point[i][1]=Integer.parseInt(substr[2]);//y坐标}cin.close();//计算距离矩阵,注意这里的计算方式,才用的是伪欧式距离for (int i = 0; i < cityNum; i++) {dist[i][i]=0;//对角线元素为0for (int j = i+1; j < cityNum; j++) {double rij=Math.sqrt((Math.pow(point[i][0]-point[j][0], 2)+Math.pow(point[i][1]-point[j][1], 2))/10.0);//rij四舍五入取整int tij=(int) Math.round(rij);if(tij<rij) {dist[i][j]=tij+1;dist[j][i]=dist[i][j];}else {dist[i][j]=tij;dist[j][i]=dist[i][j];}}}dist[cityNum-1][cityNum-1]=0;vPgd=Integer.MAX_VALUE;bestT=0;t=0;random=new Random(System.currentTimeMillis());}
}

SO类是蚂蚁类

package com.chb.Tabu;public class SO {private int x;private int y;public SO(int x, int y) {super();this.x = x;this.y = y;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}
}

PSO类是算法的主体类

package com.chb.Tabu;import java.io.FileNotFoundException;
import java.util.ArrayList;public class PSO {//初始化种群public static void initGroup() {int i,j,k;for (k = 0; k <Data.scale; k++) {//种群数Data.oppulation[k][0]=Data.random.nextInt(65535)%Data.cityNum;for (i = 0; i < Data.cityNum; ) {//粒子个数Data.oppulation[k][i]=Data.random.nextInt(65535)%Data.cityNum; for ( j = 0; j <i; j++) {if(Data.oppulation[k][i]==Data.oppulation[k][j]) {break;}}if(j==i) {i++;}}}}public static void initListV() {int ra;int raA;int raB;Data.listV=new ArrayList<ArrayList<SO>>();for (int i = 0; i < Data.scale; i++) {ArrayList<SO>list=new ArrayList<SO>();ra=Data.random.nextInt(65535)%Data.cityNum;for (int j = 0; j < ra; j++) {raA=Data.random.nextInt(65535)%Data.cityNum;raB=Data.random.nextInt(65535)%Data.cityNum;while(raA==raB) {raB=Data.random.nextInt(65535)%Data.cityNum;}SO s=new SO(raA,raB);list.add(s);}Data.listV.add(list);}}//评价函数public static int evaluate(int[] chr) {int len=0;for (int i = 1; i < Data.cityNum; i++) {len+=Data.dist[chr[i-1]][chr[i]];}len+=Data.dist[chr[Data.cityNum-1]][chr[0]];return len;}// 求一个基本交换序列作用于编码arr后的编码public static void add(int[]arr,ArrayList<SO>list) {int temp=-1;SO s;for (int i = 0; i < list.size(); i++) {s=list.get(0);temp=arr[s.getX()];arr[s.getX()]=arr[s.getY()];arr[s.getY()]=temp;}}// 求两个编码的基本交换序列,如A-B=SSpublic static ArrayList<SO>minus(int[]a,int[]b){int[]temp=b.clone();int index;SO s;ArrayList<SO> list=new ArrayList<SO>();for (int i = 0; i < Data.cityNum; i++) {if(a[i]!=temp[i]) {// 在temp中找出与a[i]相同数值的下标indexindex=findNum(temp,a[i]);// 在temp中交换下标i与下标index的值changeIndex(temp, i, index);// 记住交换子s = new SO(i, index);// 保存交换子list.add(s);}}return list;}// 在arr数组中查找num,返回num的下标public static int findNum(int[]arr,int num) {int index=-1;for (int i = 0; i < Data.cityNum; i++) {if(arr[i]==num) {index=i;break;}}return index;}// 将数组arr下标index1与下标index2的值交换public static void changeIndex(int[]arr,int index1,int index2) {int temp=arr[index1];arr[index1]=arr[index2];arr[index2]=temp;}//二维数组拷贝public static void copyarray(int[][]a,int[][]b) {for (int i = 0; i < Data.scale; i++) {for (int j = 0; j < Data.cityNum; j++) {b[i][j]=a[i][j];}}}//一维数组拷贝public static void copyarrayNum(int[]a,int[]b) {for (int i = 0; i < Data.cityNum; i++) {b[i]=a[i];}}public static void evolution() {int i,j,k;int len=0;float ra=0f;ArrayList<SO>Vi;//迭代一次for (int t = 0; t < Data.MAX_GEN; t++) {//对于每颗粒子for (i = 0; i < Data.scale; i++) {if(i==Data.bestNum) {continue;}ArrayList<SO>Vii=new ArrayList<SO>();Vi=Data.listV.get(i);len=(int) (Vi.size()*Data.w);for ( j = 0; j < len; j++) {Vii.add(Vi.get(j));}// Pid-XidArrayList<SO> a = minus(Data.Pd[i], Data.oppulation[i]);ra = Data.random.nextFloat();// ra(Pid-Xid)+len = (int) (a.size() * ra);//越界判断for (j = 0; j < len; j++) {Vii.add(a.get(j));}// Pid-XidArrayList<SO> b = minus(Data.Pgd, Data.oppulation[i]);ra = Data.random.nextFloat();// ra(Pid-Xid)+len = (int) (b.size() * ra);//越界判断for (j = 0; j < len; j++) {SO tt= b.get(j);Vii.add(tt);}//保存ViiData.listV.add(i,Vii);// 更新位置add(Data.oppulation[i], Vii);// 计算新粒子群适应度,Fitness[max],选出最好的解for (k = 0; k < Data.scale; k++) {Data.fitness[k] = evaluate(Data.oppulation[k]);if (Data.vPd[k] > Data.fitness[k]) {Data.vPd[k] = Data.fitness[k];copyarrayNum(Data.oppulation[k], Data.Pd[k]);Data.bestNum=k;}if (Data.vPgd > Data.vPd[k]) {//System.out.println("最佳长度"+Data.vPgd+" 代数:"+Data.bestT);Data.bestT = t;Data.vPgd = Data.vPd[k];copyarrayNum(Data.Pd[k], Data.Pgd);}}        }}}public static void solve() {int i;int k;initGroup();initListV();// 每颗粒子记住自己最好的解copyarray(Data.oppulation, Data.Pd);// 计算初始化种群适应度,Fitness[max],选出最好的解for (k = 0; k < Data.scale; k++) {Data.fitness[k] = evaluate(Data.oppulation[k]);Data.vPd[k] = Data.fitness[k];if (Data.vPgd > Data.vPd[k]) {Data.vPgd = Data.vPd[k];copyarrayNum(Data.Pd[k], Data.Pgd);Data.bestNum=k;}}// 打印
//      System.out.println("初始粒子群...");
//      for (k = 0; k < Data.scale; k++) {
//          for (i = 0; i < Data.cityNum; i++) {
//              System.out.print(Data.oppulation[k][i] + ",");
//          }
//          System.out.println();
//          System.out.println("----" + Data.fitness[k]);
//      }// 进化evolution();// 打印
//      System.out.println("最后粒子群...");
//      for (k = 0; k < Data.scale; k++) {
//          for (i = 0; i < Data.cityNum; i++) {
//              System.out.print(Data.oppulation[k][i] + ",");
//          }
//          System.out.println();
//          System.out.println("----" + Data.fitness[k]);
//         }System.out.println("最佳长度出现代数:"+Data.bestT);System.out.println("最佳长度"+Data.vPgd);System.out.println("最佳路径:");for (i = 0; i < Data.cityNum; i++) {System.out.print(Data.Pgd[i] + "-->");}}public static void main(String[] args) throws FileNotFoundException {Data.read_data("data/att48.txt");PSO.solve();}
}

data文件夹中的att48.txt是测试文件,可直接百度TSPLIB下载,或从https://pan.baidu.com/s/1Pc71mAN7WBbdxkzOkOK8gw处下载
运行结果:

分析:这个实验结果很差,原因出在迭代公式上,以后有时间再优化

:本文提炼、转载自
[1]https://blog.csdn.net/wangqiuyun/article/details/12515203
[2]https://mp.weixin.qq.com/s?__biz=MzU0NzgyMjgwNg==&mid=2247485031&idx=1&sn=7431c3937e66bf3f8f383eb8f088f6f3&chksm=fb49cbdecc3e42c8f38d1af4ae67c6c667350605bc7a01c26a4ac4b53f4207c156dfe09ed104&mpshare=1&scene=1&srcid=0822pVkjBrc3Z6hBfKflSkNn&sharer_sharetime=1566433694416&sharer_shareid=054592193644de509623829748e83807&key=5c697a296e1d5a5c77e9aab85df6cf52cb48d9f4dfadc09bce1ab7644261e5b6b451806e6c8d6e58e4cb08b22ec02421d923a21932c520f029d0a52d62971bfdffcac0dcf87536336aeb1205cca7ed28&ascene=1&uin=MjYzMDA1MzAyMQ%3D%3D&devicetype=Windows+10&version=62060834&lang=zh_CN&pass_ticket=u%2FFCYZF31oHuOVDtiAk9qU93vdWJIhzB98r7dHrcOYBSBGJ242N951lTB%2F35LG4A

TSP-粒子群算法求解相关推荐

  1. 粒子群算法java_基于粒子群算法求解求解TSP问题(JAVA)

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

  2. 粒子群算法求解旅行商问题TSP (JAVA实现)

    粒子群算法求解旅行商问题TSP 写在开头: 最近师妹的结课作业问我,关于使用粒子群求解TSP问题的思路.我想了想,自己去年的作业用的是遗传算法,貌似有些关联,索性给看了看代码.重新学习了一遍粒子群算法 ...

  3. 粒子群算法求解旅行商问题

    算法原理 旅行商问题是一个经典的NP问题,假设有N个城市,需要确定一个访问顺序,使得每个城市都访问一面,最后回到起点城市,且保证行走的总距离最短.        假设随机生成10个城市坐标,城市之间的 ...

  4. 粒子群算法求解多元函数最值问题

    粒子群算法求解多元函数最值问题 一.简介 多元函数极值&最值问题通常使用导数/偏导数进行推导,这里尝试使用启发式算法进行求解近似最优解.选用粒子群算法进行求解,粒子群算法模仿鸟群觅食行为,核心 ...

  5. 粒子群算法求解带约束优化问题 源码实现

    算法原理 之前求解的无约束的问题. 粒子群算法求解无约束优化问题 源码实现 算法原理如下 今天讲解下求解约束优化的问题.该问题常用的方法是罚函数法.即如果一个解x不满足约束条件,就对适应度值设置一个惩 ...

  6. MATLAB粒子群算法求解带充电站(桩)的电动车辆路径规划EVRP问题代码实例

    MATLAB粒子群算法求解带充电站(桩)的电动车辆路径规划EVRP问题代码实例 问题实例描述: 现有一个配送中心需要向20个客户点进行送货.每个客户点有不同货物需求量和卸货服务时间.配送中心和客户点的 ...

  7. 【微电网优化】基于matlab粒子群算法求解综合能源系统优化问题【含Matlab源码 1969期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[微电网优化]基于matlab粒子群算法求解综合能源系统优化问题[含Matlab源码 1969期] 点击上面蓝色字体,直接付费下载,即可. ...

  8. 粒子群算法求解四维病态方程

    粒子群算法求解四维病态方程 问题 求解 问题 min⁡f(x)=∑i=13[100(xi+1−xi2)2+(xi−1)2]xi∈[−30,30](i=1,2,3,4)\begin{aligned} \ ...

  9. 【选址优化】基于粒子群算法求解配电网抢修选址优化问题含Matlab源码

    1 简介 基于粒子群算法求解配电网抢修选址优化问题​. 2 部分代码 function DrawCircle(Circle1, Circle2, r, 3600, s)​plot(model.trou ...

  10. 【微电网优化】基于matlab粒子群算法求解微网经济调度和环境友好调度优化问题【含Matlab源码 2283期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[微电网优化]基于matlab粒子群算法求解微网经济调度和环境友好调度优化问题[含Matlab源码 2283期] 点击上面蓝色字体,直接付 ...

最新文章

  1. 海量java等互联网相关电子图书分享
  2. 你觉得你个性上最大的优点是什么?
  3. BeetleX.FastHttpApi之Vuejs扩展
  4. [html] 你有使用过webp的图片格式吗?
  5. mysql limit 后子查询_mysql 关于limit 子查询和获取某当天所有记录
  6. c++二分答案 之 跳石头
  7. 诊断域帐号被锁定的原因
  8. hibernate映射配置文件说明
  9. ARM-linux的启动流程
  10. python和matlab的区别_我为什么选择Python,不是Matlab和R语言呢?
  11. 使用爬虫下载x书视频
  12. IE 0day,2010传说中的攻击Google等公司的代码
  13. 东南大学成贤学院计算机报名,2021上半年江苏东南大学成贤学院计算机等级考试报名通知...
  14. Jetson Nano | DeepStream部署Yolov5(Pytorch模型-->wts 文件-->TensorRT模型)
  15. Kubernetes — 使用 kubeadm 部署高可用集群
  16. SolidWorks学习笔记5创建基准面,基准线,基准点
  17. 蓝字冲销是什么意思_红字和蓝字冲销
  18. jquery实现标签锚定(定位)
  19. ffmpeg安装教程(支持10bit编码)
  20. html5英文参考文献,外文参考文献引用常识介绍

热门文章

  1. php API接口最基本的写法
  2. Win10电脑一直循环重启进不了系统桌面怎么办
  3. Flutter 多子 Widget 布之Stack、Positioned
  4. Java使用aopse实现word转换pdf
  5. iptable中文学习文档
  6. Java程序性能优化 ! .
  7. Leetcode之跳跃游戏整理
  8. linux 命令行修改mac,Linux下修改MAC地址
  9. java登录界面代码
  10. 运营——线上引流9大方法