粒子群优化算法及其java实现
憋了两周终于把开题报告憋出来了,再一次证明自己不适合搞学术,哎……,花了点时间把报告中提到的粒子群算法看了看,看了些资料,用java跑起来。
算法简介
粒子群算法最先由Barnhart博士和Kennedy博士于1995 年提出,是一种源于对鸟群捕食行为的研究而发明的进化计算技术,原理是模仿鸟群寻觅食物的搜索过程,设想鸟群在一定区域搜寻食物,在不知道食物确切位置的情况下,鸟群依靠群体中个体判断距离食物的远近程度来调节飞行方向和飞行速度,最终通过群体的经验和自身记忆的智慧找到食物。
算法原理
算法描述
算法流程图
算法的实现(java)
- Particle.java文件
package com.jiajia.pso;
import java.util.Random;
/**
* @ClassName: Particle
* @Author: fanjiajia
* @Date: 2019/5/13 上午11:01
* @Version: 1.0
* @Description:
*/
public class Particle {
//维数
public int dimension = 2;
//粒子的位置
public double[] X = new double[dimension];
//局部最好位置
public double[] pbest = new double[dimension];
//粒子的速度
public double[] V = new double[dimension];
//最大速度
public double Vmax = 2;
//适应值
public double fitness;
/**
* 根据当前位置计算适应值
* @return newFitness
*/
public double calculateFitness() {
//1.Ackley's function:
//double newFitness = -20*Math.pow(Math.E,(-0.2*Math.sqrt(0.5*(X[0]*X[0]+X[1]*X[1]))))-Math.pow(Math.E,(0.5*(Math.cos(2*Math.PI*X[0])+Math.cos(2*Math.PI*X[1]))))+Math.E+20;
//2.Sphere function
//double newFitness = X[0]*X[0]+X[1]*X[1];
//3.Rosenbrock function
double newFitness = 100*(Math.pow((X[1]-X[0]*X[0]),2))+Math.pow((X[0]-1), 2);
return newFitness;
}
/**
* 初始化自己的位置和pbest
*/
public void initialX() {
for(int i=0;i<dimension;i++) {
X[i] = new Random().nextInt(50);
pbest[i] = X[i];
}
}
/**
* 初始化自己的速度
*/
public void initialV() {
for(int i=0;i<dimension;i++) {
double tmp = new Random().nextDouble();//随机产生一个0~1的随机小数
V[i] = tmp*4+(-2);
}
}
}
- PSO.java
package com.jiajia.pso;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* @ClassName: PSO
* @Author: fanjiajia
* @Date: 2019/5/13 上午11:02
* @Version: 1.0
* @Description:
*/
public class PSO {
private static double[] gbest;//全局最优位置
private static double gbest_fitness = Double.MAX_VALUE;//全局最优位置对应的fitness
private static int particle_num = 20;//粒子数
private static int N = 500;//迭代次数
private static int c1,c2 = 2;
private static double w = 1.4;//惯性因子
private static List<Particle> particles = new ArrayList<Particle>();//粒子群
private static List<Double> fittessList = new ArrayList<>(N);
/**
* 主程序入口
* @param args
*/
public static void main(String[] args) {
process();
}
/**
* 初始化所有粒子
*/
public static void initialParticles() {
for(int i=0;i<particle_num;i++) {
Particle particle = new Particle();
particle.initialX();
particle.initialV();
particle.fitness = particle.calculateFitness();
particles.add(particle);
}
}
/**
* update gbest
*/
public static void updateGbest() {
double fitness = Double.MAX_VALUE;
int index = 0;
for(int i=0;i<particle_num;i++) { // 找到群体中适应值最小的粒子
if(particles.get(i).fitness<fitness) {
index = i;
fitness = particles.get(i).fitness;
}
}
if(fitness<gbest_fitness) { // 如果个体适应值小于全局适应值,更新全局的最优值为个体最优值
gbest = particles.get(index).pbest.clone();
gbest_fitness = fitness;
}
}
/**
* 跟新每个粒子的速度
*/
public static void updateV(int n) {
for(Particle particle:particles) {
for(int i=0;i<particle.dimension;i++) {
double v =(0.9 - n*(0.9-0.4)/N) * particle.V[i]+c1*rand()*(particle.pbest[i]-particle.X[i])+c2*rand()*(gbest[i]-particle.X[i]);
if(v>particle.Vmax) // 判断速度是否超过最大的速度
v = particle.Vmax;
else if(v<-particle.Vmax) // 比最大速度的相反数小
v = -particle.Vmax;
particle.V[i] = v;//更新Vi
}
}
}
/**
* 更新每个粒子的位置和pbest
*/
public static void updateX() {
for(Particle particle:particles) {
for(int i=0;i<particle.dimension;i++) {
particle.X[i] = particle.X[i] + particle.V[i];
}
double newFitness = particle.calculateFitness();//新的适应值
//如果新的适应值比原来的小则跟新fitness和pbest
if(newFitness<particle.fitness) {
particle.pbest = particle.X.clone();
particle.fitness = newFitness;
}
}
}
/**
* 算法主要流程
*/
public static void process() {
int n = 0;
initialParticles();
updateGbest();
while(n++<N) {
updateV(n);
updateX();
updateGbest();
fittessList.add(gbest_fitness);
System.out.println(n+".当前gbest:("+gbest[0]+","+gbest[1]+") fitness="+gbest_fitness);
}
write2File();
}
/**
* 返回一个0~1的随机数
* @return
*/
public static double rand() {
return new Random().nextDouble();
}
}
代码参考了其他资料,后面有说明,但是对其中部分进行了改进。
在Particle
(粒子类)中设定了三个适应函数,Ackley
,Sphere
,Rosenbrock
,关于这三个函数的介绍可以参考https://en.wikipedia.org/wiki/Test_functions_for_optimization,这里面列出来了很多优化测试函数,很多的paper在设计了优化策略或者改进相应的优化策略之后,都会利用其中的函数进行测试。
这里用到的函数是Rosenbrock
:
可以看出这里最小值在(1,1,,,1)处取的。
为了看到相应的效果,这里将全局适应值写到txt文件中,并利用python绘制出来(莫名的感觉繁琐,要是python,哪有这么麻烦,只可惜最后的实验都是java写)。
上面是$w$为1时,即惯性系数为1时的收敛结果,可以看出,算法前期搜索很快,后期较慢,且偶尔会陷入局部最优解里面。
惯性因子w的优化
惯性因子$w$代表受上一次粒子速度的影响程度,$w$越大,收敛越快,但容易错过最优解。$w$越小,收敛较慢,容易陷入局部最优解,出不来。因此改进$w$成为很多改进的焦点,其中采用较多的是Shi建议的线性递减权值策略,通常将$w$设定在[0.4,0.9]之间:
采用线性递减权值策略后得到的收敛效果:
可以看出前期收敛直线下降,且不容易陷入局部最优,最后达到全局收敛。
除了上面的线性递减权值策略,还有自适应权值策略,随机权重策略。详见参考资料[4];
参考资料
- 粒子群算法原理及Matlab实现
- 基本PSO算法实现(Java)
- Y.Shi. A Modified Particle Swarm Optimizer. 1998
- Test functions for optimization
- 武装. 几种改进的智能优化算法及其应用[M].科学技术文献出版社, 2018.
最后
生命不息,生活好难!!!
粒子群优化算法及其java实现的更多相关文章
- [Algorithm] 群体智能优化算法之粒子群优化算法
同进化算法(见博客<[Evolutionary Algorithm] 进化算法简介>,进化算法是受生物进化机制启发而产生的一系列算法)和人工神经网络算法(Neural Networks,简 ...
- 粒子群优化算法PSO及matlab实现
算法学习自:MATLAB与机器学习教学视频 1.粒子群优化算法概述 粒子群优化(PSO, particle swarm optimization)算法是计算智能领域,除了蚁群算法,鱼群算法之外的一种群 ...
- MATLAB粒子群优化算法(PSO)
MATLAB粒子群优化算法(PSO) 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 一.介绍 粒子群优化算法(Particle Swarm Optim ...
- ARIMA模型--粒子群优化算法(PSO)和遗传算法(GA)
ARIMA模型(完整的Word文件可以去我的博客里面下载) ARIMA模型(英语:AutoregressiveIntegratedMovingAverage model),差分整合移动平均自回归模型, ...
- 计算智能(CI)之粒子群优化算法(PSO)(一)
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 计算智能(Computational Intelligence , ...
- 粒子群优化算法(PSO)之基于离散化的特征选择(FS)(二)
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 作者:Geppetto 前面我们介绍了特征选择(Feature S ...
- 粒子群优化算法(PSO)之基于离散化的特征选择(FS)(一)
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 作者:Geppetto 在机器学习中,离散化(Discretiza ...
- 粒子群优化算法对BP神经网络优化 Matlab实现
1.粒子群优化算法 粒子群算法(particle swarm optimization,PSO)由Kennedy和Eberhart在1995年提出,该算法模拟鸟集群飞行觅食的行为,鸟之间通过集体的协作 ...
- 数值计算:粒子群优化算法(PSO)
PSO 最近需要用上一点最优化相关的理论,特地去查了些PSO算法相关资料,在此记录下学习笔记,附上程序代码.基础知识参考知乎大佬文章,写得很棒! 传送门 背景 起源:1995年,受到鸟群觅食行为的规律 ...
随机推荐
- vue 使用vue-video-player播放hls格式视频
安装 vue-video-player 在 “ devDependencies ” 中 安装 videojs-contrib-hls 在“ dependencies ”中 main.js 中 ...
- node.js 微信开发2-消息回复、token获取、自定义菜单
项目结构 >config/wechat.json 微信公众号的配置文件 >controllers/oauth.js 微信网页授权接口(下一篇再细讲讲) >controllers/we ...
- 互联网项目中mysql推荐(读已提交RC)的事务隔离级别
[原创]互联网项目中mysql应该选什么事务隔离级别 Mysql为什么不和Oracle一样使用RC,而用RR 使用RC的原因 这个是有历史原因的,当然要从我们的主从复制开始讲起了!主从复制,是基于什么 ...
- ELK文档--ELK简介
请参考:http://www.cnblogs.com/aresxin/p/8035137.html
- 四:MySQL系列之Python交互(四)
该篇主要介绍MySQL数据库的分表.以及与Python的交互的基本操作等. 一.拆分表操作 1.1 准备工作 创建数据库 --> 使用数据库 --> 创建数据表 --- 添加记录 -- ...
- Make 和 Makefile快速入门
前言 一个项目,拥有成百上千的源程序文件,编译链接这些源文件都是有规则的.Makefile是整个工程的编译规则集合,只需要一个make命令,就可以实现“自动化编译”.make是一个解释makefile ...
- 更改Ubuntu下默认Python版本
更改Ubuntu下默认Python版本 首先查看系统内有哪些版本的Python ls /usr/bin/python* 查看当前python版本 python --version 基于用户修改默认版本 ...
- pandas里面过滤列出现ValueError: cannot index with vector containing NA / NaN values错误的解决方法(转)
###df_18的字段fuek是否包含 / df_18[df_18['fuel'].str.contains('/')] 报错: ValueError Traceback (most recent c ...
- k8s的Pod状态和生命周期管理
Pod状态和生命周期管理 一.什么是Pod? 二.Pod中如何管理多个容器? 三.使用Pod 四.Pod的持久性和终止 五.Pause容器 六.init容器 七.Pod的生命周期 (1)Pod p ...
- python中set(集合),深浅拷贝以及一些补充知识点
1.set集合 特点:无序,不重复,元素必须可哈希(不可变) 作用:去重复 本身是可变的数据类型.有增删改查操作.{集合的增删改查操作应用较少,这里不做详细介绍了(这里的增有一个方法update注意这 ...