粒子群算法(PSO)原理与经典应用
一、算法简介
粒子群算法(Particle Swarm Optimization, PSO)是一种模拟群体智能的全局优化算法,由Kennedy和Eberhart于1995年提出。它通过模拟鸟群、鱼群等群体觅食行为,协同搜索最优解,广泛应用于函数优化、神经网络训练、路径规划等领域。
二、基本原理
PSO通过一群“粒子”在搜索空间中移动来寻找最优解。每个粒子代表一个潜在解,具有位置和速度。粒子根据自身历史最优位置(个体极值 pbestp_{best}pbest)和全体粒子历史最优位置(全局极值 gbestg_{best}gbest)来调整自己的速度和位置。
1. 速度与位置更新公式
粒子 iii 在第 kkk 代的速度和位置更新如下:
vik+1=wvik+c1r1(pbest,i−xik)+c2r2(gbest−xik) v_{i}^{k+1} = w v_{i}^k + c_1 r_1 (p_{best,i} - x_{i}^k) + c_2 r_2 (g_{best} - x_{i}^k) vik+1=wvik+c1r1(pbest,i−xik)+c2r2(gbest−xik)
xik+1=xik+vik+1 x_{i}^{k+1} = x_{i}^k + v_{i}^{k+1} xik+1=xik+vik+1
其中:
- www:惯性权重,平衡全局与局部搜索能力
- c1,c2c_1, c_2c1,c2:学习因子(通常取2)
- r1,r2r_1, r_2r1,r2:[0,1][0,1][0,1]之间的随机数
2. 算法流程
- 初始化粒子群的位置和速度
- 计算每个粒子的适应度
- 更新个体极值和全局极值
- 更新速度和位置
- 判断终止条件,若未满足则返回第2步
三、经典应用问题:Sphere函数最小化
Sphere函数是优化算法测试中最常用的基准函数之一:
f(x)=∑i=1nxi2 f(x) = \sum_{i=1}^n x_i^2 f(x)=i=1∑nxi2
其中 xi∈[−5.12,5.12]x_i \in [-5.12, 5.12]xi∈[−5.12,5.12],nnn 为变量维数。最优解为 x=(0,0,...,0)x = (0, 0, ..., 0)x=(0,0,...,0),此时 f(x)=0f(x) = 0f(x)=0。
Python伪代码示例
# ...粒子群算法主流程伪代码...
for each particle:
update velocity
update position
evaluate fitness
update pbest and gbest
完整代码示例
以Sphere函数最小化为例
import numpy as np # 导入NumPy库,用于科学计算
import matplotlib.pyplot as plt # 导入matplotlib的pyplot模块,用于绘图
# 设置matplotlib支持中文
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False # 设置正常显示负号
# 定义Sphere函数,作为我们的目标函数
def sphere(x): # 定义函数sphere,输入参数为x
return np.sum(x ** 2) # 返回x中所有元素平方和
# --- 粒子群算法参数设置 ---
num_particles = 30 # 设置粒子数量
dim = 2 # 设置问题维度
max_iter = 100 # 设置最大迭代次数
bound = 5.12 # 设置搜索空间的边界
w = 0.7 # 设置惯性权重
c1 = 1.5 # 设置个体学习因子
c2 = 1.5 # 设置社会学习因子
# --- 初始化粒子群 ---
# 在[-bound, bound]范围内随机初始化所有粒子的位置
pos = np.random.uniform(-bound, bound, (num_particles, dim))
# 在[-1, 1]范围内随机初始化所有粒子的速度
vel = np.random.uniform(-1, 1, (num_particles, dim))
pbest = pos.copy() # 初始化个体最优位置为当前位置
# 计算每个粒子初始位置的适应度值
pbest_val = np.array([sphere(x) for x in pos])
gbest_idx = np.argmin(pbest_val) # 找到初始全局最优值的索引
gbest = pbest[gbest_idx].copy() # 初始化全局最优位置
gbest_val = pbest_val[gbest_idx] # 初始化全局最优值
# 用于记录每次迭代的全局最优值,以便后续可视化
gbest_history = []
# --- 主循环:迭代更新粒子群 ---
for iter in range(max_iter): # 循环迭代指定的次数
r1 = np.random.rand(num_particles, dim) # 生成随机数r1
r2 = np.random.rand(num_particles, dim) # 生成随机数r2
# 根据公式更新每个粒子的速度
vel = w * vel + c1 * r1 * (pbest - pos) + c2 * r2 * (gbest - pos)
# 根据新速度更新每个粒子的位置
pos = pos + vel
# 对超出边界的粒子位置进行处理,限制在边界内
pos = np.clip(pos, -bound, bound)
# 计算更新后每个粒子位置的适应度值
fitness = np.array([sphere(x) for x in pos])
# --- 更新个体和全局最优解 ---
# 找到当前适应度值优于个体历史最优值的粒子
mask = fitness < pbest_val
pbest[mask] = pos[mask] # 更新这些粒子的个体最优位置
pbest_val[mask] = fitness[mask] # 更新这些粒子的个体最优值
# 找到当前所有粒子中的最优值索引
min_idx = np.argmin(pbest_val)
# 如果当前最优值优于全局历史最优值
if pbest_val[min_idx] < gbest_val:
gbest = pbest[min_idx].copy() # 更新全局最优位置
gbest_val = pbest_val[min_idx] # 更新全局最优值
# 记录本次迭代的全局最优值
gbest_history.append(gbest_val)
# --- 输出结果 ---
print(f"最优解:{gbest}, 最优值:{gbest_val}") # 打印最终找到的最优解和最优值
# --- 可视化收敛曲线 ---
plt.plot(gbest_history) # 绘制全局最优值的收敛曲线
plt.xlabel('迭代次数') # 设置x轴标签
plt.ylabel('全局最优值') # 设置y轴标签
plt.title('PSO求解Sphere函数收敛曲线') # 设置图表标题
plt.grid() # 显示网格
plt.show() # 显示图表
四、总结
粒子群算法以其简单高效、参数少、易实现等优点,在连续优化领域有广泛应用。通过合理设置参数和改进策略,PSO可用于求解多种复杂优化问题。
7238



被折叠的 条评论
为什么被折叠?



