Feathersky 2007

 

流程图

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


初始化一群随机粒子(随机解)

//粒子的类

class CParticle

{

 

public:

 

     int nDimension;                    //维度

 

 

     double coordinate[MaxDimension]; //每个维度的坐标

 

//粒子i位置:xi=(xi1,xi2,xid),将xi代入适应函数f(xi)求适应值;

 

 

     double coordinateLimit[MaxDimension][2]; // 每个维度的坐标上下限

 

 

 

     double velocity[MaxDimension];         //每个维度的速度

 

     double velocityLimit[MaxDimension][2]; //每个维度的速度上下限

在每一维,粒子都有一个最大限制速度Vmax,如果

某一维的速度超过设定的Vmax ,那么这一维的速度

就被限定为Vmax 。( Vmax >0

 

 

 

 

    //个体的最优记录

     double pBest;

     double pBestCoordinate[MaxDimension]; //每个维度的坐标

 

 

 

     //更新速度所用参数   

     double w;

     double c1;

     double c2;

}

 

 

 

 

    

 

 

每次迭代中,粒子通过跟踪两个极值更新自己:

     -粒子本身找到的历史最后解(个体极值点pbest

     -整个种群目前找到的最好解(全局极值点gbest

 

     double Fitness(FitnessFunc pFunc,int N,double fChange=0)

     {

         double fitness=pFunc(coordinate,N,fChange);

 

         //记录个体最优

         if(fitness<pBest)

         {

              pBest=fitness;

 

              memcpy(pBestCoordinate,coordinate,nDimension*sizeof(double));

         }

 

         return fitness;

 

     }

 

 

 

需要计算粒子的适应值,以判断粒子位置距最优点的距离。

每次迭代中,根据适应度值更新pbestgbest

 

    粒子i的第n维速度和位置更新公式:

         vin=w*vin+c1*r1*(pbestin-xin)+c2*r2*(gbestn-xin)

   xin=xin+vin

   c1,c2学习因子,经验值取c1=c2=2,调节学习最大步长

   r1,r2两个随机数,取值范围(0,1),以增加搜索随机性

         w 惯性因子,非负数,调节对解空间的搜索范围

 

//更新速度   standard

     void UpdateVelocity1(double gBestCoordinate[])

     {  

 

         for(int i=0; i<nDimension; i++)

         {            

              velocity[i]=w*velocity[i]+c1*MyRand(0,1)*(pBestCoordinate[i]-coordinate[i]) + c2*MyRand(0,1)*(gBestCoordinate[i]-coordinate[i]);

         }

 

         //检测是否溢出

         CheckOverflow(velocity,velocityLimit);

     }

 

 

迭代中止条件:设置最大迭代次数或全局最优位置满足预定最小适应阈值。        

 

 

 

//粒子群的类

 

class CParticleGroup

{

 

public:

 

     int nPopulation;            //粒子数量

 

     CParticle * pParticles;     //保存粒子的数组

 

 

     //信息记录

     int    maxIteration;                  //

     int    iteration;                     //第几代

 

     int    gBestIndex;                     //当前最优的particle对应的索引  

     double gBest;                          //当前最优的particle对应的函数值

     double gBestCoordinate[MaxDimension]; //当前最优的particle对应的坐标值

     double gAverageFitness;                //平均适应度

 

 

     double environmentChangeThreshold;

     }

 

 

 

     初始化各粒子初始位置,在有效范围内随机选数

 

     void Initial(int population,int dimension, double w, double c1,double c2, double coordinateLimit[][2],double velocityLimit[][2])

     {

         nPopulation=population;

 

         if(pParticles) free(pParticles);

 

         pParticles=(CParticle *)malloc(nPopulation*sizeof(CParticle));

 

         for(int i=0; i<nPopulation; i++) pParticles[i].Initial(dimension,w,c1,c2,coordinateLimit,velocityLimit);

 

         iteration=0;

         gBest=0;

 

         environmentChangeThreshold=1.0;

 

     }

 

 

     double Run(FitnessFunc pFunc,int N,double fChange=0)

     {

 

         iteration++;

 

         double lastgBest=gBest;                   //记录上一次全局最优

         double lastAverageFitness=gAverageFitness;   //记录上一次平均适应度

 

 

         gBest=MAXNUM;   

 

         double totalFitness=0;

 

         for(int i=0; i<nPopulation; i++)

         {

              pParticles[i].Run();

 

              double fit=pParticles[i].Fitness(pFunc,N,fChange);      计算各粒子的适应度值

 

 

              totalFitness+=fit;

 

              if(gBest>fit)        记录各粒子的个体极值点位置 记录最佳适应度值 找出全局极值和相应的序号  

 

 

              {

 

                   gBestIndex=i;

 

                   gBest=fit;             

                  

                   memcpy(gBestCoordinate,pParticles[i].coordinate,MaxDimension*sizeof(double));

 

              }

         }

 

         gAverageFitness=totalFitness/nPopulation;

 

 

      更新各粒子速度

 

         for( i=0; i<nPopulation; i++)

         {

              pParticles[i].UpdateVelocity3(gBestCoordinate,iteration,maxIteration);     

         }

 

 

 

 

         //检测环境是否发生变化

         double gBestchange=abs(lastgBest-gBest)/(abs(lastgBest)+0.0001);

         double gAveragechange=abs(lastAverageFitness-gAverageFitness)/(abs(lastAverageFitness)+0.0001);

 

         //若变化,更新粒子参数,使粒子群在上次子群附近加一个随机变化后重新开始迭代

         if(lastgBest<gBest && gBestchange>environmentChangeThreshold && gAveragechange>environmentChangeThreshold)

         {

              for( i=0; i<nPopulation; i++)

              {

                   pParticles[i].w=0.9;

                   pParticles[i].pBest=MAXNUM;

 

                           

                   for(int k=0; k<pParticles[0].nDimension; k++)

                   {

                       double low=pParticles[0].coordinateLimit[k][0];

                       double up=pParticles[0].coordinateLimit[k][1];

 

                       pParticles[i].coordinate[k]+=MyRand(0,(up-low)/10.0);                

                       pParticles[i].coordinate[k]-=MyRand(0,(up-low)/10.0);            

             

                   }

              }            

         }

 

         return gBest;

 

     }

 

 

 

对于第一方面,本程序采用如下检测

 

         //检测环境是否发生变化

         double gBestchange=abs(lastgBest-gBest)/(abs(lastgBest)+0.0001); 最优值的变换

         double gAveragechange=abs(lastAverageFitness-gAverageFitness)/(abs(lastAverageFitness)+0.0001); 评价值的变化

 

        

         if(lastgBest<gBest && gBestchange>environmentChangeThreshold && gAveragechange>environmentChangeThreshold)

 

对于第2方面改进,本程序采用

更新粒子参数,使粒子群在上次子群附近加一个随机变化后重新开始迭代

for( i=0; i<nPopulation; i++)

              {

                   pParticles[i].w=0.9;

                   pParticles[i].pBest=MAXNUM;

 

                           

                   for(int k=0; k<pParticles[0].nDimension; k++)

                   {

                       double low=pParticles[0].coordinateLimit[k][0];

                       double up=pParticles[0].coordinateLimit[k][1];

 

                       pParticles[i].coordinate[k]+=MyRand(0,(up-low)/10.0);                

                       pParticles[i].coordinate[k]-=MyRand(0,(up-low)/10.0);            

             

                   }

              }  

    

 

         

 

posted on 2008-12-18 13:16  feathersky  阅读(520)  评论(0编辑  收藏  举报