当前位置:首页 > C > 正文

粒子群优化算法详解(C语言从零实现粒子群算法)

在人工智能和计算优化领域,粒子群算法(Particle Swarm Optimization, PSO)是一种非常流行且高效的优化算法。它模拟鸟群或鱼群的群体智能行为,通过个体与群体之间的信息交换来寻找最优解。本教程将带你用C语言实现一个完整的粒子群算法,即使你是编程小白,也能轻松上手!

粒子群优化算法详解(C语言从零实现粒子群算法) 粒子群算法 C语言实现 优化算法 智能计算 第1张

什么是粒子群算法?

粒子群算法由Kennedy和Eberhart于1995年提出,灵感来源于鸟群觅食行为。每个“粒子”代表解空间中的一个候选解,它有两个关键属性:

  • 位置(Position):当前解的坐标(例如在二维空间中为 (x, y))
  • 速度(Velocity):粒子移动的方向和快慢

每个粒子会记住自己找到的最好位置(称为个体最优,pBest),同时整个群体也会记录所有粒子中最好的位置(称为全局最优,gBest)。粒子根据这两个信息不断更新自己的速度和位置,最终趋向最优解。

C语言实现步骤

我们将用C语言实现一个简单的二维粒子群优化算法,目标是最小化函数:f(x, y) = x² + y²(该函数在 (0, 0) 处取得最小值 0)。

1. 定义粒子结构体

typedef struct {    double x, y;        // 粒子当前位置    double vx, vy;      // 粒子当前速度    double pbest_x, pbest_y; // 个体历史最优位置    double pbest_value; // 个体历史最优适应值} Particle;

2. 初始化粒子群

随机生成N个粒子的位置和速度,并初始化它们的个体最优值。

#include <stdio.h>#include <stdlib.h>#include <time.h>#include <math.h>#define POP_SIZE 30     // 粒子数量#define MAX_ITER 100    // 最大迭代次数#define W 0.729         // 惯性权重#define C1 1.494        // 个体学习因子#define C2 1.494        // 群体学习因子#define RAND_01 ((double)rand() / RAND_MAX)// 目标函数:求最小值double fitness(double x, double y) {    return x * x + y * y;}void initialize(Particle swarm[POP_SIZE]) {    for (int i = 0; i < POP_SIZE; i++) {        // 随机初始化位置 [-10, 10]        swarm[i].x = -10 + 20 * RAND_01;        swarm[i].y = -10 + 20 * RAND_01;                // 随机初始化速度 [-1, 1]        swarm[i].vx = -1 + 2 * RAND_01;        swarm[i].vy = -1 + 2 * RAND_01;                // 初始个体最优就是当前位置        swarm[i].pbest_x = swarm[i].x;        swarm[i].pbest_y = swarm[i].y;        swarm[i].pbest_value = fitness(swarm[i].x, swarm[i].y);    }}

3. 更新粒子位置和速度

核心公式如下:

v = w·v + c1·r1·(pBest - x) + c2·r2·(gBest - x)

x = x + v

其中 r1 和 r2 是 [0,1] 之间的随机数。

void update_swarm(Particle swarm[POP_SIZE], double *gbest_x, double *gbest_y, double *gbest_value) {    // 先找全局最优    *gbest_value = swarm[0].pbest_value;    *gbest_x = swarm[0].pbest_x;    *gbest_y = swarm[0].pbest_y;        for (int i = 1; i < POP_SIZE; i++) {        if (swarm[i].pbest_value < *gbest_value) {            *gbest_value = swarm[i].pbest_value;            *gbest_x = swarm[i].pbest_x;            *gbest_y = swarm[i].pbest_y;        }    }        // 更新每个粒子    for (int i = 0; i < POP_SIZE; i++) {        double r1 = RAND_01;        double r2 = RAND_01;                // 更新速度        swarm[i].vx = W * swarm[i].vx +                       C1 * r1 * (swarm[i].pbest_x - swarm[i].x) +                       C2 * r2 * (*gbest_x - swarm[i].x);                swarm[i].vy = W * swarm[i].vy +                       C1 * r1 * (swarm[i].pbest_y - swarm[i].y) +                       C2 * r2 * (*gbest_y - swarm[i].y);                // 更新位置        swarm[i].x += swarm[i].vx;        swarm[i].y += swarm[i].vy;                // 边界处理(可选)        if (swarm[i].x < -10) swarm[i].x = -10;        if (swarm[i].x > 10) swarm[i].x = 10;        if (swarm[i].y < -10) swarm[i].y = -10;        if (swarm[i].y > 10) swarm[i].y = 10;                // 计算新位置的适应值        double current_fit = fitness(swarm[i].x, swarm[i].y);                // 更新个体最优        if (current_fit < swarm[i].pbest_value) {            swarm[i].pbest_value = current_fit;            swarm[i].pbest_x = swarm[i].x;            swarm[i].pbest_y = swarm[i].y;        }    }}

4. 主函数:运行算法

int main() {    srand(time(NULL));        Particle swarm[POP_SIZE];    double gbest_x, gbest_y, gbest_value;        initialize(swarm);        printf("开始粒子群优化...\n");    for (int iter = 0; iter < MAX_ITER; iter++) {        update_swarm(swarm, &gbest_x, &gbest_y, &gbest_value);                if (iter % 10 == 0) {            printf("迭代 %d: 最优值 = %.6f, 位置 = (%.4f, %.4f)\n",                    iter, gbest_value, gbest_x, gbest_y);        }    }        printf("\n最终结果:\n");    printf("最优值 = %.8f\n", gbest_value);    printf("最优位置 = (%.6f, %.6f)\n", gbest_x, gbest_y);        return 0;}

编译与运行

将上述代码保存为 pso.c,然后在终端执行:

gcc pso.c -o pso -lm./pso

你将看到粒子群逐步逼近 (0, 0) 的过程,这正是我们期望的最优解!

总结

通过本教程,你已经掌握了如何用C语言实现基本的粒子群算法。这种智能计算方法广泛应用于工程优化、机器学习参数调优等领域。你可以尝试修改目标函数、调整参数(如惯性权重W、学习因子C1/C2)或增加维度,进一步探索优化算法的强大能力!

提示:实际应用中,建议对速度和位置进行边界限制,防止粒子“飞出”有效搜索空间。