粒子群算法简单实现

PSO算法相关定义

PSO中的每个粒子P包含两个向量: x, v

o位置向量x:粒子在解空间中的当前位置: x[x1, x2, ..., xdim]

o速度向量v:粒子在解空间中的飞行速度: v[v1, v2, ..., vdim]

pBest :粒子自身的历史最优位置

gBest :群体全局最优向量

粒子速度与位置更新:

P.v=omega*P.v+c1*r1*(P.pBest-P.x)+c2*r2*(gBest-P.x);

P.x=P.x+P.v;

其中omega为惯性权重,c1,c2为学习因子,r1,r2为[0, 1]上的随机数

算法流程:

粒子群算法简单实现粒子群算法简单实现

实例测试:

// 测试实例1
// f=x1*x1+x2*x2+x3*x3, 求fmin
// N=40, G=500
// -10<=x<=-4
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
const int dim=3;
const int N=40;
const int G=500;
const int low=-10, high=-4, wid=high-low;;
const double INF=99999.9;
double omega=0.729;
double c1=1.49445, c2=c1;
vector<double> gBest;
// 定义粒子
struct pp{
    vector<double> x;
    vector<double> v;
    vector<double> pBest;
    double value;
}P[N];
// 比较函数
bool cmp(struct pp A, struct pp B) {
    return A.value<B.value;
}
int random() {
    int temp=rand()%(wid+1);
    return low+temp;
}
// 目标函数(适应度函数)
double f(struct pp &P) {
    double vl=0;
    for (int i=0; i<dim; i++)
        vl+=P.x[i]*P.x[i];
    return vl;
}
// 更新操作
void update(struct pp &P) {
    double r1=rand()/double(RAND_MAX);
    double r2=rand()/double(RAND_MAX);
    //P.v=omiga*P.v+c1*r1*(P.pBest-P.x)+c2*r2*(gBest-P.x);
    for (int i=0; i<dim; i++)
        P.v[i]=omega*P.v[i]+c1*r1*(P.pBest[i]-P.x[i])+c2*r2*(gBest[i]-P.x[i]);
    //P.x=P.x+P.v;
    for (int i=0; i<dim; i++) {
        P.x[i]=P.x[i]+P.v[i];
        if (P.x[i]>high)
            P.x[i]=high;
        else if (P.x[i]<low)
            P.x[i]=low;
    }
}
// 初始化
void Init() {
    srand((unsigned)time(NULL));
    for (int i=0; i<N; i++) {
        for (int j=0; j<dim; j++) {
            P[i].v.push_back(random());
            P[i].x.push_back(random());
        }
        P[i].pBest=P[i].x;
        P[i].value=INF;
        P[i].value=min(f(P[i]), P[i].value);
    }
    sort(P, P+N, cmp);
    gBest=P[0].pBest;
}
// 运行
void Run() {
    for (int i=0; i<G; i++) {
        for (int j=0; j<N; j++) {
            update(P[j]);
            double temp=f(P[j]);
            if (temp<P[j].value) {
                P[j].pBest=P[j].x;
                P[j].value=temp;
            }
            if (temp<P[0].value)
                gBest=P[j].pBest;
        }
        sort(P, P+N, cmp);
    }
    for (int i=0; i<dim; i++)
        printf("x%d = %.2f\n", i+1, gBest[i]);
}
// 测试
int main() {
    Init();
    Run();
    return 0;
}
/**********输出**********/
x1 = -4.00
x2 = -4.00
x3 = -4.00

//实例测试2
// f=sinx1+cosx2-cos(2*x3),求fmin
// -10<=x<=-4
// 目标函数(适应度函数)
double f(struct pp &P) {
    double vl=0;
    vl=sin(P.x[0])+cos(P.x[1])-cos(2*P.x[2]);
    return vl;
}
/**********输出**********/
x1 = -7.85
x2 = -9.42
x3 = -6.28
或
x1 = -7.85
x2 = -9.42
x3 = -9.42
对于cos(2*x3)来说周期为pie=3.14,因此两组输出等价

BY DXH924

2019.3.15