源文件main.cpp
#include "PSO.h";
const int D=10;//维数,即自变量x的个数,const代表是常量,在这个程序中值保持不变,不被修改
const int N=100;//粒子数量,即解组的个数,矩阵中一行代表一组解
const int iters=200;//总迭代次数
const double c1=2;//控制与自身的学习速度
const double c2=2;//控制与群体的学习速度
double w=0.9;
double w_max=0.9,w_min=0.4;
double x_max=20,x_min=-20,v_max=10,v_min=-10;
int i,j,ii;
//初始化种群与每个粒子速度
Matrix<double,N,D>x;
Matrix<double,N,D>v;
Matrix<double,N,D>p;
double g_best;
Matrix<double,N,1>p_best;
Matrix<double,1,D>g;
void xxx()
{
std::default_random_engine num_rand;
int i,j;
for(i=0; i<N; i+=1)
{
for(j=0; j<D; j+=1)
{
x(i,j)=num_rand()%(NNN+1)/(double)(NNN+1)*(x_max-x_min)+x_min;
v(i,j)=num_rand()%(NNN+1)/(double)(NNN+1)*(v_max-v_min)+v_min;
}
}
p=x;
for(i=0;i<N;i+=1)
{
p_best(i)=f(x.row(i));//计算每一组自变量对于目标函数值
}
int index=0;
g_best=p_best.minCoeff();
for(i=0;i<N;i+=1)
{
if(g_best==p_best(i))
{
index=i;//确定最优值的索引
}
}
g=x.row(index);//返回最优值对于自变量组
}
Matrix<double,1,iters>gb;
double x0,d_p,d_g;
//粒子群算法开始迭代
void iter()
{
for(i=0;i<iters;i+=1)
{
for(j=0;j<N;j+=1)
{
x0=f(x.row(j));
d_p=x0-p_best(j);//看看当前第j个与p_best中存储的之前的个体哪个好
if(d_p<0)
{
p_best(j)=x0;//替换
p.row(j)=x.row(j);
}
d_g=p_best(j)-g_best;//与群体最优对比
if(d_g<0)
{
g_best=p_best(j);
g=p.row(j);
}
v.row(j)=w*v.row(j)+c1*num_rand()*(p.row(j)-x.row(j))+c2*num_rand()*(g-x.row(j));
x.row(j)=x.row(j)+v.row(j);
//蚁群算法公式
//判断是否超出边界
for(ii=0;ii<D;ii+=1)
{
if(v(j,ii)>v_max||v(j,ii)<v_min)
{
v(j,ii)=num_rand()*(v_max-v_min)+v_min;
}
if(x(j,ii)>x_max||x(j,ii)<x_min)
{
x(j,ii)=num_rand()*(x_max-x_min)+x_min;
}
}
}
gb(i)=g_best;
w=(w_max-w_min)*(iters-i)/iters+w_min;
}
}
int main()
{
srand(unsigned(time(NULL)));
xxx();
iter();
cout<<g_best<<endl;
return 0;
}
头文件PSO.h
#ifndef PSO_H_INCLUDED
#define PSO_H_INCLUDED
#include <iostream>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<random>
#include<ctime>
#include<Eigen/Dense>
#include<time.h>
#define NNN 99
using namespace Eigen;
using namespace std;
double num_rand()
{
return rand()%(NNN+1)/(double)(NNN+1);
// std::default_random_engine e;
// return e.min()%(NNN+1)/(double)(NNN+1);
}
double f(MatrixXd xx)
{
xx=xx.array().square();
return xx.sum();
}
#endif // PSO_H_INCLUDED
运行结果:
1.24673e-08
Process returned 0 (0x0) execution time : 0.644 s
Press any key to continue.
可见仅迭代200次,精度可达到e-08,时间复杂度也低;