一、题目

使用粒子群算法求解函数f(x)的最小值。理论上的最小值是0。

二、原理

粒子群算法利用群体中的个体对信息的共享使整个群体的运动在问题求解空间中产生从无序到有序的演化过程,从而获得最优解。

试想一下,如果一群鸟在一片区域中寻找食物,所有的鸟都不知道食物在什么地方,但是每一只鸟都知道自己距离食物有多远,也知道这一群鸟中离食物最近的鸟在什么位置,这样每一只鸟都可以改变当前自己的移动方向,逐渐向离食物最近的鸟所在位置靠近,这样通过不断的搜寻,就能找到食物。

解题思路:

  1. 假设有100只鸟,初始时这100只鸟分布在不同的位置。这里鸟的位置用30个自变量xi表示。这里的鸟相当于粒子。
  2. 计算每只鸟相对于食物的距离。这里的距离计算使用设定的目标函数,本题的距离目标函数是f(x)。因为我们就是希望f(x)越小越好,与距离关系对应。
  3. 找到这100只鸟当中离食物最近的鸟的位置作为此时的全局最优解。
  4. 根据每一只鸟当前的位置与全局最优解的位置更新当前的速度与位置,向最优解的位置靠近。
  5. 通过数次迭代,就能找到食物的位置。食物的位置就是f(x)的最小值。

更新公式:

v[i] 表示粒子i的速度。
w 为惯性权重,用于记录当前自身的速度,通常为非负数,调节解空间的搜索范围,为0时则失去自身速度的记忆。
c1、c2 表示学习参数,调节学习的最大步长。
pbest 是当前粒子的最优值。
gbest 为集群中搜索到的最优值,也就是历史最优值。
present[i] 为当前粒子的位置。

三、程序实现

3.1 粒子状态类

import java.util.Random;public class Particle {//维数public  int dimension = 30;//粒子的位置public double[] X = new double[dimension];//局部最好位置public double[] pbest = new double[dimension];//粒子的速度public double[] V = new double[dimension];//适应值public double fitness;/*** 根据当前位置计算适应值* @return newFitness*/public double calculateFitness() {double newFitness;double a = 0;double b = 1;for (int i = 0; i < dimension; i++) {a += X[i] * X[i];b = b * Math.cos(X[i] / Math.pow((i+1), 0.5));}newFitness = a / 4000 - b + 1;return newFitness;}/*** 初始化自己的位置和pbest*/public void initialX() {for(int i = 0;i < dimension; i++) {X[i] = new Random().nextDouble(); // 随机产生一个0~1的随机小数X[i] = -600 + 1200 * X[i];pbest[i] = X[i];}}/*** 初始化自己的速度*/public void initialV() {for(int i = 0;i < dimension; i++) {double tmp = new Random().nextDouble(); // 随机产生一个0~1的随机小数V[i] = tmp * 2 - 4;}}
}

3.2 日志类

import java.io.*;
/*** 日志类,记录结果。*/
public class Logger {public static void log(String msg) {try {BufferedWriter out = new BufferedWriter(new FileWriter("./PSO/src/log.txt", true));out.write(msg);out.flush();out.close();} catch (IOException e) {e.printStackTrace();}}
}

3.3 PSO类

import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class PSO {private static double[] gbest; // 全局最优位置private static double gbest_fitness = Double.MAX_VALUE; // 全局最优位置对应的fitnessprivate static int particle_num = 100; // 粒子数private static int N = 50000; // 迭代次数private static int c1 = 2;private static int c2 = 2;private static double w = 1.5; // 惯性因子private static double Vmax = 1; // 最大速度private static List<Particle> particles = new ArrayList<Particle>();//粒子群/*** 主程序入口*/public static void main(String[] args) {initialParticles(); // 初始化updateGbest(); // 更新gBest// 循环N次for (int i = 0; i < N; i++) {updateV(i); // 更新VupdateX(); // 更新XupdateGbest(); // 更新gBest// 输出日志if (i % 20 == 0) {System.out.println(i + "fitness=" + gbest_fitness);String msg = i / 20 + " " + gbest_fitness + "\n";Logger.log(msg);}}}/*** 初始化所有粒子*/public static void initialParticles() {for(int i=0; i < particle_num; i++) {Particle particle = new Particle(); // 创建粒子群对象particle.initialX(); // 初始化Xparticle.initialV(); // 初始化Vparticle.fitness = particle.calculateFitness(); // 计算距离particles.add(particle); // 放到集合中}}/*** 更新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) {if (n % 10000 == 0) {Vmax = Vmax * 0.1;}for(Particle particle : particles) {for(int i = 0;i < particle.dimension; i++) {double v = w * particle.V[i]+c1*rand()*(particle.pbest[i]-particle.X[i])+c2*rand()*(gbest[i]-particle.X[i]);if(v > Vmax) // 判断速度是否超过最大的速度v =  Vmax;else if(v < - Vmax) // 比最大速度的相反数小v = - 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和pbestif(newFitness < particle.fitness) {particle.pbest = particle.X.clone();particle.fitness = newFitness;}}}/*** 返回一个0~1的随机数* @return*/public static double rand() {return new Random().nextDouble();}
}

四、实验结果

4.1 Python可视化

这里为了显示的美观性,只选取了其中一部分数据进行可视化。

import os
import matplotlib.pyplot as plt
import matplotlib; matplotlib.use('TkAgg')# 读取log.txt文件
with open(os.path.join("log.txt"), 'r') as fd:dataList = fd.readlines()
dataList = [l[:-1] for l in dataList] # 把/n去掉
# 将数据放入list中
data = []
iters = []
for i in range(len(dataList[900:950])):sample = dataList[i].split()data.append(float(sample[1]))iters.append(int(sample[0]))
# 绘图
plt.title("Result GA")
plt.plot(iters, data, color='blue')
plt.xlabel("iters")
plt.ylabel("result")
plt.savefig("Result_GA")
plt.show()

4.2 实验结果

横坐标是迭代次数,纵坐标是距离结果。

迭代50000次的结果。理论上继续迭代可以使值更接近于0。

五、总结

本次实验在调参的时候遇到了问题,无论迭代次数有多少次,目标距离很难有进一步的缩小,即无法跳出局部最优解,经过大量的调试,得到了其中一种解决方案。

方法是改变设定的Vmax值,该值是用来限制V的大小,V是用来更新参数X的,X是用来求距离的。一共50000次迭代,每10000次,Vmax缩小为原来的十分之一。

通过该方法,解决了距离无法缩小的问题。即无法跳出局部最优解的问题。

Java实战:粒子群算法相关推荐

  1. 粒子群算法实战分享-附原版动画PPT(技术分享也可以文艺范?)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 本文是针对博主使用粒子群优化算法解决水面无人艇静态.动态障碍物规避,及场地布局三类问题,做了更深入的总结分析. 与目前火热的机器学习不同,智能优化 ...

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

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

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

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

  4. 群体智能-粒子群算法--使用java对于粒子群系统的显示(2)

    大家好,可爱的小编今天来补充剩下的关于粒子群算法的想法. 呃呃,今天呢?小编主要谈的是关于如何编写这个的java实现代码.其实,关于代码实现呢?这个小编觉得,其实有时候你的编程思维很重要,可能要是一开 ...

  5. 粒子群算法(PSO)——Java实现PSO算法(详细注释) 优化算法

    粒子群算法原理: https://blog.csdn.net/daaikuaichuan/article/details/81382794 代码||注释||结果 package PSO;/** Tar ...

  6. 普通粒子群算法和优化方法

    粒子群优化(PSO, particle swarm optimization) 是由Kennedy和Eberhart在1995年提出的一 种群智能优化方法. 优点:好理解容易实现,适合解决极值问题 缺 ...

  7. 粒子群算法tsp java_粒子群算法解决TSP问题汇总.doc

    PAGE \* MERGEFORMAT 14 河南理工大学计算机科学与技术学院课程设计报告 2014- 2015学年第一学期 课程名称 Java语言程序设计 设计题目 利用粒子群算法解决TSP问题 姓 ...

  8. 粒子群算法tsp java_粒子群算法解决TSP问题

    1. 粒子群算法简介 粒子群算法(particle swarm optimization,PSO)由Kennedy和Eberhart在1995年提出,属于进化算法的一种,是通过对模拟鸟群扑食行为设计的 ...

  9. 粒子群课设_GitHub - LIYAJUN2018/tscss: 基于粒子群算法的中职自动排课系统

    kvf-admin kvf-admin是一套快速开发框架.脚手架.后台管理系统.权限系统,上手简单,拿来即用.为广大开发者去除大部分重复繁锁的代码工作,让开发者拥有更多的时间陪恋人.家人和朋友. 后端 ...

最新文章

  1. 【PC工具】好用的搜索引擎DogeDoge替代百度搜索,中国的duckduckgo
  2. python连接oracle数据库的方法_Python3.6连接Oracle数据库的方法详解
  3. Jsoup代码解读之三-Document的输出
  4. 弱鸡儿长乐爆零旅Day1
  5. Eclipse下Java项目转web项目
  6. 转【es中数据节点和主机】
  7. 全局变量与局部变量的作用域问题
  8. lambda表达式python_python lambda表达式用法
  9. Defending Against Model Stealing Attacks with Adaptive Misinformation
  10. 为什么说SQL语句中使用IN性能不高?
  11. springboot调整请求头大小_SpringBoot http post请求数据大小设置操作
  12. java sql 工资管理,企业工资管理系统(Java+MySQL)Word版
  13. 2023年“挑战杯”大学生课外学术科技作品竞赛有感
  14. 股市的逻辑-201006
  15. 一个非常轻巧的基于Groovy的Web应用程序项目模板
  16. 5G为人工智能与工业互联网赋能|79页高清PPT
  17. 测U盘实际容量 (缩水U盘、扩容盘、假U盘)
  18. Linux bz2文件解压
  19. python安装其他版本时出现0x80070666
  20. WordPress 4.1的新功能

热门文章

  1. 拼多多API接口,item_get_app - 根据ID取商品详情原数据
  2. 从Spy Mouse看App Store的推广方法
  3. koa2搭建项目(一)
  4. hN大学数字逻辑电路期末考试 题详解
  5. bs4主要知识点介绍及实例解析---利用bs4爬取伯乐在线(分别存储在数据库和xls表中)
  6. ps去掉文字的简单方法
  7. MySql like通配符使用(mysql 正则表达式)
  8. UR3构型机器人MATLAB仿真
  9. java中MVC原理详解,Spring MVC 原理总结
  10. 能力成长模型(转自阿里梁飞老师博客)