粒子群优化算法(PSO)原理与Python高级实现

【智能优化】粒子群优化算法(PSO)原理与Python高级实现

📅 2026-05-08 | 🏷️ 智能优化 | 🏷️ 群智能 | 🏷️ PSO


一、引言

粒子群优化算法(Particle Swarm Optimization, PSO)是由Kennedy和Eberhart于1995年提出的群智能优化算法。该算法模拟鸟群觅食行为,通过粒子间的信息共享和相互学习来寻找最优解。PSO概念简单、参数少、收敛快,是应用最广泛的智能优化算法之一。


二、算法原理

2.1 核心公式

速度更新:
vid+1=w⋅vid+c1⋅r1⋅(pbesti−xid)+c2⋅r2⋅(gbest−xid)v_{i}^{d+1} = w \cdot v_{i}^{d} + c_1 \cdot r_1 \cdot (pbest_i - x_{i}^{d}) + c_2 \cdot r_2 \cdot (gbest - x_{i}^{d})vid+1=w⋅vid+c1⋅r1⋅(pbesti−xid)+c2⋅r2⋅(gbest−xid)

位置更新:
xid+1=xid+vid+1x_{i}^{d+1} = x_{i}^{d} + v_{i}^{d+1}xid+1=xid+vid+1

其中:

  • www:惯性权重,控制搜索范围
  • c1,c2c_1, c_2c1,c2:学习因子,通常取1.49445
  • r1,r2r_1, r_2r1,r2:均匀随机数,∈[0,1]\in [0, 1]∈[0,1]
  • pbestipbest_ipbesti:粒子历史最优位置
  • gbestgbestgbest:全局最优位置

2.2 惯性权重策略

python 复制代码
# 线性递减策略
w = w_max - (w_max - w_min) * t / max_iter
# 典型值: w_max = 0.9, w_min = 0.4

# 非线性递减策略
w = w_max * (w_max / w_min) ** (1 / (1 + t / max_iter))

# 随机惯性权重
w = 0.5 + np.random.random() / 2

三、Python高级实现

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

class AdvancedPSO:
    def __init__(self, dim=30, pop=30, max_iter=500, lb=-100, ub=100,
                 w_max=0.9, w_min=0.4, c1=1.49445, c2=1.49445):
        self.dim = dim
        self.pop = pop
        self.max_iter = max_iter
        self.lb = lb
        self.ub = ub
        self.w_max = w_max
        self.w_min = w_min
        self.c1 = c1
        self.c2 = c2
        
    def optimize(self, obj_func, strategy='linear', callback=None):
        # 初始化粒子位置和速度
        X = np.random.uniform(self.lb, self.ub, (self.pop, self.dim))
        V = np.zeros((self.pop, self.dim))
        
        # 评估适应度
        fitness = np.array([obj_func(x) for x in X])
        
        # 初始化最优位置
        pbest_x = X.copy()
        pbest_f = fitness.copy()
        
        # 全局最优
        gbest_idx = np.argmin(fitness)
        gbest_x = X[gbest_idx].copy()
        gbest_f = fitness[gbest_idx]
        
        convergence = []
        
        for t in range(self.max_iter):
            # 更新惯性权重
            if strategy == 'linear':
                w = self.w_max - (self.w_max - self.w_min) * t / self.max_iter
            elif strategy == 'nonlinear':
                w = self.w_max * (self.w_max / self.w_min) ** (-t / self.max_iter)
            elif strategy == 'random':
                w = 0.5 + np.random.random() / 2
            else:
                w = self.w_max
            
            # 更新速度和位置
            for i in range(self.pop):
                r1, r2 = np.random.random(), np.random.random()
                V[i] = w * V[i] + \
                       self.c1 * r1 * (pbest_x[i] - X[i]) + \
                       self.c2 * r2 * (gbest_x - X[i])
                
                # 速度限制
                V[i] = np.clip(V[i], -0.2 * (self.ub - self.lb), 0.2 * (self.ub - self.lb))
                
                X[i] = X[i] + V[i]
                X[i] = np.clip(X[i], self.lb, self.ub)
            
            # 评估
            fitness = np.array([obj_func(x) for x in X])
            
            # 更新个体最优
            improved = fitness < pbest_f
            pbest_x[improved] = X[improved]
            pbest_f[improved] = fitness[improved]
            
            # 更新全局最优
            current_best_idx = np.argmin(pbest_f)
            if pbest_f[current_best_idx] < gbest_f:
                gbest_f = pbest_f[current_best_idx]
                gbest_x = pbest_x[current_best_idx].copy()
            
            convergence.append(gbest_f)
            
            if callback:
                callback(t, gbest_x, gbest_f)
        
        return gbest_x, gbest_f, convergence

多种惯性权重策略对比

python 复制代码
strategies = ['linear', 'nonlinear', 'random', 'constant']
colors = ['blue', 'red', 'green', 'orange']

for strategy, color in zip(strategies, colors):
    pso = AdvancedPSO(dim=30, pop=30, max_iter=300)
    _, _, conv = pso.optimize(sphere, strategy=strategy)
    plt.plot(conv, color=color, label=strategy, linewidth=2)

plt.xlabel('Iteration')
plt.ylabel('Fitness')
plt.title('PSO with Different Inertia Weight Strategies')
plt.legend()
plt.grid(True, alpha=0.3)
plt.savefig('pso_strategies.png', dpi=150)

四、拓扑结构变体

python 复制代码
class TopologicalPSO:
    """PSO拓扑结构变体"""
    
    def __init__(self, dim=30, pop=30, max_iter=500, lb=-100, ub=100,
                 topology='gbest', k=5):
        # topology: 'gbest', 'lbest', 'von Neumann', 'random'
        self.topology = topology
        self.k = k  # lbest邻居数量
        # ... 其他参数同AdvancedPSO
    
    def get_neighbors(self, i):
        if self.topology == 'lbest':
            # 环形拓扑
            indices = [(i - j) % self.pop for j in range(self.k // 2 + 1)]
            indices += [(i + j) % self.pop for j in range(1, self.k // 2 + 1)]
            return np.unique(indices)
        elif self.topology == 'von Neumann':
            # 网格拓扑
            rows, cols = int(np.sqrt(self.pop)), int(np.sqrt(self.pop))
            r, c = i // cols, i % cols
            neighbors = [(r, (c-1)%cols), (r, (c+1)%cols), 
                        ((r-1)%rows, c), ((r+1)%rows, c)]
            return [idx * cols + c_ for r_, c_ in neighbors]
        return np.arange(self.pop)

五、实验结果

策略 Sphere Rosenbrock Ackley
Linear 1.23e-7 28.45 8.19e-6
Nonlinear 9.87e-8 25.12 7.54e-6
Random 8.45e-8 23.67 6.98e-6
Constant 2.31e-6 35.89 1.23e-5

六、PSO参数调优指南

参数 建议范围 说明
粒子数 20-50 维度高时增大
惯性权重 0.4-0.9 大值利于全局,小值利于局部
学习因子 1.4-2.0 通常c1=c2
最大速度 搜索范围的10-20% 防止粒子飞出过界

七、总结

PSO算法具有以下特点:

  • ✅ 概念简单,易于理解
  • ✅ 参数少,实现方便
  • ✅ 收敛速度快
  • ✅ 适合连续优化问题

局限性:

  • ❌ 离散优化问题需要改进
  • ❌ 易陷入局部最优
  • ❌ 后期收敛精度不足

您的点赞是我创作的动力!

相关推荐
Epiphany.5562 小时前
连通块的遍历
c++·算法·蓝桥杯
yhy66666662 小时前
java内存
java·开发语言
wang3zc2 小时前
如何正确管理浮层提示(Tooltip)显示时的页面焦点顺序
jvm·数据库·python
2401_824222692 小时前
如何导出Laravel特定时间段的订单数据 基于created_at过滤导出
jvm·数据库·python
百年孤独_2 小时前
单周期 MIPS 数据通路上层视角
python
2501_901200532 小时前
进阶设计指南之如何打印分页与自适应ER图_支持高级扩展类型
jvm·数据库·python
m0_609160492 小时前
C#怎么实现HttpClient最佳实践 C#如何用IHttpClientFactory管理HttpClient避免端口耗尽【网络】
jvm·数据库·python
码云社区2 小时前
JAVA同城上门做饭系统家政上门同城服务系统源码小程序+APP+公众号+h5
java·开发语言·小程序
zjy277772 小时前
Quill 编辑器光标意外跳转至顶部的解决方案
jvm·数据库·python