党新苗 发表于 2025-7-6 16:06:12

粒子群算法的原理与实现示例

  粒子群算法(Particle Swarm Optimization,PSO)是一种基于群体智能的优化算法,由 Kennedy 和 Eberhart 于 1995 年提出,其灵感来源于鸟群觅食、鱼群游动等自然界中群体行为的协作与信息共享机制。该算法通过模拟群体中个体(粒子)的运动和信息交互,在解空间中搜索最优解,具有实现简单、收敛速度快、参数少等特点,被广泛应用于函数优化、神经网络训练、工程设计等领域。
一、算法思想

  PSO通过模拟群体中个体(粒子)的协作与信息共享来寻找最优解。每个粒子代表解空间中的一个候选解,通过跟踪自身和群体的历史最优信息,不断调整自身位置(解),来逼近全局最优解。
二、基本概念

  粒子(Particle):每个粒子有位置(Position)和速度(Velocity)两个属性,位置对应解空间中的一个点,速度决定粒子下一步的移动方向和距离。
  适应值(Fitness):根据目标函数计算的值,用于评价粒子的优劣。
  个体最优(pBest):粒子自身历史上找到的最佳位置。
  全局最优(gBest):整个群体中所有粒子找到的最佳位置(或局部邻域最优,如拓扑结构的变体)。
三、算法流程

1. 初始化

  a) 随机生成一群粒子,初始化其位置和速度。
  b) 计算每个粒子的适应值,记录个体最优(pBest)和全局最优(gBest)。
2. 迭代更新

  每次迭代中,粒子通过以下公式更新速度和位置:

\

\
其中,
  \(v_i^t\):粒子\(i\)在时刻\(t\)的速度。
  \(x_i^t\):粒子\(i\)在时刻\(t\)的位置。
  \(w\):惯性权重,平衡全局探索与局部开发。
  \(c_1,c_2\):学习因子(通常设为2),分别控制个体和群体经验的影响。
  \(r_1,r_2\):内的随机数,增加随机性。
3. 更新最优值

  计算新位置的适应值,更新pBest和gBest。
4. 终止条件

  算法通过多次迭代优化,直到满足以下任一条件时停止:
  a) 达到预设的最大迭代次数;
  b) 全局最优解的精度满足问题要求(如与目标值的误差小于阈值);
  c) 全局最优解在连续多轮迭代中不再变化(收敛稳定)。
四、关键参数

1. 惯性权重\(w\)

  较大的\(w\)(如0.9)增强全局搜索能力(适合探索新区域),较小的\(w\)(如0.4)增强局部搜索能力(适合精细优化)。实际应用中常采用线性递减策略(如从 0.9 降至 0.4),兼顾前期探索和后期收敛。
2. 学习因子\(c_1,c_2\)

  \(c_1\)反映粒子的 “个体认知”能力,\(c_2\)反映“社会协作”能力。两者平衡决定了粒子是倾向于自身经验还是群体信息。
3. 粒子群规模

  规模过小可能导致搜索不充分,规模过大会增加计算量,通常取 20~100。
五、优缺点

  优点:实现简单,无需梯度信息(适用于非连续、非可微函数),收敛速度快,鲁棒性强。
  缺点:易陷入局部最优解(尤其在高维复杂问题中),对参数设置较敏感,后期收敛速度可能变慢。
六、Python示例

import matplotlib
matplotlib.use('TkAgg')

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']# 中文支持
plt.rcParams['axes.unicode_minus'] = False# 负号显示

# 定义目标函数(这里使用Rastrigin函数)
def rastrigin(x, A=10):
    return A * len(x) + sum([(xi ** 2 - A * np.cos(2 * np.pi * xi)) for xi in x])


# 粒子群算法实现
def particle_swarm_optimization(objective_func, dim, num_particles, max_iter,
                              x_min, x_max, w=0.7, c1=1.5, c2=1.5):
    # 初始化粒子位置和速度
    particles_position = np.random.uniform(x_min, x_max, size=(num_particles, dim))
    particles_velocity = np.random.uniform(-1, 1, size=(num_particles, dim))

    # 初始化个体最优位置和全局最优位置
    particles_best_position = particles_position.copy()
    particles_best_value = np.array()
    global_best_index = np.argmin(particles_best_value)
    global_best_position = particles_best_position.copy()
    global_best_value = particles_best_value

    # 迭代优化
    history = []
    for iteration in range(max_iter):
      for i in range(num_particles):
            # 更新速度和位置
            r1, r2 = np.random.rand(2)
            particles_velocity = (w * particles_velocity +
                                     c1 * r1 * (particles_best_position - particles_position) +
                                     c2 * r2 * (global_best_position - particles_position))
            particles_position += particles_velocity

            # 边界处理
            particles_position = np.clip(particles_position, x_min, x_max)

            # 计算新的适应度值
            fitness = objective_func(particles_position)

            # 更新个体最优
            if fitness < particles_best_value:
                particles_best_value = fitness
                particles_best_position = particles_position.copy()

                # 更新全局最优
                if fitness < global_best_value:
                  global_best_value = fitness
                  global_best_position = particles_position.copy()

      history.append(global_best_value)
      if iteration % 10 == 0:
            print(f"迭代 {iteration}, 最优值: {global_best_value:.4f}")

    return global_best_position, global_best_value, history


# 运行粒子群算法
dim = 2# 问题维度
num_particles = 30# 粒子数量
max_iter = 100# 最大迭代次数
x_min, x_max = -5.12, 5.12# 搜索空间范围

best_position, best_value, history = particle_swarm_optimization(
    rastrigin, dim, num_particles, max_iter, x_min, x_max
)

print(f"\n优化结果:")
print(f"最优位置: {np.round(best_position, 4)}")
print(f"最优值: {best_value:.4f}")

# 可视化
plt.figure(figsize=(12, 5))

# 绘制收敛曲线
plt.subplot(1, 2, 1)
plt.plot(history)
plt.title('收敛曲线')
plt.xlabel('迭代次数')
plt.ylabel('最优值')
plt.grid(True)

# 绘制目标函数和最终粒子位置
if dim == 2:
    plt.subplot(1, 2, 2)
    x = np.linspace(x_min, x_max, 100)
    y = np.linspace(x_min, x_max, 100)
    X, Y = np.meshgrid(x, y)
    Z = np.zeros_like(X)
    for i in range(X.shape):
      for j in range(X.shape):
            Z = rastrigin(, Y])

    contour = plt.contourf(X, Y, Z, 50, cmap='viridis')
    plt.colorbar(contour)
    plt.scatter(best_position, best_position, c='red', marker='*', s=200, label='最优解')
    plt.title('目标函数等高线图')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.legend()
    plt.grid(True)

plt.tight_layout()
plt.show()

  示例实现了标准的粒子群算法,用于求解 Rastrigin 函数的最小值。包含以下主要部分:
  目标函数定义:使用 Rastrigin 函数作为测试函数,它是一个具有多个局部最小值的复杂函数。
  算法实现:实现了完整的 PSO 算法,包括粒子初始化、速度和位置更新、边界处理等。
  参数设置:可以调整粒子数量、迭代次数、惯性权重和学习因子等参数。
  结果可视化:绘制了算法的收敛曲线和目标函数的等高线图,直观展示优化结果。
七、小结

  粒子群算法通过模拟群体中个体的协作与学习,利用 “个体最优” 和 “全局最优” 引导搜索方向,通过速度和位置的动态更新逐步逼近最优解。其核心是信息共享与群体协作,既保留了个体的探索能力,又通过群体信息加速收敛。在各类优化问题中具有广泛的适用性。

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除
页: [1]
查看完整版本: 粒子群算法的原理与实现示例