test_pso.cpp
Go to the documentation of this file.
00001 /*
00002  * reference http://www.cnblogs.com/lyrichu/p/6151272.html
00003  * by lyrichu
00004  * 2016-12-09
00005  */
00006 #include<stdio.h>
00007 #include<stdlib.h>
00008 #include<math.h>
00009 #include<time.h>
00010 #include<unistd.h>
00011 #define c1 1.49445 //加速度因子一般是根据大量实验所得
00012 #define c2 1.49445
00013 #define maxgen 1001  // 迭代次数
00014 #define sizepop 20 // 种群规模
00015 #define popmax 5.12 // 个体最大取值
00016 #define popmin -5.12 // 个体最小取值
00017 #define Vmax 1 // 速度最大值
00018 #define Vmin -1 //速度最小值
00019 #define dim 2 // 粒子的维数
00020 #define PI 3.1415926 //圆周率
00021 
00022 double pop[sizepop][dim]; // 定义种群数组
00023 double V[sizepop][dim]; // 定义种群速度数组
00024 double fitness[sizepop]; // 定义种群的适应度数组
00025 double result[maxgen];  //定义存放每次迭代种群最优值的数组
00026 double pbest[sizepop][dim];  // 个体极值的位置
00027 double gbest[dim]; //群体极值的位置
00028 double fitnesspbest[sizepop]; //个体极值适应度的值
00029 double fitnessgbest; // 群体极值适应度值
00030 double genbest[maxgen][dim]; //每一代最优值取值粒子
00031 
00032 //适应度函数
00033 double func(double * arr)
00034 {
00035     double x = *arr; //x 的值
00036     double y = *(arr+1); //y的值
00037     double fitness = -(20+x*x+y*y-10*cos(2*PI*x)-10*cos(2*PI*y));
00038     return fitness;
00039 
00040 }    
00041 // 种群初始化
00042 void pop_init(void)
00043 {
00044     for(int i=0;i<sizepop;i++)
00045     {
00046         for(int j=0;j<dim;j++)
00047         {
00048             pop[i][j] = (((double)rand())/RAND_MAX-0.5)*4; //-2到2之间的随机数
00049             V[i][j] = ((double)rand())/RAND_MAX-0.5; //-0.5到0.5之间
00050         }
00051         fitness[i] = func(pop[i]); //计算适应度函数值
00052     }
00053 }
00054 // max()函数定义
00055 double * max(double * fit,int size)
00056 {
00057     int index = 0; // 初始化序号
00058     double max = *fit; // 初始化最大值为数组第一个元素
00059     static double best_fit_index[2];
00060     for(int i=1;i<size;i++)
00061     {
00062         if(*(fit+i) > max)
00063             max = *(fit+i);
00064             index = i;
00065     }
00066     best_fit_index[0] = index;
00067     best_fit_index[1] = max;
00068     return best_fit_index;
00069 
00070 }
00071 // 迭代寻优
00072 void PSO_func(void)
00073 {
00074     pop_init();
00075     double * best_fit_index; // 用于存放群体极值和其位置(序号)
00076     best_fit_index = max(fitness,sizepop); //求群体极值
00077     int index = (int)(*best_fit_index);
00078     // 群体极值位置
00079     for(int i=0;i<dim;i++)
00080     {
00081         gbest[i] = pop[index][i];
00082     }
00083     // 个体极值位置
00084     for(int i=0;i<sizepop;i++)
00085     {
00086         for(int j=0;j<dim;j++)
00087         {
00088             pbest[i][j] = pop[i][j];
00089         }
00090     }
00091     // 个体极值适应度值
00092     for(int i=0;i<sizepop;i++)
00093     {
00094         fitnesspbest[i] = fitness[i];
00095     }
00096     //群体极值适应度值
00097     double bestfitness = *(best_fit_index+1);
00098     fitnessgbest = bestfitness;
00099 
00100     //迭代寻优
00101     for(int i=0;i<maxgen;i++)
00102     {
00103         for(int j=0;j<sizepop;j++)
00104         {
00105             //速度更新及粒子更新
00106             for(int k=0;k<dim;k++)
00107             {
00108                 // 速度更新
00109                 double rand1 = (double)rand()/RAND_MAX; //0到1之间的随机数
00110                 double rand2 = (double)rand()/RAND_MAX;
00111                 V[j][k] = V[j][k] + c1*rand1*(pbest[j][k]-pop[j][k]) + c2*rand2*(gbest[k]-pop[j][k]);
00112                 if(V[j][k] > Vmax)
00113                     V[j][k] = Vmax;
00114                 if(V[j][k] < Vmin)
00115                     V[j][k] = Vmin;
00116                 // 粒子更新
00117                 pop[j][k] = pop[j][k] + V[j][k];
00118                 if(pop[j][k] > popmax)
00119                     pop[j][k] = popmax;
00120                 if(pop[j][k] < popmin)
00121                     pop[j][k] = popmin;
00122             }
00123             fitness[j] = func(pop[j]); //新粒子的适应度值
00124             //printf(cur pos(%lf,%lf).\n",fitness[j],genbest[best_gen_number][0],genbest[best_gen_number][1]);
00125             if(j == 0) {
00126                 printf("%d %lf\n", i, fitnessgbest);
00127             }
00128         }
00129         for(int j=0;j<sizepop;j++)
00130         {
00131             // 个体极值更新
00132             if(fitness[j] > fitnesspbest[j])
00133             {
00134                 for(int k=0;k<dim;k++)
00135                 {
00136                     pbest[j][k] = pop[j][k];
00137                 }
00138                 fitnesspbest[j] = fitness[j];
00139             }
00140             // 群体极值更新
00141             if(fitness[j] > fitnessgbest)
00142             {
00143                 for(int k=0;k<dim;k++)
00144                     gbest[k] = pop[j][k];
00145                 fitnessgbest = fitness[j];
00146             }
00147         }
00148         for(int k=0;k<dim;k++)
00149         {
00150             genbest[i][k] = gbest[k]; // 每一代最优值取值粒子位置记录
00151         }
00152         result[i] = fitnessgbest; // 每代的最优值记录到数组
00153         //sleep(1);
00154     }
00155 }
00156 
00157 // 主函数
00158 int main(void)
00159 {
00160     clock_t start,finish; //程序开始和结束时间
00161     start = clock(); //开始计时
00162     srand((unsigned)time(NULL)); // 初始化随机数种子
00163     PSO_func();
00164     double * best_arr;
00165     best_arr = max(result,maxgen);
00166     int best_gen_number = *best_arr; // 最优值所处的代数
00167     double best = *(best_arr+1); //最优值
00168     printf("迭代了%d次,在第%d次取到最优值,最优值为:%lf.\n",maxgen,best_gen_number+1,best);
00169     printf("取到最优值的位置为(%lf,%lf).\n",genbest[best_gen_number][0],genbest[best_gen_number][1]);
00170     finish = clock(); //结束时间
00171     double duration = (double)(finish - start)/CLOCKS_PER_SEC; // 程序运行时间
00172     printf("程序运行耗时:%lf\n",duration);
00173     return 0;
00174 }


test_statistic
Author(s):
autogenerated on Thu Jun 6 2019 18:52:37