粒子群优化算法及其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年,受到鸟群觅食行为的规律 ...
随机推荐
- English-培训2-五大句型
- java网络编程--httpurlconnection
HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现.如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行.可以通过以下两个语句来 ...
- Innodb学习
一.并发控制 为什么要进行并发控制? 因为并发的任务会对同一个临界资源进行操作,如果不进行并发控制,可能导致不一致,故必须进行并发控制. 如何进行并发控制? 1.锁. 2.数据多版本. 施工ing.. ...
- 一份数据分析学习清单.xls
今天给大家整理一份数据分析的学习清单,打算了解学习这方面的同学可以看看,基本上大的需要学习的点都有涉及:具体细节知识的学习建议大家亲自去动手制作思维导图,自己动手梳理知识脉络. 上期入口:18个堪称神 ...
- Laravel 队列不执行的原因,job缓存
laravel关于异步消息队列queue不生效(job缓存)解决办法 php artisan queue:restart 每次修改代码都需要执行上面的命令,执行后成功解决! 然后再次执行 php ar ...
- 【搜索/tarjan找环】zznu-简单环路
简单环路 题目描述 有一个N x M 大小的地图,地图中的每个单元包含一个大写字母. 若两个相邻的(这里的相邻指“上下左右”相邻)点上的字母相同,我们可以用线段连接这两个点. 若存在一个包含同一字母的 ...
- ngtos 天融信
NGFW系列产品基于天融信公司10年高品质安全产品开发经验结晶的NGTOS系统架构,采用了多项突破性技术.基于分层的设计思想,天融信公司通过长期的安全产品研发经验,分析多种安全硬件平台技术的差异,创造 ...
- C++读取中文或英文文件空格分割
// show file content - sbumpc() example #include <iostream> // std::cout, std::streambuf #incl ...
- Java下的tinylog日志打印
做个笔记. 做某个功能时需要DEBUG调试日志,但是直接System.out.println 是打印在终端,有些情况下是看不到输出的,所以需要用日志框架去打印输出值. 经过搜索完以后发现Logback ...
- 负载均衡集群(LBC)
一.LVS简介及工作模式1. LVS简介Linux Virtual Server,该软件的功能是实现LB(load balance) 2.LVS的三种工作模式 1)NAT模式(NAT) LVS 服务器 ...