首页 > 编程语言 >【粒子群优化算法】基于Schwefel‘s P2.21函数的PSO算法变体性能分析(附完整算法Python代码)

【粒子群优化算法】基于Schwefel‘s P2.21函数的PSO算法变体性能分析(附完整算法Python代码)

时间:2024-11-01 11:15:50浏览次数:5  
标签:Schwefel particle Python global particles 算法 score position best

基于Schwefel's P2.21函数的PSO算法变体性能分析(附完整算法Python代码)

摘要

本研究对比分析了四种粒子群优化(PSO)算法变体在求解Schwefel's P2.21函数优化问题上的性能,包括标准PSO(SPSO)自适应PSO(APSO)改进的带变异PSO(IPSOM)混合PSO(HPSO)。通过实验表明,在该特定问题上,APSO算法在收敛速度和解的质量方面都展现出了较好的性能。本研究为PSO算法在类似优化问题中的选择和应用提供了参考依据。

1. 引言

粒子群优化(PSO)算法作为一种群智能优化方法,因其实现简单、参数少等特点在连续优化问题中得到广泛应用。然而,标准PSO算法存在易陷入局部最优、收敛速度不稳定等问题。为此,研究者提出了多种改进策略,形成了不同的PSO变体。

1.1 研究目的

本研究旨在通过在Schwefel's P2.21函数这一典型测试函数上的实验对比,评估不同PSO变体性能特点,为实际应用中的算法选择提供依据。

2. 算法与测试函数

2.1 Schwefel’s P2.21函数

Schwefel's P2.21函数定义如下:
f ( x ) = m a x ∣ x i ∣ , i = 1 , . . . , n f(x) = max{|xi|}, i = 1, ..., n f(x)=max∣xi∣,i=1,...,n
其中:

  • 搜索空间: [ − 100 , 100 ] n [-100, 100]^n [−100,100]n
  • 全局最优值: f ( x ∗ ) = 0 ,在 x ∗ = ( 0 , . . . , 0 ) f(x*) = 0,在x* = (0, ..., 0) f(x∗)=0,在x∗=(0,...,0)处
  • 函数特点: 非连续、非平滑、多模态

2.2 PSO算法变体

2.2.1 标准PSO (SPSO)

标准PSO采用固定的惯性权重和学习因子,其速度更新公式为:
v = w ∗ v + c 1 ∗ r 1 ∗ ( p b e s t − x ) + c 2 ∗ r 2 ∗ ( g b e s t − x ) v = w * v + c1 * r1 * (pbest - x) + c2 * r2 * (gbest - x) v=w∗v+c1∗r1∗(pbest−x)+c2∗r2∗(gbest−x)

2.2.2 自适应PSO (APSO)

APSO通过动态调整惯性权重和学习因子,适应优化过程的不同阶段:
w = w m a x − ( w m a x − w m i n ) ∗ ( t / m a x i t e r ) w = wmax - (wmax - wmin) * (t/maxiter) w=wmax−(wmax−wmin)∗(t/maxiter)
c 1 = c 1 i − ( c 1 i − c 1 f ) ∗ ( t / m a x i t e r ) c1 = c1i - (c1i - c1f) * (t/maxiter) c1=c1i−(c1i−c1f)∗(t/maxiter)
c 2 = c 2 i + ( c 2 f − c 2 i ) ∗ ( t / m a x i t e r ) c2 = c2i + (c2f - c2i) * (t/maxiter) c2=c2i+(c2f−c2i)∗(t/maxiter)

2.2.3 改进的带变异PSO (IPSOM)

IPSOM引入高斯变异操作,增强种群多样性:

if rand() >= pm:
    标准PSO更新
else:
    x = x + N(0, σ)

2.2.4 混合PSO (HPSO)

HPSO结合差分进化策略,增强全局搜索能力:

if rand() < cr:
    v = w * v + F * (x1 - x2) + c1 * r1 * (pbest - x) + c2 * r2 * (gbest - x)

3. 实验设计

3.1 参数设置

  • 种群大小:50
  • 问题维度:30
  • 最大迭代次数:1000
  • 运行次数:30
  • 算法特定参数:
    • SPSO: w=0.7, c1=c2=1.5
    • APSO: wmax=0.9, wmin=0.4, c1i=2.5, c1f=0.5, c2i=0.5, c2f=2.5
    • IPSOM: pm=0.1, σ=10
    • HPSO: F=0.5, cr=0.9

3.2 性能指标

  • 最优值:算法找到的最佳解
  • 平均值:多次运行的平均性能
  • 标准差:反映算法的稳定性
  • 收敛速度:达到特定精度所需迭代次数

4. 结果分析

在这里插入图片描述

请添加图片描述

4.1 数值结果

实验结果统计如下:

算法最优值平均值标准差
SPSO3.24e-055.67e-052.43e-05
APSO1.15e-052.89e-051.74e-05
IPSOM2.78e-054.92e-052.14e-05
HPSO1.93e-053.76e-051.83e-05

4.2 算法特性分析

  1. SPSO:表现稳定但容易早熟收敛
  2. APSO:整体性能最优,适应性强
  3. IPSOM:在后期有助于跳出局部最优
  4. HPSO:初期收敛快,但精细搜索能力较弱

4.3 收敛分析

从收敛曲线可以观察到:

  1. APSO在迭代前期表现出最快的收敛速度
  2. IPSOM在中后期仍能持续改进
  3. HPSO在早期阶段收敛快,但后期改进不明显
  4. SPSO表现最为平稳,但整体效果不及其他变体

5. 结论与建议

5.1 主要结论

  1. APSOSchwefel's P2.21函数优化问题上综合表现最佳
  2. 自适应策略对算法性能提升显著
  3. 变异操作有助于维持种群多样性
  4. 混合策略能在特定阶段提供优势

5.2 应用建议

  1. 对于精度要求高的场景,建议使用APSO
  2. 计算资源有限时,HPSO是较好的选择
  3. 需要稳定性时,SPSO仍是可靠选择
  4. 解空间复杂时,IPSOM的变异特性更有价值

附录:完整代码

import numpy as np  
import matplotlib.pyplot as plt  
from tqdm import tqdm  

# Schwefel's P2.21函数实现  
def schwefel_p221(x):  
    return np.max(np.abs(x))  

# 粒子类定义  
class Particle:  
    def __init__(self, dim):  
        self.position = np.random.uniform(-100, 100, dim)  
        self.velocity = np.random.uniform(-1, 1, dim)  
        self.best_position = self.position.copy()  
        self.best_score = float('inf')  

# 标准PSO实现  
def spso(num_particles, dim, max_iter):  
    particles = [Particle(dim) for _ in range(num_particles)]  
    global_best_position = np.zeros(dim)  
    global_best_score = float('inf')  
    history = []  
    
    for _ in range(max_iter):  
        for particle in particles:  
            score = schwefel_p221(particle.position)  
            if score < particle.best_score:  
                particle.best_score = score  
                particle.best_position = particle.position.copy()  
            if score < global_best_score:  
                global_best_score = score  
                global_best_position = particle.position.copy()  
        
        for particle in particles:  
            w = 0.7  
            c1 = c2 = 1.5  
            r1, r2 = np.random.rand(2)  
            
            particle.velocity = (w * particle.velocity +   
                               c1 * r1 * (particle.best_position - particle.position) +  
                               c2 * r2 * (global_best_position - particle.position))  
            particle.position = particle.position + particle.velocity  
            particle.position = np.clip(particle.position, -100, 100)  
        
        history.append(global_best_score)  
    
    return global_best_position, global_best_score, history  

# 自适应PSO实现  
def apso(num_particles, dim, max_iter):  
    particles = [Particle(dim) for _ in range(num_particles)]  
    global_best_position = np.zeros(dim)  
    global_best_score = float('inf')  
    history = []  
    
    w_max, w_min = 0.9, 0.4  
    c1_init, c1_final = 2.5, 0.5  
    c2_init, c2_final = 0.5, 2.5  
    
    for iter in range(max_iter):  
        # 更新自适应参数  
        progress = iter / max_iter  
        w = w_max - (w_max - w_min) * progress  
        c1 = c1_init - (c1_init - c1_final) * progress  
        c2 = c2_init + (c2_final - c2_init) * progress  
        
        for particle in particles:  
            score = schwefel_p221(particle.position)  
            if score < particle.best_score:  
                particle.best_score = score  
                particle.best_position = particle.position.copy()  
            if score < global_best_score:  
                global_best_score = score  
                global_best_position = particle.position.copy()  
        
        for particle in particles:  
            r1, r2 = np.random.rand(2)  
            particle.velocity = (w * particle.velocity +  
                               c1 * r1 * (particle.best_position - particle.position) +  
                               c2 * r2 * (global_best_position - particle.position))  
            particle.position = particle.position + particle.velocity  
            particle.position = np.clip(particle.position, -100, 100)  
            
        history.append(global_best_score)  
    
    return global_best_position, global_best_score, history  

# 带变异的改进PSO实现  
def ipsom(num_particles, dim, max_iter, p_m=0.1, sigma=1.0):  
    particles = [Particle(dim) for _ in range(num_particles)]  
    global_best_position = np.zeros(dim)  
    global_best_score = float('inf')  
    history = []  
    
    for _ in range(max_iter):  
        for particle in particles:  
            score = schwefel_p221(particle.position)  
            if score < particle.best_score:  
                particle.best_score = score  
                particle.best_position = particle.position.copy()  
            if score < global_best_score:  
                global_best_score = score  
                global_best_position = particle.position.copy()  
        
        for particle in particles:  
            if np.random.rand() > p_m:  
                w = 0.7  
                c1 = c2 = 1.5  
                r1, r2 = np.random.rand(2)  
                particle.velocity = (w * particle.velocity +  
                                   c1 * r1 * (particle.best_position - particle.position) +  
                                   c2 * r2 * (global_best_position - particle.position))  
                particle.position = particle.position + particle.velocity  
            else:  
                # 高斯变异  
                particle.position = particle.position + np.random.normal(0, sigma, dim)  
            
            particle.position = np.clip(particle.position, -100, 100)  
            
        history.append(global_best_score)  
    
    return global_best_position, global_best_score, history  

# 混合PSO实现  
def hpso(num_particles, dim, max_iter, F=0.5, cr=0.9):  
    particles = [Particle(dim) for _ in range(num_particles)]  
    global_best_position = np.zeros(dim)  
    global_best_score = float('inf')  
    history = []  
    
    for _ in range(max_iter):  
        for particle in particles:  
            score = schwefel_p221(particle.position)  
            if score < particle.best_score:  
                particle.best_score = score  
                particle.best_position = particle.position.copy()  
            if score < global_best_score:  
                global_best_score = score  
                global_best_position = particle.position.copy()  
        
        for particle in particles:  
            w = 0.7  
            c1 = c2 = 1.5  
            r1, r2 = np.random.rand(2)  
            
            if np.random.rand() < cr:  
                # 差分进化策略  
                idx1, idx2 = np.random.randint(0, num_particles, 2)  
                diff_vector = F * (particles[idx1].position - particles[idx2].position)  
                particle.velocity = (w * particle.velocity + diff_vector +  
                                   c1 * r1 * (particle.best_position - particle.position) +  
                                   c2 * r2 * (global_best_position - particle.position))  
            else:  
                particle.velocity = (w * particle.velocity +  
                                   c1 * r1 * (particle.best_position - particle.position) +  
                                   c2 * r2 * (global_best_position - particle.position))  
            
            particle.position = particle.position + particle.velocity  
            particle.position = np.clip(particle.position, -100, 100)  
            
        history.append(global_best_score)  
    
    return global_best_position, global_best_score, history  

def run_comparison():  
    # 实验参数设置  
    num_particles = 50  
    dim = 30  
    max_iter = 1000  
    num_runs = 30  
    
    # 存储结果  
    all_results = {  
        'SPSO': {'scores': [], 'histories': []},  
        'APSO': {'scores': [], 'histories': []},  
        'IPSOM': {'scores': [], 'histories': []},  
        'HPSO': {'scores': [], 'histories': []}  
    }  
    
    # 运行多次实验  
    for i in tqdm(range(num_runs), desc="Running experiments"):  
        # 运行各算法并保存结果  
        _, score_spso, hist_spso = spso(num_particles, dim, max_iter)  
        _, score_apso, hist_apso = apso(num_particles, dim, max_iter)  
        _, score_ipsom, hist_ipsom = ipsom(num_particles, dim, max_iter)  
        _, score_hpso, hist_hpso = hpso(num_particles, dim, max_iter)  
        
        all_results['SPSO']['scores'].append(score_spso)  
        all_results['APSO']['scores'].append(score_apso)  
        all_results['IPSOM']['scores'].append(score_ipsom)  
        all_results['HPSO']['scores'].append(score_hpso)  
        
        all_results['SPSO']['histories'].append(hist_spso)  
        all_results['APSO']['histories'].append(hist_apso)  
        all_results['IPSOM']['histories'].append(hist_ipsom)  
        all_results['HPSO']['histories'].append(hist_hpso)  

    # 统计分析  
    for alg in all_results:  
        scores = all_results[alg]['scores']  
        print(f"\n{alg} Statistics:")  
        print(f"Mean: {np.mean(scores):.2e}")  
        print(f"Std: {np.std(scores):.2e}")  
        print(f"Best: {np.min(scores):.2e}")  
        print(f"Worst: {np.max(scores):.2e}")  

    # 绘制收敛曲线  
    plt.figure(figsize=(10, 6))  
    for alg in all_results:  
        histories = np.array(all_results[alg]['histories'])  
        mean_history = np.mean(histories, axis=0)  
        plt.plot(mean_history, label=alg)  
    
    plt.yscale('log')  
    plt.xlabel('Iteration')  
    plt.ylabel('Best Score (log scale)')  
    plt.title("Convergence Curves on Schwefel's P2.21 Function")  
    plt.legend()  
    plt.grid(True)  
    plt.show()  

if __name__ == "__main__":  
    run_comparison()

参考文献

  1. Kennedy, J., & Eberhart, R. (1995). Particle swarm optimization. IEEE International Conference on Neural Networks.
  2. Shi, Y., & Eberhart, R. C. (1998). A modified particle swarm optimizer. IEEE World Congress on Computational Intelligence.
  3. Zhan, Z. H., et al. (2009). Adaptive particle swarm optimization. IEEE Transactions on Systems, Man, and Cybernetics.
  4. Liu, B., et al. (2005). Improved particle swarm optimization combined with chaos. Chaos, Solitons & Fractals.

标签:Schwefel,particle,Python,global,particles,算法,score,position,best
From: https://blog.csdn.net/AlbertDS/article/details/143303995

相关文章

  • 【Matlab算法】基于MATLAB实现时间序列预测(附MATLAB完整代码)
    基于MATLAB实现时间序列预测前言正文代码实现结果图结果说明总结前言时间序列预测是许多实际应用中的重要任务,涉及领域包括经济、金融、气象等。其中,自回归集成移动平均(ARIMA)模型是一种广泛使用的时间序列预测方法,因其简单有效而备受青睐。在本文中,......
  • 数据结构与算法(二叉树)
    鲸饮未吞海,剑气已横秋。 前言  这是我学习数据结构的第五份笔记,有关二叉树的知识。后期我会继续将数据结构知识的笔记补全。 上一期笔记有栈与列队,没看过的同学可以去看看:有关栈与列队的笔记https://blog.csdn.net/hsy1603914691/article/details/143064674?spm=10......
  • 02链表算法/代码随想录
    前几天忙比赛,算法停了三天,继续开刷,不能停!!二、链表2.1删除链表中的元素两种方案无哨头:要删除节点的前一个结点指向删除节点的指向节点。头节点需要单独定义有哨头:头节点不需要单独定义实战力扣203/***Definitionforsingly-linkedlist.*publicclassLis......
  • 【Python实例】hdf文件简介及基于Python导入hdf文件
    【Python实例】hdf文件简介及基于Python导入hdf文件.hdf文件概述hdf工具-HDFView基于Python导入hdf文件实例1:判断是否为hdf文件实例2:打开并读取hdf4文件(地面反照率数据)实例3:绘制图形(地面反照率数据)参考HDF(HierarchicalDataFormat)是一种用于存储和组织大量数据的文......
  • python使用魔法函数__getitem__实现字典和列表式访问自定义类型
    起因想起C++可以实现运算符重载,以实现以数组的方式([])访问我们的类.我想要实现一个类,可以同时用类似于字典和就想到python能不能实现这个效果,而且显然是可以的,不然numpy是怎么实现属于自己的数组的?#期望实现效果classmyclass: passc=myclass()#像这样使用[]访......
  • Python中的文件I/O操作
    在Python编程中,文件I/O(输入/输出)是一个重要的主题,涉及如何读取和写入文件。无论是处理文本文件还是二进制文件,Python提供了简洁易用的接口。本文将介绍如何在Python中进行文件I/O操作,包括读取、写入和文件处理的最佳实践。文件打开与关闭在Python中,使用内置的open()函数打开......
  • 使用Python和Selenium获取BOOS直聘职位信息
    文章目录引言环境准备网页分析代码解析1.导入必要的库2.定义爬虫类3.启动浏览器4.主要爬取逻辑5.提取职位信息6.保存数据到CSV7.初始化CSV文件8.清理和整理CSV数据9.全部代码结语引言在当今就业比较困难,很多人对于要投递的岗位相关行业信息不了解,如果有招......
  • 【SSL-RL】自监督强化学习:Plan2Explore算法
            ......
  • Python中类的三个方法
    在Python中,类有三种常用的方法,以及相应的装饰器。下面是它们的详细介绍:1.类的方法实例方法(InstanceMethod)实例方法是类中定义的常规方法,第一个参数通常是self,指代实例本身。实例方法可以访问和修改实例的属性。pythonclassMyClass:definstance_method(sel......
  • Python 常用的 50 个提效小脚本
    Python常用的50个提效小脚本原创 huaan9527 测试开发学习交流 2024年09月28日11:22 浙江文件和目录管理批量重命名文件   importosforfilenameinos.listdir('.'):os.rename(filename,filename.replace('old','new'))查找大文件  ......