简介以及基本PSO的实现:http://blog.csdn.net/fovwin/article/category/1256709
相对于基本PSO,标准PSO加入了惯性权重系数W,W代表者粒子群对全局空间的搜索能力和局部收敛速度的权衡。
也就是说,若惯性权重W越大,速度更新式子的第一项所占的比重,即速度惯性项,比较大。粒子就会比较不受约束,可以冲来冲去。不受世俗的约束,也就不容易变“俗”(陷入局部极小点出不来);若惯性权重W越小,速度更新式子的后两项所占的比重,即个体历史极值和全局最优解,比较大。粒子被自己的经验和社会的世俗所约束了,听“妈妈”的话,当然人生走的顺畅,但是你一般在你20岁就知道你后辈子的路,即容易陷入局部极小点出不来——过早收敛早熟。
所以一般在一开始一般设置较大的W值,让它充分搜索全局空间(就像小时候不听话,有时候老爸老妈说了这样不行,我们也会自己试了再说,呵呵),到粒子迭代的后半阶段,设置W较小,可以提高收敛速度(后半辈子大部分按经验活着)。
本文的W按照如下设置:
-
- #define W_START 1.4
- #define W_END 0.4
- #define W_FUN (W_START-(W_START-W_END)*pow((double)cur_n/ITE_N,2))
当然,我们可以有的别的设置公式,但是大体呈现下降的趋势,也可以用模糊控制规则(下下步实现目标)来设置~~~
至于作用效果么,比基本的能更快早到最优解~~~不过木有pp,1.X版再说~~~
相对与Verson 0.0版减少好几个函数,第一版初级阶段,主要为了学习原理,Version 1.0版代码更加简洁,将pso.c和pso.h独立出来,好以后扩展,通过define来设置你的待优化函数(下一步尝试多种诡异的函数,有的还蛮漂亮的),但是还要完善,但是加入了扩展适应度函数的框架~~~将初始化第一次计算P,X和之后的合并为一体~~~
main.c
- #include "pso.h"
- #include "stdio.h"
-
-
- int main(int argc, const char *argv[])
- {
- cur_n=0;
- RandInitofSwarm();
- while(cur_n++ != ITE_N)
- {
- UpdatePandGbest();
- UpdateofVandX();
- }
-
- getchar();
- return 0;
- }
pso.h
- #ifndef _PSO_H_
- #define _PSO_H_
-
-
- #define TEST 0
- #define GOLDSTEIN_PRICE 0
- #define SCHAFFER 1
- #define HANSEN 0
- #define NEEDLE 0
-
- #define Dim 2 //粒子维度
- #define PNum 20 //种群规模
- #define ITE_N 50 //最大迭代次数
- int cur_n;
-
-
- #define W_START 1.4
- #define W_END 0.4
- #define W_FUN (W_START-(W_START-W_END)*pow((double)cur_n/ITE_N,2))
-
- struct PARTICLE
- {
- double X[Dim];
- double P[Dim];
- double V[Dim];
- double Fitness;
- } particle;
-
- struct SWARM
- {
- struct PARTICLE Particle[PNum];
- int GBestIndex;
- double GBest[Dim];
- double C1;
- double C2;
- double Xup[Dim];
- double Xdown[Dim];
- double Vmax[Dim];
- } swarm;
-
- void RandInitofSwarm(void);
- void UpdateofVandX(void);
- void UpdatePandGbest(void);
-
- #endif
pso.c
- #include "stdio.h"
- #include "stdlib.h"
- #include "time.h"
- #include "math.h"
- #include "pso.h"
-
-
-
- void RandInitofSwarm(void)
- {
- int i, j;
-
- swarm.C1 = 2.0;
- swarm.C2 = 2.0;
- for(j = 0; j < Dim; j++)
- {
- swarm.Xdown[j] = -10;
- swarm.Xup[j] = 10;
- swarm.Vmax[j] = 0.1;
- }
-
- srand((unsigned)time(NULL));
- for(i = 0; i < PNum; i++)
- {
- for(j = 0; j < Dim; j++)
- {
- swarm.Particle[i].X[j] = rand() / (double)RAND_MAX * (swarm.Xup[j] - swarm.Xdown[j]) + swarm.Xdown[j];
- swarm.Particle[i].V[j] = rand() / (double)RAND_MAX * swarm.Vmax[j] * 2 - swarm.Vmax[j];
- }
- }
- }
-
- static double ComputAFitness(double X[])
- {
-
-
-
-
- #if TEST
- return X[0]*X[0]+X[1]*X[1]+3;
- #endif
-
-
-
-
-
- #if GOLDSTEIN_PRICE
- return (1+pow(X[0]+X[1]+1,2)*(19-14*X[0]+3*pow(X[0],2)-14*X[1]+6*X[0]*X[1]+ 3*pow(X[1],2))*(30+pow((2*X[0]-3*X[1]),2)*\
- (18-32*X[0]+12*pow(X[0],2)+48*X[1]-36*X[0]*X[1] + 27*pow(X[1],2))));
- #endif
-
-
-
-
-
- #if SCHAFFER
-
-
- return -1*(0.5-(sin(sqrt(X[0]*X[0]+X[1]*X[1]))*\
- sin(sqrt(X[0]*X[0]+X[1]*X[1]))-0.5)/pow(( 1+0.001*(X[0]*X[0]+X[1]*X[1])),2));
-
- #endif
-
-
-
-
-
-
-
-
-
-
- #if HANSEN
- int i;
- double temp1=0,temp2=0;
- double hansenf=0;
- for (i=1;i <= 5;i++)
- {
- temp1+=i*cos((i-1)*X[0]+i);
- temp2+=i*cos((i-1)*X[1]+i);
- }
- hansenf=-1*temp1*temp2;
-
- return hansenf;
- #endif
-
-
-
-
-
-
-
-
-
- #if NEEDLE
- return -1*pow((3/(0.05+pow(X[0]-1,2)+pow(X[1]-1,2))),2);
- #endif
-
- }
-
-
- void UpdateofVandX(void)
- {
- int i, j;
- srand((unsigned)time(NULL));
- for(i = 0; i < PNum; i++)
- {
- for(j = 0; j < Dim; j++)
- swarm.Particle[i].V[j] = W_FUN * swarm.Particle[i].V[j] +
- rand() / (double)RAND_MAX * swarm.C1 * (swarm.Particle[i].P[j] - swarm.Particle[i].X[j]) +
- rand() / (double)RAND_MAX * swarm.C2 * (swarm.GBest[j] - swarm.Particle[i].X[j]);
- for(j = 0; j < Dim; j++)
- {
- if(swarm.Particle[i].V[j] > swarm.Vmax[j])
- swarm.Particle[i].V[j] = swarm.Vmax[j];
- if(swarm.Particle[i].V[j] < -swarm.Vmax[j])
- swarm.Particle[i].V[j] = -swarm.Vmax[j];
- }
-
- for(j = 0; j < Dim; j++)
- {
- swarm.Particle[i].X[j] += swarm.Particle[i].V[j];
- if(swarm.Particle[i].X[j] > swarm.Xup[j])
- swarm.Particle[i].X[j] = swarm.Xup[j];
- if(swarm.Particle[i].X[j] < swarm.Xdown[j])
- swarm.Particle[i].X[j] = swarm.Xdown[j];
- }
- }
- }
-
-
- void UpdatePandGbest(void)
- {
- int i, j;
-
- for (i = 0; i < PNum; i++)
- {
- if (swarm.Particle[i].Fitness < ComputAFitness(swarm.Particle[i].P))
- {
- for(j = 0; j < Dim; j++)
- {
- swarm.Particle[i].P[j] = swarm.Particle[i].X[j];
- }
- }
- }
-
- for(i = 0; i < PNum; i++)
- if(ComputAFitness(swarm.Particle[i].P) < ComputAFitness(swarm.Particle[swarm.GBestIndex].P))
- swarm.GBestIndex = i;
- for(j = 0; j < Dim; j++)
- {
- swarm.GBest[j] = swarm.Particle[swarm.GBestIndex].P[j];
- }
- printf("The %dth iteraction.\n",cur_n);
- printf("GBestIndex:%d \n",swarm.GBestIndex );
- printf("GBest:" );
- for(j=0;j<Dim;j++)
- {
- printf("%.4f ,",swarm.GBest[j]);
- }
- printf("\n" );
- printf("Fitness of GBest: %f \n\n",ComputAFitness(swarm.Particle[swarm.GBestIndex].P));
- }