Last active
May 10, 2021 09:37
-
-
Save fattiger00/cf7e285ce718744291f5dae9262e405d to your computer and use it in GitHub Desktop.
PSO ALGORITHM by cpp.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<iostream> | |
#include<random> | |
#include<math.h> | |
using namespace std; | |
//群体中的粒子数 | |
#define SWARMSIZE 10 | |
//值域大小 值域为:x为[0,SPACESIZE] | |
#define SPACESIZE 2 | |
//迭代次数 | |
static int generNum = 100; | |
//粒子 | |
struct Particle | |
{ | |
double present;//粒子的位置 | |
double fitness;//适应度 | |
double pbest;//个体的最佳位置 | |
double vel;//速度 | |
}pars[SWARMSIZE];//定义粒子群 | |
//防止粒子直接跨过最优解,粒子的最大速度 | |
static double vMax = 0.1; | |
//群体最佳 | |
static double gbest = 0; | |
//目标函数 | |
double fitnessFunc(double x){ | |
return sin(x); | |
} | |
double rdNum[10000]; | |
double randomNum(int upper = 9,int times = 6){ | |
static default_random_engine e; | |
e.seed(time(0)); | |
static uniform_int_distribution<unsigned> u(1,9); | |
//产生0-1的double随机数 | |
double t = 0; | |
for(int i = 0 ; i < generNum*2+100 ; i ++){ | |
for(int j = 0 ; j < times ; j++){ | |
t += pow(10,j)*u(e); | |
} | |
t = t / pow(10,times); | |
rdNum[i] = t; | |
t = 0; | |
} | |
return t; | |
} | |
void initPars(){ | |
randomNum(); | |
for(int i = 0 ; i < SWARMSIZE ; i++){ | |
//给粒子们一个初始位置 | |
pars[i].present = SPACESIZE * rdNum[generNum*2+i*2+1]; | |
//给粒子们一个初始速度 0~0.05 | |
pars[i].vel = rdNum[generNum*2+i*2]/ 20; | |
pars[i].pbest = pars[i].present; | |
//找到粒子群中适应度最大的粒子,即为gbest | |
pars[i].fitness = fitnessFunc(pars[i].present); | |
if(pars[i].fitness > fitnessFunc(gbest)) gbest = pars[i].present; | |
} | |
} | |
void PSO(){ | |
for(int i = 0 ; i < generNum ; i++){ | |
for(int j = 0 ; j < SWARMSIZE ; j++){ | |
//更新速度 | |
double par = 2*rdNum[j*2]*(pars[j].pbest - pars[j].present); | |
double glo = 2*rdNum[j*2+1]*(gbest - pars[j].present); | |
double nextVel = pars[j].vel + par + glo; | |
//限制步长 | |
if(abs(nextVel) > vMax) { | |
pars[j].vel = nextVel > 0 ? vMax : -1*vMax; | |
} | |
else{ | |
pars[j].vel = nextVel; | |
} | |
//更新位置 | |
double nextPos = pars[j].present + pars[j].vel; | |
if(nextPos > SPACESIZE ) { | |
nextPos = SPACESIZE; | |
} | |
if(nextPos < 0){ | |
nextPos = 0; | |
} | |
pars[j].present = nextPos; | |
} | |
for(int j = 0 ; j < SWARMSIZE ; j++){ | |
//更新个体的适应度 | |
pars[j].fitness = fitnessFunc(pars[i].present); | |
//更新个体最优解和全局最优解 | |
if(pars[j].fitness > fitnessFunc(pars[j].pbest)){ | |
pars[j].pbest = pars[j].present; | |
} | |
if(fitnessFunc(pars[j].pbest) > fitnessFunc(gbest)) gbest = pars[j].present; | |
} | |
} | |
printf("迭代%d次,全局最优解在:%lf,值为%lf\n",generNum,gbest,fitnessFunc(gbest)); | |
} | |
int main(){ | |
initPars(); | |
PSO(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment