【C系列】一个C++的粒子群(PSO)算法实现

来源:互联网 发布:生死狙击m1911伤害数据 编辑:程序博客网 时间:2024/05/22 07:50
以下代码亲测运行成功,运行环境:visio studio 2005。
------------------------------------------------------------------------------
[cpp] view plain copy
#include <cstring>  
#include <iostream>  
#include <cmath>  
#include <algorithm>  
#include <ctime>  
  
#define rand_01 ((float)rand() / (float)RAND_MAX)  
  
const int numofdims = 30;  
const int numofparticles = 50;  
  
using namespace std;  
  
//typedef void (*FitnessFunc)(float X[numofparticles][numofdims], float fitnesses[numofparticles]);  
  
void fitnessfunc(float X[numofparticles][numofdims], float fitnesses[numofparticles])  
{  
    memset(fitnesses, 0, sizeof (float) * numofparticles);  
    for(int i = 0; i < numofparticles; i++)  
    {  
        for(int j = 0; j < numofdims; j++)  
        {  
            fitnesses[i] += X[i][j] * X[i][j]; //(pow(X[i][j], 2));  
        }  
    }  
}  
  
void rosenBroekFunc(float X[numofparticles][numofdims], float fitnesses[numofparticles])  
{  
    float x1, x2, t1, t2;  
    memset(fitnesses, 0, sizeof (float) * numofparticles);      
    for(int i = 0; i < numofparticles; i++)  
        for(int j = 0; j < numofdims - 1; j++)  
        {  
            x1 = X[i][j];  
            x2 = X[i][j+1];  
            t1 = (x2 - x1 * x1);  
            t1 *= t1;  
            t1 *= 100;  
            t2 = x1 - 1;  
            t2 *= t2;  
            fitnesses[i] = t1 + t2;  
        }  
}  
  
float mean(float inputval[], int vallength)  
{  
    float addvalue = 0;  
    for(int i = 0; i < vallength; i++)  
    {  
        addvalue += inputval[i];  
    }  
    return addvalue / vallength;  
}  
  
void PSO(int numofiterations, float c1, float c2,  
              float Xmin[numofdims], float Xmax[numofdims], float initialpop[numofparticles][numofdims],  
              float worsts[], float meanfits[], float bests[], float *gbestfit, float gbest[numofdims])  
{  
    float V[numofparticles][numofdims] = {0};  
    float X[numofparticles][numofdims];  
    float Vmax[numofdims];  
    float Vmin[numofdims];  
    float pbests[numofparticles][numofdims];  
    float pbestfits[numofparticles];  
    float fitnesses[numofparticles];  
    float w;  
    float minfit;  
    int   minfitidx;  
  
    memcpy(X, initialpop, sizeof(float) * numofparticles * numofdims);  
    fitnessfunc(X, fitnesses);  
    //rosenBroekFunc(X, fitnesses);  
      
//    fp(X, fitnesses);  
    minfit = *min_element(fitnesses, fitnesses + numofparticles);  
    minfitidx = min_element(fitnesses, fitnesses + numofparticles) - fitnesses;  
    *gbestfit = minfit;  
    memcpy(gbest, X[minfitidx], sizeof(float) * numofdims);  
  
    //设置速度极限  
    for(int i = 0; i < numofdims; i++)  
    {  
        Vmax[i] = 0.2 * (Xmax[i] - Xmin[i]);  
        Vmin[i] = -Vmax[i];  
    }  
  
    for(int t = 0; t < 1000; t++)  
    {  
        w = 0.9 - 0.7 * t / numofiterations;  
  
        //计算个体历史极小值  
        for(int i = 0; i < numofparticles; i++)  
        {  
            if(fitnesses[i] < pbestfits[i])  
            {  
                pbestfits[i] = fitnesses[i];  //pbestfits初始化尚未赋值  
                memcpy(pbests[i], X[i], sizeof(float) * numofdims);  
            }  
        }  
        for(int i = 0; i < numofparticles; i++)  
        {  
            for(int j = 0; j < numofdims; j++)  
            {  
                V[i][j] = min(max((w * V[i][j] + rand_01 * c1 * (pbests[i][j] - X[i][j])  
                                   + rand_01 * c2 * (gbest[j] - X[i][j])), Vmin[j]), Vmax[j]);  
                X[i][j] = min(max((X[i][j] + V[i][j]), Xmin[j]), Xmax[j]);  
            }  
        }  
  
    fitnessfunc(X, fitnesses);  
    //rosenBroekFunc(X, fitnesses);  
        minfit = *min_element(fitnesses, fitnesses + numofparticles);  
        minfitidx = min_element(fitnesses, fitnesses + numofparticles) - fitnesses;  
        if(minfit < *gbestfit)  
        {  
            *gbestfit = minfit;  
            //cout << "It=" << t << "->" << minfit << endl;  
            memcpy(gbest, X[minfitidx], sizeof(float) * numofdims);  
        }  
  
        worsts[t] = *max_element(fitnesses, fitnesses + numofparticles);  
        bests[t] = *gbestfit;  
        meanfits[t] = mean(fitnesses, numofparticles);  
    }  
  
  
}  
  
int main()  
{  
    time_t t;  
    srand((unsigned) time(&t));  
  
    float xmin[30], xmax[30];  
    float initpop[50][30];  
    float worsts[1000], bests[1000];  
    float meanfits[1000];  
    float gbestfit;  
    float gbest[30];  
    for(int i = 0; i < 30; i++)  
    {  
        xmax[i] = 100;  
        xmin[i] = -100;  
    }  
    for(int i = 0; i < 50; i++)  
        for(int j = 0; j < 30; j++)  
        {  
            initpop[i][j] = rand() % (100 + 100 + 1) - 100;  
        }  
      
    PSO(1000, 2, 2, xmin, xmax, initpop, worsts, meanfits, bests, &gbestfit, gbest);  
  
    cout<<"fitness: " << gbestfit << endl;  
    for(int i = 0; i < 30; i++)  
      cout << gbest[i] << ", ";  
    cout << endl;  
      宁波除皱http://www.biopls.net/Project/list-15-1.shtml
    return 0;  
}  
原创粉丝点击