
一、什么是粒子群算法?
想象一群鸟在一片未知区域寻找食物。每只鸟都不知道食物的确切位置,但它们知道当前离食物还有多远。于是,每只鸟会根据两个信息调整自己的飞行方向:
- 自己曾经找到过的最近食物位置(个体最优)
- 整个鸟群中其他鸟发现的最近食物位置(全局最优)
粒子群算法正是模拟这一过程。每个“粒子”代表一个潜在解,在搜索空间中飞行,通过不断更新速度和位置,最终逼近最优解。
二、算法核心公式
每个粒子包含两个关键属性:位置(position)和速度(velocity)。更新规则如下:
速度更新公式:
v[i] = w * v[i] + c1 * rand() * (pbest[i] - x[i]) + c2 * rand() * (gbest - x[i])
位置更新公式:
x[i] = x[i] + v[i]
其中:
w:惯性权重,控制粒子保持原有速度的程度 c1、c2:学习因子,通常取 2.0 pbest[i]:第 i 个粒子的历史最优位置 gbest:整个群体的历史最优位置 rand():[0,1) 之间的随机数
三、C++ 实现粒子群算法
下面我们用 C++ 编写一个完整的 PSO 算法,用于求解简单的二维函数最小值问题(例如:f(x, y) = x² + y²)。
#include <iostream>#include <vector>#include <cmath>#include <cstdlib>#include <ctime>#include <algorithm>using namespace std;// 目标函数:求最小值(例如 f(x, y) = x^2 + y^2)double objectiveFunction(const vector<double>& pos) { return pos[0] * pos[0] + pos[1] * pos[1];}struct Particle { vector<double> position; // 当前位置 vector<double> velocity; // 当前速度 vector<double> pbest; // 个体历史最优位置 double fitness; // 当前适应度 double bestFitness; // 个体历史最优适应度 Particle(int dim) { position.resize(dim); velocity.resize(dim); pbest.resize(dim); // 随机初始化位置 [-10, 10] for (int i = 0; i < dim; ++i) { position[i] = (rand() % 2000 - 1000) / 100.0; velocity[i] = (rand() % 200 - 100) / 100.0; pbest[i] = position[i]; } fitness = objectiveFunction(position); bestFitness = fitness; }};int main() { srand(time(0)); const int numParticles = 30; // 粒子数量 const int dimensions = 2; // 搜索空间维度 const int maxIterations = 100; // 最大迭代次数 const double w = 0.729; // 惯性权重 const double c1 = 1.49445; // 个体学习因子 const double c2 = 1.49445; // 全局学习因子 vector<Particle> swarm(numParticles, Particle(dimensions)); // 初始化全局最优 int gbestIndex = 0; for (int i = 1; i < numParticles; ++i) { if (swarm[i].fitness < swarm[gbestIndex].fitness) gbestIndex = i; } cout << "开始优化...\n"; for (int iter = 0; iter < maxIterations; ++iter) { for (int i = 0; i < numParticles; ++i) { // 更新速度和位置 for (int d = 0; d < dimensions; ++d) { double r1 = (double)rand() / RAND_MAX; double r2 = (double)rand() / RAND_MAX; swarm[i].velocity[d] = w * swarm[i].velocity[d] + c1 * r1 * (swarm[i].pbest[d] - swarm[i].position[d]) + c2 * r2 * (swarm[gbestIndex].position[d] - swarm[i].position[d]); swarm[i].position[d] += swarm[i].velocity[d]; // 可选:限制位置范围(如 [-10, 10]) if (swarm[i].position[d] < -10) swarm[i].position[d] = -10; if (swarm[i].position[d] > 10) swarm[i].position[d] = 10; } // 计算新适应度 swarm[i].fitness = objectiveFunction(swarm[i].position); // 更新个体最优 if (swarm[i].fitness < swarm[i].bestFitness) { swarm[i].bestFitness = swarm[i].fitness; swarm[i].pbest = swarm[i].position; } } // 更新全局最优 for (int i = 0; i < numParticles; ++i) { if (swarm[i].fitness < swarm[gbestIndex].fitness) { gbestIndex = i; } } if (iter % 20 == 0 || iter == maxIterations - 1) { cout << "迭代 " << iter << ": 最优值 = " << swarm[gbestIndex].fitness << ", 位置 = (" << swarm[gbestIndex].position[0] << ", " << swarm[gbestIndex].position[1] << ")\n"; } } cout << "\n优化完成!\n"; cout << "全局最优解: f(" << swarm[gbestIndex].position[0] << ", " << swarm[gbestIndex].position[1] << ") = " << swarm[gbestIndex].fitness << endl; return 0;}
四、代码说明与运行结果
上述代码实现了标准的 粒子群算法,主要步骤包括:
- 定义目标函数(这里是最简单的 x² + y²)
- 创建粒子类,包含位置、速度、个体最优等属性
- 初始化粒子群
- 在每次迭代中更新每个粒子的速度和位置
- 更新个体最优(pbest)和全局最优(gbest)
- 输出优化过程和最终结果
编译并运行后,你将看到类似以下的输出:
开始优化...迭代 0: 最优值 = 0.8723, 位置 = (0.52, -0.74)迭代 20: 最优值 = 0.0031, 位置 = (0.04, -0.04)迭代 40: 最优值 = 0.0002, 位置 = (-0.01, 0.01)迭代 60: 最优值 = 1e-06, 位置 = (0.001, -0.0008)迭代 80: 最优值 = 2e-08, 位置 = (0.0001, -0.0001)迭代 99: 最优值 = 5e-10, 位置 = (1e-05, -2e-05)优化完成!全局最优解: f(1e-05, -2e-05) = 5e-10
可以看到,算法成功找到了接近 (0, 0) 的最优解,目标函数值趋近于 0。
五、总结与扩展
通过本教程,你已经掌握了如何用 C++ 从零实现 粒子群优化算法。这项 智能优化算法 不仅适用于学术研究,也广泛用于工程实践。你可以尝试:
- 更换目标函数(如 Rastrigin、Rosenbrock 等复杂函数)
- 调整参数(w, c1, c2)观察收敛效果
- 增加边界处理、动态惯性权重等改进策略
- 将算法封装成类,提高代码复用性
希望这篇 C++实现粒子群优化 教程能为你打开智能算法的大门!动手试试吧,你会发现 粒子群算法 既强大又有趣。