V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
l91liliang
V2EX  ›  C

小白求问,这个用 C 写的粒子群算法(PSO)有什么问题。

  •  
  •   l91liliang · Dec 13, 2016 · 3076 views
    This topic created in 3429 days ago, the information mentioned may be changed or developed.

    f(3)函数总是计算错误

    `//粒子群 PSO 算法

    #include<stdio.h> #include<math.h> #include<time.h> #include<stdlib.h> #define P_num 200 //粒子数目
    #define dim 50 #define low -512 //搜索域范围 #define high 512 #define iter_num 1000 #define V_max 20 //速度范围 #define c1 2 #define c2 2 #define w 0.5 #define alp 1 double particle[P_num][dim]; //个体集合 double particle_loc_best[P_num][dim]; //每个个体局部最优向量 double particle_loc_fit[P_num]; //个体的局部最优适应度,有局部最优向量计算而来 double particle_glo_best[dim]; //全局最优向量 double gfit; //全局最优适应度,有全局最优向量计算而来
    double particle_v[P_num][dim]; //记录每个个体的当前代速度向量 double particle_fit[P_num]; //记录每个粒子的当前代适应度

    double f1(double a[]) { int i; double sum=0.0; for(i=0; i<dim; i++) { sum+=a[i]*a[i]; } return sum; }

    double f2(double a[]) { int i; double sum=0.0; for(i=0;i<dim;i++) { sum=(1+(a[i]+a[i+1]+1)(a[i]+a[i+1]+1)(19-14a[i]+3a[i]a[i]-14a[i+1]+6a[i]a[i+1]+3a[i+1]a[i+1]))(30+(2a[i]-3a[i+1])(2a[i]-3a[i+1])(18-32a[i]+12a[i]a[i]+48a[i+1]-36a[i]a[i+1]+27a[i+1]*a[i+1])); } return sum; }

    double f3(double a[]) { int i; double sum=0.0; for(i=0;i<dim;i++) { sum+=-a[i]sin(sqrt(abs(a[i]))); } return sum; } double fitness(double a[]) //适应度函数 { return f2(a); } void initial() { int i,j; for(i=0; i<P_num; i++) //随即生成粒子 { for(j=0; j<dim; j++) { particle[i][j] = low+(high-low)1.0rand()/RAND_MAX; //初始化群体 particle_loc_best[i][j] = particle[i][j]; //将当前最优结果写入局部最优集合 particle_v[i][j] = -V_max+2V_max1.0rand()/RAND_MAX; //速度 } } for(i=0; i<P_num; i++) //计算每个粒子的适应度 { particle_fit[i] = fitness(particle[i]); particle_loc_fit[i] = particle_fit[i]; } gfit = particle_loc_fit[0]; //找出全局最优 j=0; for(i=1; i<P_num; i++) { if(particle_loc_fit[i]<gfit) { gfit = particle_loc_fit[i]; j = i; } } for(i=0; i<dim; i++) //更新全局最优向量 { particle_glo_best[i] = particle_loc_best[j][i]; } } void renew_particle() { int i,j; for(i=0; i<P_num; i++) //更新个体位置生成位置 { for(j=0; j<dim; j++) { particle[i][j] += alpparticle_v[i][j]; if(particle[i][j] > high) { particle[i][j] = high; } if(particle[i][j] < low) { particle[i][j] = low; } } } } void renew_var() { int i, j; for(i=0; i<P_num; i++) //计算每个粒子的适应度 { particle_fit[i] = fitness(particle[i]); if(particle_fit[i] < particle_loc_fit[i]) //更新个体局部最优值 { particle_loc_fit[i] = particle_fit[i]; for(j=0; j<dim; j++) // 更新局部最优向量 { particle_loc_best[i][j] = particle[i][j]; } } } for(i=0,j=-1; i<P_num; i++) //更新全局变量 { if(particle_loc_fit[i]<gfit) { gfit = particle_loc_fit[i]; j = i; } } if(j != -1) { for(i=0; i<dim; i++) //更新全局最优向量
    { particle_glo_best[i] = particle_loc_best[j][i]; } } for(i=0; i<P_num; i++) //更新个体速度 { for(j=0; j<dim; j++) { particle_v[i][j]=w
    particle_v[i][j]+ c11.0rand()/RAND_MAX*(particle_loc_best[i][j]-particle[i][j])+ c21.0rand()/RAND_MAX*(particle_glo_best[j]-particle[i][j]); if(particle_v[i][j] > V_max) { particle_v[i][j] = V_max; } if(particle_v[i][j] < -V_max) { particle_v[i][j] = -V_max; } } } } int main() { freopen("result.txt","a+",stdout); int i=0; srand((unsigned)time(NULL)); initial(); while(i < iter_num) { renew_particle(); renew_var(); i++; } printf("粒子个数:%d\n",P_num); printf("维度为:%d\n",dim); printf("最优值为%.10lf\n", gfit); return 0; }`

    Supplement 1  ·  Dec 13, 2016

    //Part 1 #include<stdio.h>

    #include<math.h>

    #include<time.h>

    #include<stdlib.h>

    #define P_num 50 //粒子数目,m

    #define dim 20 //粒子维度,n

    #define low -500 //搜索域范围

    #define high 500

    #define iter_num 1000 //迭代次数,k

    #define V_max 20 //速度范围

    #define c1 2

    #define c2 2

    //#define w 0.5

    #define wmax 0.9

    #define wmin 0.4

    double particle[P_num][dim]; //个体集合

    double particle_loc_best[P_num][dim]; //每个个体局部最优向量

    double particle_loc_fit[P_num]; //个体的局部最优适应度,有局部最优向量计算而来

    double particle_glo_best[dim]; //全局最优向量

    double gfit; //全局最优适应度,有全局最优向量计算而来

    double particle_v[P_num][dim]; //记录每个个体的当前代速度向量

    double particle_fit[P_num]; //记录每个粒子的当前代适应度

    //随机生成粒子
    for(i=0; i<P_num; i++)            //在粒子群中生成粒子
    {
    	for(j=0; j<dim; j++)	//在搜索空间内生成粒子
    	{
    		particle[i][j] = low+(high-low)*1.0*rand()/RAND_MAX;    //初始化群体
    		particle_loc_best[i][j] = particle[i][j];               //将当前最优结果写入局部最优集合
    		particle_v[i][j] = -V_max+2*V_max*1.0*rand()/RAND_MAX;    //速度
    	}
    }
    
    for(i=0; i<P_num; i++)            //计算每个粒子的适应度
    {
    	particle_fit[i] = fitness(particle[i]);
    	particle_loc_fit[i] = particle_fit[i];
    }
    gfit = particle_loc_fit[0];      //找出全局最优
    j=0;
    for(i=1; i<P_num; i++)
    {
    	if(particle_loc_fit[i]<gfit)
    	{
    		gfit = particle_loc_fit[i];
    		j = i;
    	}
    }
    for(i=0; i<dim; i++)             //更新全局最优向量
    {
    	particle_glo_best[i] = particle_loc_best[j][i];
    }
    

    }

    void renew_particle()

    {

    int i,j;
    
    for(i=0; i<P_num; i++)            //更新个体位置生成位置
    
    {
    
    	for(j=0; j<dim; j++)
    
    	{
    
    		particle[i][j] +=  particle_v[i][j];
    
    		if(particle[i][j] > high)
    
    		{
    
    			particle[i][j] = high;
    
    		}
    
    		if(particle[i][j] < low)
    
    		{
    
    			particle[i][j] = low;
    
    		}
    
    	}
    
    }
    

    }

    Supplement 2  ·  Dec 13, 2016
    //Part 2
    int main()

    {

    FILE *fp;

    fp=freopen("result.txt","a+",stdout);

    int i=0;

    int x,y;

    srand((unsigned)time(NULL));

    initial();

    while(i < iter_num)

    {

    double w;

    w=wmax-(wmax-wmin)/iter_num*i;

    renew_particle();

    for(x=0; x<P_num; x++) //计算每个粒子的适应度

    {

    particle_fit[x] = fitness(particle[x]);

    if(particle_fit[x] < particle_loc_fit[x]) //更新个体局部最优值

    {

    particle_loc_fit[x] = particle_fit[x];

    for(y=0; y<dim; y++) // 更新局部最优向量

    {

    particle_loc_best[x][y] = particle[x][y];

    }

    }

    }


    for(x=0,y=-1; x<P_num;x++) //更新全局变量

    {

    if(particle_loc_fit[x]<gfit)

    {

    gfit = particle_loc_fit[x];

    y = x;

    }

    }

    if(y != -1)

    {

    for(x=0; x<dim; x++) //更新全局最优向量

    {

    particle_glo_best[x] = particle_loc_best[y][x];

    }

    }

    for(x=0; x<P_num; x++) //更新个体速度

    {

    for(y=0; y<dim; y++)

    {

    particle_v[x][y]=w*particle_v[x][y]+

    c1*1.0*rand()/RAND_MAX*(particle_loc_best[x][y]-particle[x][y])+

    c2*1.0*rand()/RAND_MAX*(particle_glo_best[y]-particle[x][y]);

    if(particle_v[x][y] > V_max)

    {

    particle_v[x][y] = V_max;

    }

    if(particle_v[x][y] < -V_max)

    {

    particle_v[x][y] = -V_max;

    }

    }

    }

    i++;

    }

    printf("粒子个数:%d\n",P_num);

    printf("维度为:%d\n",dim);

    printf("最优值为%.10lf\n", gfit);

    return 0;

    }
    14 replies    2016-12-14 08:03:58 +08:00
    chaosoy
        1
    chaosoy  
       Dec 13, 2016
    眼晕
    mnzlichunyu
        2
    mnzlichunyu  
       Dec 13, 2016
    这谁要是看完了,我敬他是一条好汉。
    l91liliang
        3
    l91liliang  
    OP
       Dec 13, 2016 via Android
    @zchpeng @mnzlichunyu Sorry.不会用 markdown 。求教。。。
    aleen42
        4
    aleen42  
       Dec 13, 2016   ❤️ 1
    = =你不会断点 debug ,然后查哪一行计算异常吗?
    aleen42
        5
    aleen42  
       Dec 13, 2016
    虽然我也小白,但建议你对照这个项目,看看自己的算法哪里出错了。 https://github.com/kkentzo/pso
    l91liliang
        6
    l91liliang  
    OP
       Dec 13, 2016
    @aleen42 我正在调试中,感觉问题不大。但是结果是错误的。我再慢慢调试吧。谢谢您。
    altairkuma
        7
    altairkuma  
       Dec 13, 2016
    ```
    #include<stdio.h>
    #include<math.h>
    #include<time.h>
    #include<stdlib.h>
    #define P_num 200 //粒子数目
    #define dim 50
    #define low -512 //搜索域范围
    #define high 512
    #define iter_num 1000
    #define V_max 20 //速度范围
    #define c1 2
    #define c2 2
    #define w 0.5
    #define alp 1
    double particle[P_num][dim]; //个体集合
    double particle_loc_best[P_num][dim]; //每个个体局部最优向量
    double particle_loc_fit[P_num]; //个体的局部最优适应度,有局部最优向量计算而来
    double particle_glo_best[dim]; //全局最优向量
    double gfit; //全局最优适应度,有全局最优向量计算而来
    double particle_v[P_num][dim]; //记录每个个体的当前代速度向量
    double particle_fit[P_num]; //记录每个粒子的当前代适应度

    double f1(double a[])
    {
    int i;
    double sum=0.0;
    for(i=0; i<dim; i++)
    { sum+=a[i]*a[i]; }
    return sum;
    }

    double f2(double a[])
    {
    int i;
    double sum=0.0;
    for(i=0;i<dim;i++)
    {
    sum=(1+(a[i]+a[i+1]+1)(a[i]+a[i+1]+1)(19-14a[i]+3a[i]a[i]-14a[i+1]+6a[i]a[i+1]+3a[i+1]a[i+1]))(30+(2a[i]-3a[i+1])(2a[i]-3a[i+1])(18-32a[i]+12a[i]a[i]+48a[i+1]-36a[i]a[i+1]+27a[i+1]*a[i+1]));
    }
    return sum;
    }

    double f3(double a[])
    {
    int i;
    double sum=0.0;
    for(i=0;i<dim;i++)
    { sum+=-a[i]sin(sqrt(abs(a[i]))); }
    return sum;
    }

    double fitness(double a[]) //适应度函数
    {
    return f2(a);
    }

    void initial()
    {
    int i,j;
    for(i=0; i<P_num; i++) //随即生成粒子
    {
    for(j=0; j<dim; j++)
    {
    particle[i][j] = low+(high-low)1.0rand()/RAND_MAX; //初始化群体
    particle_loc_best[i][j] = particle[i][j]; //将当前最优结果写入局部最优集合
    particle_v[i][j] = -V_max+2V_max1.0rand()/RAND_MAX; //速度
    }
    }
    for(i=0; i<P_num; i++) //计算每个粒子的适应度
    {
    particle_fit[i] = fitness(particle[i]);
    particle_loc_fit[i] = particle_fit[i];
    }
    gfit = particle_loc_fit[0]; //找出全局最优
    j=0;
    for(i=1; i<P_num; i++)
    {
    if(particle_loc_fit[i]<gfit)
    { gfit = particle_loc_fit[i]; j = i; }
    }
    for(i=0; i<dim; i++) //更新全局最优向量
    { particle_glo_best[i] = particle_loc_best[j][i]; }
    }

    void renew_particle()
    {
    int i,j;
    for(i=0; i<P_num; i++) //更新个体位置生成位置
    {
    for(j=0; j<dim; j++)
    { particle[i][j] += alpparticle_v[i][j];
    if(particle[i][j] > high)
    { particle[i][j] = high; }
    if(particle[i][j] < low)
    { particle[i][j] = low; }
    }
    }
    }

    void renew_var()
    {
    int i, j;
    for(i=0; i<P_num; i++) //计算每个粒子的适应度
    {
    particle_fit[i] = fitness(particle[i]);
    if(particle_fit[i] < particle_loc_fit[i]) //更新个体局部最优值
    {
    particle_loc_fit[i] = particle_fit[i];
    for(j=0; j<dim; j++) // 更新局部最优向量
    { particle_loc_best[i][j] = particle[i][j]; }
    }
    }
    for(i=0,j=-1; i<P_num; i++) //更新全局变量
    {
    if(particle_loc_fit[i]<gfit)
    { gfit = particle_loc_fit[i]; j = i; }
    }
    if(j != -1)
    {
    for(i=0; i<dim; i++) //更新全局最优向量
    { particle_glo_best[i] = particle_loc_best[j][i];}
    }
    for(i=0; i<P_num; i++) //更新个体速度
    {
    for(j=0; j<dim; j++)
    {
    particle_v[i][j]=wparticle_v[i][j]+ c11.0rand()/RAND_MAX*(particle_loc_best[i][j]-particle[i][j])+ c21.0rand()/RAND_MAX*(particle_glo_best[j]-particle[i][j]);
    if(particle_v[i][j] > V_max)
    { particle_v[i][j] = V_max; }
    if(particle_v[i][j] < -V_max)
    { particle_v[i][j] = -V_max; }
    }
    }
    }

    int main()
    {
    freopen("result.txt","a+",stdout);
    int i=0;
    srand((unsigned)time(NULL));
    initial();
    while(i < iter_num)
    { renew_particle(); renew_var(); i++; }
    printf("粒子个数:%d\n",P_num);
    printf("维度为:%d\n",dim);
    printf("最优值为%.10lf\n", gfit);
    return 0;
    }
    ```
    spice630
        8
    spice630  
       Dec 13, 2016
    兄弟,我告诉你个方法,在 github 上发个 gist ,贴过来
    l91liliang
        9
    l91liliang  
    OP
       Dec 13, 2016
    lsmgeb89
        10
    lsmgeb89  
       Dec 13, 2016
    这会不会贴代码啊……
    araraloren
        11
    araraloren  
       Dec 13, 2016
    ...描述一下问题 代码最好贴在别的地方, V2EX 的代码展示体验太差
    l91liliang
        12
    l91liliang  
    OP
       Dec 13, 2016 via Android
    各位兄弟,格式还不错的版本已添加进附言 1 、 2 ,请各位帮帮忙。
    ivanlw
        13
    ivanlw  
       Dec 14, 2016
    附言的格式还不错?怪不得你看不懂代码
    l91liliang
        14
    l91liliang  
    OP
       Dec 14, 2016 via Android
    @ivanlw 我说了自己是小白嘛。恳请您协助解决问题。谢谢。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2534 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 12:07 · PVG 20:07 · LAX 05:07 · JFK 08:07
    ♥ Do have faith in what you're doing.