一个C++的粒子群(PSO)算法实现

326 篇文章 2 订阅
85 篇文章 2 订阅

收集和修改的PSO算法,可用于参考实现:

#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;
    
    return 0;
}


  • 3
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
粒子群算法(Particle Swarm Optimization,PSO)是一种基于群体智能的优化算法,用于解决优化问题。下面是粒子群算法C++实现的基本步骤: 1. 初始化粒子群:定义粒子的位置和速度,并为每个粒子随机分配初始位置和速度。 2. 计算适应度值:根据问题的适应度函数,计算每个粒子的适应度值。 3. 更新个体最优解:对于每个粒子,根据当前位置和历史最优位置,更新个体最优解。 4. 更新全局最优解:从所有粒子的个体最优解中选择全局最优解。 5. 更新速度和位置:根据粒子群算法的公式,更新每个粒子的速度和位置。 6. 判断终止条件:根据预设的终止条件,判断是否终止算法。如果满足条件,则结束算法;否则,返回步骤3。 以下是一个简单的粒子群算法C++实现示例: cpp #include <iostream> #include <vector> #include <cmath> #include <cstdlib> #include <ctime> // 定义粒子结构体 struct Particle { std::vector<double> position; // 粒子位置 std::vector<double> velocity; // 粒子速度 double fitness; // 适应度值 std::vector<double> bestPosition; // 个体最优位置 double bestFitness; // 个体最优适应度值 }; // 定义粒子群算法类 class PSO { public: PSO(int numParticles, int numDimensions, double inertiaWeight, double cognitiveWeight, double socialWeight, double minRange, double maxRange) : numParticles(numParticles), numDimensions(numDimensions), inertiaWeight(inertiaWeight), cognitiveWeight(cognitiveWeight), socialWeight(socialWeight), minRange(minRange), maxRange(maxRange) { // 初始化粒子群 particles.resize(numParticles); for (int i = 0; i < numParticles; ++i) { particles[i].position.resize(numDimensions); particles[i].velocity.resize(numDimensions); particles[i].bestPosition.resize(numDimensions); for (int j = 0; j < numDimensions; ++j) { particles[i].position[j] = getRandomNumber(minRange, maxRange); particles[i].velocity[j] = getRandomNumber(minRange, maxRange); } particles[i].fitness = calculateFitness(particles[i].position); particles[i].bestPosition = particles[i].position; particles[i].bestFitness = particles[i].fitness; } // 初始化全局最优解 globalBestPosition.resize(numDimensions); globalBestFitness = std::numeric_limits<double>::max(); } // 粒子群算法迭代更新 void update() { for (int i = 0; i < numParticles; ++i) { for (int j = 0; j < numDimensions; ++j) { // 更新速度 double r1 = getRandomNumber(0, 1); double r2 = getRandomNumber(0, 1); particles[i].velocity[j] = inertiaWeight * particles[i].velocity[j] + cognitiveWeight * r1 * (particles[i].bestPosition[j] - particles[i].position[j]) + socialWeight * r2 * (globalBestPosition[j] - particles[i].position[j]); // 更新位置 particles[i].position[j] = particles[i].position[j] + particles[i].velocity[j]; // 限制位置在范围内 if (particles[i].position[j] < minRange) { particles[i].position[j] = minRange; } if (particles[i].position[j] > maxRange) { particles[i].position[j] = maxRange; } } // 更新适应度值 particles[i].fitness = calculateFitness(particles[i].position); // 更新个体最优解 if (particles[i].fitness < particles[i].bestFitness) { particles[i].bestPosition = particles[i].position; particles[i].bestFitness = particles[i].fitness; } // 更新全局最优解 if (particles[i].fitness < globalBestFitness) { globalBestPosition = particles[i].position; globalBestFitness = particles[i].fitness; } } } // 获取全局最优解 std::vector<double> getGlobalBestPosition() const { return globalBestPosition; } // 获取全局最优适应度值 double getGlobalBestFitness() const { return globalBestFitness; } private: int numParticles; // 粒子数量 int numDimensions; // 粒子维度 double inertiaWeight; // 惯性权重 double cognitiveWeight; // 认知权重 double socialWeight; // 社会权重 double minRange; // 位置范围最小值 double maxRange; // 位置范围最大值 std::vector<Particle> particles; // 粒子群 std::vector<double> globalBestPosition; // 全局最优位置 double globalBestFitness; // 全局最优适应度值 // 计算适应度值(示例中使用的是一个简单的适应度函数,可根据实际问题进行修改) double calculateFitness(const std::vector<double>& position) { double fitness = 0.0; for (int i = 0; i < numDimensions; ++i) { fitness += std::pow(position[i], 2); } return fitness; } // 生成指定范围内的随机数 double getRandomNumber(double min, double max) { return min + static_cast<double>(rand()) / (RAND_MAX / (max - min)); } }; int main() { srand(static_cast<unsigned int>(time(nullptr))); int numParticles = 50; // 粒子数量 int numDimensions = 2; // 粒子维度 double inertiaWeight = 0.7; // 惯性权重 double cognitiveWeight = 1.4; // 认知权重 double socialWeight = 1.4; // 社会权重 double minRange = -10.0; // 位置范围最小值 double maxRange = 10.0; // 位置范围最大值 PSO pso(numParticles, numDimensions, inertiaWeight, cognitiveWeight, socialWeight, minRange, maxRange); int maxIterations = 100; // 最大迭代次数 for (int i = 0; i < maxIterations; ++i) { pso.update(); std::cout << "Iteration " << i + 1 << ": Best Fitness = " << pso.getGlobalBestFitness() << std::endl; } std::cout << "Global Best Position: "; std::vector<double> globalBestPosition = pso.getGlobalBestPosition(); for (int i = 0; i < numDimensions; ++i) { std::cout << globalBestPosition[i] << " "; } std::cout << std::endl; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值