PSO算法解决函数优化问题

  • 考虑下面的优化函数
  • PSO算法简要介绍
  • 第一步,群体粒子的初始化
  • 第二步,更新每个粒子的速度和位置
  • 第三步,根据粒子的适应值来更新个体的历史极值并计算全局极值
  • 最后

考虑下面的优化函数

minf(x1,x2)=0.5+sin⁡2x12+x22−0.5(1+0.001(x12+x22))2minf(x_1,x_2)=0.5+\frac{\sin^2\sqrt{x_1^2+x_2^2}-0.5}{(1+0.001(x_1^2+x_2^2))^2}minf(x1​,x2​)=0.5+(1+0.001(x12​+x22​))2sin2x12​+x22​​−0.5​
−100≤x1,x2≤100-100≤x_1,x_2≤100−100≤x1​,x2​≤100
        该优化问题的目标函数是Schaffer F6函数,该函数的全局最小值为f(x1,x2)=0,而最优解为(0,0).
用PSO算法求解该问题,其设计如下:
        (1)群体规模M= 20;
        (2)适应函数取为目标函数;
        (3)邻域结构采用全局邻域结构;
        (4)惯性权重 W=0.9;
        (5)c1 = c2 = 2;
        (6)最大速度Vmax=3;
        (7)粒子群初始化:初始化粒子群中每个粒子的位置随机地产生,每个分量均匀地分布在区间[-100,100]内,速度的每个分量均匀地分布在区间 [-3,3]内;
        (8)算法终止条件:算法达到最大迭代次数4000后终止;
        运行算法30次,每次都能发现问题的最优解或次优解。

PSO算法简要介绍

PSO算法流程图如下:

        假定粒子群P = {p1,p2,…,pM},即粒子群由M个粒子组成,其中,M称为群体规模。一个粒子通过其所在的位置和速度来描述。粒子pi在d维解空间的位置表示为xi=(xi`,xi2,…,xid),而速度表示为vi=(vi1,vi2,…,vid)。粒子Pi的个体极值表示为pbesti,即pbesti是粒子pi当前所发现的最好解,pi的局部极值表示为gi,即gi为粒子pi的近邻当前所发现的最好解。另外,PSO算法性能的好坏取决于邻域拓扑结构的选择、参数的设置等。
C++所需代码类如下所示:

头文件 源文件
X X.h /
Particle Particle.h Particle.cpp
Qunti Qunti.h Qunti.cpp

//X.h
#ifndef  X_H
#define X_H
#include "Particle.h"
class X
{
public:double x[N];
};
#endif // ! X_H
// Particle.h
#ifndef PARTICLE_H
#define  PARTICLE_H
#define N 2//维数
class Particle
{
public :double x[N], v[N];Particle();//初始化方法void shuchu();//打印函数
};
#endif // !PARTICLE_H
// Particle.cpp
#include "Particle.h"
#include <iostream>
using namespace std;
Particle::Particle()
{for (int i = 0; i < N; i++) {x[i] = 0;v[i] = 0;}
}void Particle::shuchu()
{std::cout << "位置x=(";for (int i = 0; i < N; i++){if(i == N-1)std::cout << x[i];else std::cout << x[i]<<",";}std::cout << ") 速度v=(";for (int i = 0; i < N; i++){if (i == N - 1)std::cout << v[i];else std::cout << v[i] << ",";}std::cout << ")"<<endl;
}
// Qunti.h
#ifndef QUNTI_H
#define QUNTI_H
#include "Particle.h"
const int M = 20;
class Qunti
{
public:Particle p[M];void shuchu();//初始化方法
};
#endif
// Qunti.cpp
#include "Qunti.h"
#include <iostream>
using namespace std;
void Qunti::shuchu()
{for (int i = 0; i < M; i++){std::cout << "粒子"<<i + 1;p[i].shuchu();}
}

第一步,群体粒子的初始化

每个粒子位置的每个分量随机均匀地在【-100,100】内产生,速度的每个分量随机均匀地在区间【-3,3】内产生。

//第一步,群体粒子的初始化;std::default_random_engine random(time(NULL));static std::uniform_real_distribution<double> distribution1(Xmin, std::nextafter(Xmax, DBL_MAX));// C++11提供的实数均匀分布模板类static std::uniform_real_distribution<double> distribution2(Vmin, std::nextafter(Vmax, DBL_MAX));// C++11提供的实数均匀分布模板类for (int i = 0; i < M; i++){for (int j = 0; j < N; j++){qt.p[i].x[j] = distribution1(random); //群体粒子位置向量初始化qt.p[i].v[j] = distribution2(random);//群体粒子速度向量初始化pbest[i].x[j] = qt.p[i].x[j];funvalue[i] = Mubiao_fun(qt.p[i].x);}}int minlocation = 0;double minfunvalue = funvalue[0];for (int i = 0; i < M; i++){if (funvalue[i] < minfunvalue){minfunvalue = funvalue[i];minlocation = i;}}for(int j=0;j<N;j++)gbest[j] = qt.p[minlocation].x[j];qt.shuchu();

第二步,更新每个粒子的速度和位置

在PSO算法中,粒子根据以下公式来更新速度和位置:
{vi←w⋅vi+c1⋅rand()⋅(pbesti−xi)+c2⋅rand()⋅(gi−xi),xj=xi+vi,\; \begin{cases} v_i\leftarrow{w\cdot v_i+c_1\cdot rand() \cdot (pbest_i-x_i)+c_2\cdot rand() \cdot(g_i-x_i)}, & \text{} \\ x_j=x_i+v_i,& \text{} \\ \end{cases} {vi​←w⋅vi​+c1​⋅rand()⋅(pbesti​−xi​)+c2​⋅rand()⋅(gi​−xi​),xj​=xi​+vi​,​​
        其中,w是一个正常数,成为惯性权重,c1,c2是两个正常数,称为学习因子,rand()是在[0,1]中服从均匀分布的随机数。
        从上面的速度和位置更新公式中可以看出,一个粒子的速度决定了器位置的变化范围。为了防止粒子过快地从搜索空间中的一个区域飞向另一个区域,定义一个参数Vmax,使得粒子每一维的速度都被限制在区间[-Vmax,Vmax]内,也就是说,若粒子pi的速度为vi=(vi1,vi2,…,vid),则使用以下的边界条件:
{vij>Vmax⟹vij=Vmax,j=1,...,d,vij<−Vmax⟹vij=−Vmax,j=1,...,d,\; \begin{cases} v_{ij} >V_{max} \implies v_{ij} = V_{max}, j=1,...,d, & \text{} \\ v_{ij} <-V_{max} \implies v_{ij} = -V_{max}, j=1,...,d,& \text{} \\ \end{cases} {vij​>Vmax​⟹vij​=Vmax​,j=1,...,d,vij​<−Vmax​⟹vij​=−Vmax​,j=1,...,d,​​

粒子pi更新后的速度是先前速度vi,pbesti-xi和gi-xi的加权矢量和,如下图所示。粒子在解空间内不断跟踪个体极值和局部极值进行搜索,直到满足算法的终止条件为止。

//更新每个粒子的速度和位置for (int j = 0; j < N; j++){static std::uniform_real_distribution<double> distribution3(0.0, std::nextafter(1.0, DBL_MAX));// C++11提供的实数均匀分布模板类qt.p[i].v[j] = w*qt.p[i].v[j] + c1*distribution3(random)*(pbest[i].x[j] - qt.p[i].x[j]) + c2*distribution3(random)*(gbest[j] - qt.p[i].x[j]);}for (int j = 0; j < N; j++){if (qt.p[i].v[j]> Vmax) qt.p[i].v[j] = Vmax;else if (qt.p[i].v[j] < Vmin) qt.p[i].v[j] = Vmin;}for (int j = 0; j < N; j++)//粒子速度越界调整{qt.p[i].x[j] += qt.p[i].v[j];}for (int j = 0; j < N; j++)//粒子位置越界调整{if (qt.p[i].x[j]> Xmax) qt.p[i].x[j] = Xmax;else if (qt.p[i].x[j] < Xmin) qt.p[i].x[j] = Xmin;}

第三步,根据粒子的适应值来更新个体的历史极值并计算全局极值

在PSO算法中,一个粒子的邻域表示群体中与该粒子相邻的粒子的集合,粒子可以与其邻域中的粒子交换信息,邻域的规模决定了信息交换的范围。一个粒子的邻域可以是整个群体,也可以由其周围的少数几个粒子构成,邻域拓扑决定了群体中粒子的相邻关系。三种主要的邻域拓扑:星状拓扑(也称全局邻域拓扑)、坏状拓扑和轮状拓扑。

        当邻域结构取为全局邻域结构时,粒子pi的局部极值gi成为全局极值,通常记为gbest。通过对以上三种邻域结构进行实验研究,Kennedy得出的结论是:使用全局邻域结构的PSO算法收敛速度较快,但容易陷入局部最优;使用环状邻域结构的PSO算法的收敛速度较慢,但能以较大的概率发现最优解;而使用轮状邻域结构的PSO算法效果较差。

//根据粒子的适应值更新个体极值(历史最优)并计算极值(全局最优)if (Mubiao_fun(qt.p[i].x) < Mubiao_fun(pbest[i].x)){for(int j=0;j<N;j++)pbest[i].x[j] =qt.p[i].x[j];}for (int j = 0; j<N; j++)gbest[j] = pbest[i].x[j];for (int j = 0; j < M; j++){if (Mubiao_fun(pbest[j].x) < Mubiao_fun(gbest)){for (int k = 0; k<N; k++)gbest[k] = pbest[j].x[k];}}

最后

C++运行PSO算法求解函数优化的主函数如下:

// main.cpp
#include <iostream>
#include <math.h>
#include <random>
#include<time.h>
using namespace std;
#include "Particle.h"
#include "Qunti.h"
#include "X.h"
double Mubiao_fun(double x[N])
{double f = 0.5 + (pow(sin(sqrt(x[0] * x[0] + x[N-1] * x[N - 1])), 2) - 0.5) / pow((1 + 0.001*pow((x[0] * x[0] + x[N - 1] * x[N - 1]),2)), 2);return f;
}
int main()
{std::cout << "Hello world!" << endl;double w = 0.9,Xmax = 100,Xmin = -100,Vmax = 3.0,Vmin = -3.0;//位置分量和速度的最大最小值int t=0,c1 = 2, c2 = 2,iteratortime = 4000;//t=0表示第一次迭代Qunti qt;double funvalue[M], gbest[N];//M个粒子对应的函数值数组X pbest[M];//pbesti表示粒子pi的个体极值;gi表示pi的局部极值for (int i = 0; i < M; i++){funvalue[i] = 0;//数组初始化}//第一步,群体粒子的初始化;std::default_random_engine random(time(NULL));static std::uniform_real_distribution<double> distribution1(Xmin, std::nextafter(Xmax, DBL_MAX));// C++11提供的实数均匀分布模板类static std::uniform_real_distribution<double> distribution2(Vmin, std::nextafter(Vmax, DBL_MAX));// C++11提供的实数均匀分布模板类for (int i = 0; i < M; i++){for (int j = 0; j < N; j++){qt.p[i].x[j] = distribution1(random); //群体粒子位置向量初始化qt.p[i].v[j] = distribution2(random);//群体粒子速度向量初始化pbest[i].x[j] = qt.p[i].x[j];funvalue[i] = Mubiao_fun(qt.p[i].x);}}int minlocation = 0;double minfunvalue = funvalue[0];for (int i = 0; i < M; i++){if (funvalue[i] < minfunvalue){minfunvalue = funvalue[i];minlocation = i;}}for(int j=0;j<N;j++)gbest[j] = qt.p[minlocation].x[j];qt.shuchu();for (int ite = 0; ite < iteratortime; ite++){for (int i = 0; i < M; i++){//更新每个粒子的速度和位置for (int j = 0; j < N; j++){static std::uniform_real_distribution<double> distribution3(0.0, std::nextafter(1.0, DBL_MAX));// C++11提供的实数均匀分布模板类qt.p[i].v[j] = w*qt.p[i].v[j] + c1*distribution3(random)*(pbest[i].x[j] - qt.p[i].x[j]) + c2*distribution3(random)*(gbest[j] - qt.p[i].x[j]);}for (int j = 0; j < N; j++){if (qt.p[i].v[j]> Vmax) qt.p[i].v[j] = Vmax;else if (qt.p[i].v[j] < Vmin) qt.p[i].v[j] = Vmin;}for (int j = 0; j < N; j++)//粒子速度越界调整{qt.p[i].x[j] += qt.p[i].v[j];}for (int j = 0; j < N; j++)//粒子位置越界调整{if (qt.p[i].x[j]> Xmax) qt.p[i].x[j] = Xmax;else if (qt.p[i].x[j] < Xmin) qt.p[i].x[j] = Xmin;}//根据粒子的适应值更新个体极值(历史最优)并计算极值(全局最优)if (Mubiao_fun(qt.p[i].x) < Mubiao_fun(pbest[i].x)){for(int j=0;j<N;j++)pbest[i].x[j] =qt.p[i].x[j];}for (int j = 0; j<N; j++)gbest[j] = pbest[i].x[j];for (int j = 0; j < M; j++){if (Mubiao_fun(pbest[j].x) < Mubiao_fun(gbest)){for (int k = 0; k<N; k++)gbest[k] = pbest[j].x[k];}}}if (ite == iteratortime - 1){cout << "迭代" << iteratortime << "次后的群体粒子如下:" << endl;qt.shuchu();}}std::cout << "最优解位置为:x=(";for (int j = 0; j < N; j++){if(j == N-1)std::cout << gbest[j]<<")"<<endl;else std::cout << gbest[j] << ",";}system("pause");return 0;
}

运行结果如下图所示:

PSO算法优化应用实例(2020.09.24)相关推荐

  1. 多益网络校招前端面经(2020.09.24)

    多益网络校招前端面经(2020.09.24) 面试平台 QQ视频通话 时长 大约半小时 过程 自我介绍 项目问题:项目中遇到的问题以及解决方式:在团队开发过程中个成员合作方式,遇到问题的解决方式 cs ...

  2. MAT之PSO:利用PSO算法优化二元函数,寻找最优个体适应度

    MAT之PSO:利用PSO算法优化二元函数,寻找最优个体适应度 目录 实现结果 设计代码 实现结果 设计代码 figure [x,y] = meshgrid(-5:0.1:5,-5:0.1:5); z ...

  3. python pso_利用python实现PSO算法优化二元函数

    python实现PSO算法优化二元函数,具体代码如下所示: import numpy as np import random import matplotlib.pyplot as plt from ...

  4. python二元函数如何编写_利用python实现PSO算法优化二元函数

    python实现PSO算法优化二元函数,具体代码如下所示: import numpy as np import random import matplotlib.pyplot as plt from ...

  5. 基于粒子群优化BP神经网络的预测 采用PSO算法优化bp网络实现预测

    基于粒子群优化BP神经网络的预测 采用PSO算法优化bp网络实现预测,源码注释详细,matlab实现,直接运行即可. ID:72100632211160748韩雅涵122

  6. PSO算法优化BP神经网络

    PSO算法和BP神经网络都是现在非常热门的两个算法,在各自的领域都担当着至关重要的作用,下面通过MATLAB中的一个实例来介绍一下如何将二者进行完美的结合,以发挥其最大优势: 1.在MATLAB的主界 ...

  7. 引入变异因素的PSO算法优化(一)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 引入变异的PSO算法 一.PSO是什么? 二.PSO的缺点? 总结 引入变异的PSO算法 一.PSO是什么? 粒子群算法Pa ...

  8. 粒子群算法优化PID,PSO,传递函数

    阅读前必看: 1.本代码基于MATLAB2018a版本,如果版本不同可能会报错. 2.如果运行时间过长,请观察迭代次数是否有变化. 3.此案例为原创案例,转载请注明出处. 4.如果此案例碰巧与您的研究 ...

  9. Matlab实现PSO算法(附上6个完整仿真源码)

    PSO(Particle Swarm Optimization)是一种优化算法,它模拟了鸟群或鱼群等动物的集体行为,通过群体智能的方式来解决优化问题.PSO算法最初由Kennedy和Eberhart在 ...

最新文章

  1. 修改 mysql 字符集_如何修改MySQL字符集
  2. poj 3481 平衡树
  3. 最大流最小费用java_最小费用最大流及算法
  4. Android在线开发工具 App Inventor
  5. 【转】ABAP内表数据和JSON格式互转
  6. 【机器学习】因子分解机(FM) 原理及在召回中的应用(python实现)
  7. 1虚拟地址,虚拟内存映射,系统调用本质,进程运行状态
  8. 腾讯视频P2P带宽节省率持续提升之路
  9. cl_ibase_ibintx_buf buffer class
  10. 实战经验:关于Oracle Delete数据后空间重用问题的测试
  11. linux 下测速时间分析
  12. sql2005关闭c2审核_C2审核–使用C2审核模式SQL Server审核和通用标准合规性
  13. Dell服务器RAID常用管理命令总结
  14. 如何搭建自己的第四方支付平台?
  15. 如何知道坦白说里面是谁给了自己评价?
  16. 微博html5版开视频怎么退出,微博怎么取消视频号?微博视频号怎么关闭
  17. 为Kong添加服务、路由和认证
  18. unity android光照贴图格式,Unity3D-光照贴图技术
  19. 黑苹果卡在白苹果不动_iphone5开机白屏中间黑苹果,卡住不动。
  20. AngularJS 控制器中处理DOM事件

热门文章

  1. 小迪渗透基础入门(壹)
  2. SQL注入攻击零距离
  3. HS6621 串口透传 模式 - [详解]
  4. 程序员为啥365天都背电脑包?看完答案后笑出声
  5. Eigen和Sophus 用法的详细介绍
  6. 前端局部自动刷新_javascript如何实现局部刷新?
  7. 使用Exchange同步联系人/日历/邮件
  8. 微信小程序购物车收货地址实现
  9. 树莓派换源(实测有效)
  10. 如何设计实现H5营销页面搭建系统