智能算法系列之粒子群优化算法

news2024/11/17 7:19:40

在这里插入图片描述

  本博客封面由ChatGPT + DALL·E 2共同创作而成。

文章目录

    • 前言
    • 1. 算法思想
    • 2. 细节梳理
      • 2.1 超参数的选择
      • 2.2 一些trick
    • 3. 算法实现
      • 3.1 问题场景
      • 3.2 python实现
    • 代码仓库:IALib[GitHub]

前言

  本篇是智能算法(Python复现)专栏的第三篇文章,主要介绍粒子群优化算法(ParticleSwarm Optimization, PSO)的思想,python实现及相关应用场景模拟。

  粒子群优化算法,简称粒子群算法,也叫作鸟群觅食算法。PSO算法的基本思想受到许多对鸟类的群体行为(觅食行为)进行建模与仿真研究结果的启发,粒子在解空间中追随最优的粒子进行迭代搜索,而不需要像遗传算法那样使用交叉以及变异操作。

1. 算法思想

  PSO算法最初设想是模拟鸟群觅食的过程,想象这样一个场景:一群鸟随机的分布在一个区域,在这个区域只有一块食物,但是所有的鸟都不知道这块食物的具体方位,只知道自己当前的位置距离食物还有多远。找到食物最简单有效的方式就是搜索目前离食物最近的鸟的周围区域。如果把食物当作最优点,而把鸟离食物的距离当作函数的适应度,那么鸟寻觅食物的过程就可以当作函数寻优的过程。由此受到启发,经过简化提出了PSO算法。

  PSO算法作为一种仿生算法,目前还没有完备的数学理论作为基础,但是作为一种新兴的智能优化算法,已经在诸多领域展现了良好的应用前景。

  粒子群优化算法的核心思想是通过模拟鸟群或鱼群等动物的群体行为,以达到求解最优化问题的目的。在粒子群优化中,搜索空间中的每个解都被视为一个粒子,每个粒子的位置表示解的搜索空间中的位置,粒子的速度表示解的搜索方向和速度。在搜索过程中,每个粒子通过学习其他粒子的经验,更新自己的位置和速度。粒子的位置和速度的更新可以分为两个部分:局部搜索和全局搜索。局部搜索是指粒子在其自身经验的基础上进行搜索,全局搜索是指粒子在全局最优解的基础上进行搜索。具体来说,每个粒子会记忆其历史最优解和全局最优解,然后通过调整自己的速度和位置来寻找更好的解。
  粒子群优化算法的基本步骤如下:
  (1) 初始化粒子群:随机生成粒子群中每个粒子的位置和速度。
  (2) 计算每个粒子的适应度:根据粒子的位置计算适应度函数的值。
  (3) 更新每个粒子的历史最优解:将粒子自己的历史最优解更新为当前最优解。
  (4) 更新全局最优解:将整个粒子群的最优解更新为所有粒子历史最优解中最优的一个。
  (5) 更新每个粒子的速度和位置:根据当前粒子自己的历史最优解和整个粒子群的最优解,以及粒子的速度和位置,更新粒子的速度和位置。
  粒子的速度更新公式如下: v ( t + 1 ) = v ( t ) + c 1 r 1 ( t ) [ p b e s t ( t ) − x ( t ) ] + c 2 r 2 ( t ) [ g b e s t ( t ) − x ( t ) ] v(t+1) = v(t) + c_1r_1(t)[pbest(t) - x(t)] + c_2r_2(t)[gbest(t) - x(t)] v(t+1)=v(t)+c1r1(t)[pbest(t)x(t)]+c2r2(t)[gbest(t)x(t)]  其中 c 1 c_1 c1 c 2 c_2 c2表示学习因子,也叫加速因子,具体来说, c 1 c_1 c1用来调节粒子飞向自身最好位置方向的步长, c 2 c_2 c2用来调节粒子飞向全局最好位置方向的步长。 r 1 r_1 r1 r 2 r_2 r2用来保持群体的多样性。 p b e s t pbest pbest表示当前粒子迄今为止搜索到的最优位置, g b e s t gbest gbest为整个粒子群迄今为止搜索到的最优位置。
  粒子的位置更新公式如下: x ( t + 1 ) = x ( t ) + v ( t + 1 ) x(t+1) = x(t) + v(t+1) x(t+1)=x(t)+v(t+1)

在这里插入图片描述

2. 细节梳理

2.1 超参数的选择

  PSO算法中没有实际的机制来控制粒子速度,值太大会导致粒子跳过最好解,太小又会导致对搜索空间的不充分搜索,所以有必要对速度的范围进行限制,一般可以根据搜索的位置范围进行调节,比如,本示例中的搜索范围为[0, 5],粒子的速度范围为[-1, 1]
   c 1 c_1 c1 c 2 c_2 c2这两个参数对粒子群算法的收敛起的作用不是很大,但是适当调整这两个参数,可以减小局部最小值的困扰,当然也会使收敛速度变快。
   r 1 r_1 r1 r 2 r_2 r2可以设置为[0,1]的随机数。

2.2 一些trick

  为了改善基本PSO算法的收敛性能,在更新粒子的速度时引入了惯性权重的概念,即: v ( t + 1 ) = w v ( t ) + c 1 r 1 ( t ) [ p b e s t ( t ) − x ( t ) ] + c 2 r 2 ( t ) [ g b e s t ( t ) − x ( t ) ] v(t+1) = wv(t) + c_1r_1(t)[pbest(t) - x(t)] + c_2r_2(t)[gbest(t) - x(t)] v(t+1)=wv(t)+c1r1(t)[pbest(t)x(t)]+c2r2(t)[gbest(t)x(t)]  其中, w w w称为惯性权重,基本PSO算法是惯性权重 w = 1 w=1 w=1的特殊情况。惯性权重 w w w使粒子保持飞行惯性,使其可以扩展搜索空间,有能力探索新的区域。

  带有惯性权重的粒子群优化算法是最常用的一种粒子群优化算法,本示例就是基于带有惯性权重的粒子群优化算法进行实现的。

  惯性权重 w w w的引入清除了基本PSO算法对速度最大值的需求,因为 w w w的作用就是保持全局和局部搜索能力的平衡。当速度最大值增加时,就人为减少 w w w来达到搜索的平衡,而 w w w的减少可降低需要的迭代次数,就可以将某一维速度的最大值锁定为每维变量的变化范围,只对 w w w进行调节。
  对全局搜索,广泛使用的方法是在前期利用较高的探索能力得到具有超高潜力且多样化的种子,而在后期提升开发能力以加快收敛速度,所以,也可以将 w w w设定为随进化迭代次数线性减少[在本示例中未实现该操作]

  除了上述的改进算法外,还有协同粒子群优化算法、量子粒子群优化算法(Qutantum-behaved Particle SwarmOptimization,QPSO)和混合粒子群优化算法。其中混合粒子群优化算法的研究更为广泛,小博主我计划在下一篇中介绍一下基于模拟退火算法的粒子群优化算法,其性能比单纯的模拟退火算法和粒子群优化算法都要好,敬请期待。

3. 算法实现

3.1 问题场景

  最值问题,求解 f ( x ) = x s i n ( 5 x ) − x c o s ( 2 x ) f(x) = xsin(5x) - xcos(2x) f(x)=xsin(5x)xcos(2x)在定义域[0, 5]上的最小值。我们先手动计算一下:

f ′ ( x ) = 2 x s i n ( 2 x ) + s i n ( 5 x ) − c o s ( 2 x ) + 5 x c o s ( 5 x ) f^\prime (x) = 2 x sin(2 x) + sin(5 x) - cos(2 x) + 5 x cos(5 x) f(x)=2xsin(2x)+sin(5x)cos(2x)+5xcos(5x)  令 f ′ ( x ) = 0 f^\prime (x) = 0 f(x)=0之后,理论上可以求得驻点,但又不太好计算。。。

3.2 python实现

# -*- coding:utf-8 -*-
# Author:   xiayouran
# Email:    youran.xia@foxmail.com
# Datetime: 2023/3/16 16:54
# Filename: particle_swarm_optimization.py
import numpy as np
import matplotlib.pyplot as plt
from base_algorithm import BaseAlgorithm
# base_algorithm 的实现已开源在github上
# 链接在文章末尾


__all__ = ['ParticleSwarmOptimization']


class Particle:
    def __init__(self):
        self.position = None    # 粒子的位置
        self.velocity = None    # 粒子的速度
        self.best_position = None   # 个体最优解
        self.fitness = None         # 适应度值


class ParticleSwarmOptimization(BaseAlgorithm):
    def __init__(self, population_size=100, p_dim=1, v_dim=1, max_iter=1000, x_range=(0, 5), seed=10086):
        super(ParticleSwarmOptimization, self).__init__()
        self.__population_size = population_size  # 种群大小
        self.__p_dim = p_dim        # 粒子位置维度
        self.__v_dim = v_dim        # 粒子速度维度
        self.__max_iter = max_iter  # 最大迭代次数
        self.__w = 0.5    # 惯性权重
        self.__c1 = 1.5   # 加速因子1
        self.__c2 = 1.5   # 加速因子2
        self.__population = []    # 粒子群
        self.global_best_particle = None    # 全局最优解
        self.__x_range = x_range
        self.__seed = seed

        np.random.seed(seed)

    def init_population(self):
        for i in range(self.__population_size):
            particle = Particle()
            particle.position = np.random.uniform(*self.__x_range, size=self.__p_dim)   # 随机初始化位置
            particle.velocity = np.random.uniform(-1, 1, size=self.__v_dim)     # 随机初始化速度
            particle.best_position = particle.position  # 初始最优位置
            particle.fitness = self.problem_function(particle.position)     # 计算适应度值
            if self.global_best_particle is None or particle.fitness < self.problem_function(self.global_best_particle.position):
                self.global_best_particle = particle  # 更新全局最优解
            self.__population.append(particle)

    def update_population(self):
        for i in range(self.__population_size):
            particle = self.__population[i]
            r1 = np.random.uniform(0, 1)
            r2 = np.random.uniform(0, 1)
            # Step2: 更新速度
            particle.velocity = self.__w * particle.velocity + \
                                self.__c1 * r1 * (particle.best_position - particle.position) + \
                                self.__c2 * r2 * (self.global_best_particle.position - particle.position)
            # Step3: 更新位置
            particle.position += particle.velocity
            particle.position = np.clip(particle.position, 0, 5)
            # Step4: 更新个体最优解
            if self.problem_function(particle.position) < self.problem_function(particle.best_position):
                particle.best_position = particle.position
                particle.fitness = self.problem_function(particle.position)
            # Step5: 更新全局最优解
            if self.problem_function(particle.position) < self.problem_function(self.global_best_particle.position):
                self.global_best_particle = particle

    def solution(self):
        # Step1: 粒子初始化
        self.init_population()
        for i in range(self.__max_iter):
            self.update_population()
        print('best particle:\nposition: {}\nvelocity: {}'
              '\nfitness: {}\nbest_position: {}'.format(self.global_best_particle.position,
                                                        self.global_best_particle.velocity,
                                                        self.global_best_particle.fitness,
                                                        self.global_best_particle.best_position))

if __name__ == '__main__':
    algo = ParticleSwarmOptimization()
    algo.solution()

  得到的最优解如下:

best particle:
position: [3.43298001]
velocity: [1.10173139e-09]
fitness: [-6.27707976]
best_position: [3.43298001]

  模拟过程如下:

在这里插入图片描述

代码仓库:IALib[GitHub]

  本篇代码已同步至【智能算法(Python复现)】专栏专属仓库:IALib
  运行IALib库中的PSO算法:

git clone git@github.com:xiayouran/IALib.git
cd examples
python main.py -algo pso

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/497569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年的深度学习入门指南(9) - SIMD和通用GPU编程

2023年的深度学习入门指南(9) - SIMD和通用GPU编程 深度学习从一开始就跟GPU有不解之缘&#xff0c;因为算力是深度学习不可或缺的一部分。 时至今日&#xff0c;虽然多任务编程早已经深入人心&#xff0c;但是很多同学还没有接触过CPU上的SIMD指令&#xff0c;更不用说GPGPU…

【Segment Anything Model】论文+代码实战调用SAM模型预训练权重+相关论文

上篇文章已经全局初步介绍了SAM和其功能&#xff0c;本篇作为进阶使用。 文章目录 0.前言1.SAM原论文 1️⃣名词&#xff1a;提示分割&#xff0c;分割一切模型&#xff0c;数据标注&#xff0c;零样本&#xff0c;分割一切模型的数据集 2️⃣Introduction 3️⃣Task: prompta…

【五一创作】系统集成项目管理工程师-【11 人力资源】

持续更新。。。。。。。。。。。。。。。 【第十一章】人力资源 3分11.1 项目人力资源管理的定义及有关概念11.1.1 项日人力资源管理及其过程的定义2. 人力资源管理过程【掌握】11.1.2 人力资源管理相关概念11.2 编制项目人力资源管理计划11.2.1制定人力资源管理计划的技术和工…

IDEA编译报错:Error:java: 无效的源发行版: 17,一次搞定

出现这种错误的原因可能是&#xff1a; 1.本机默认使用&#xff08;编译&#xff09;的jdk与该项目所使用的jdk版本不同。 2.jdk版本不适用于这个Idea&#xff0c;很典型的一个例子就是使用的Idea是2020的&#xff0c;而你用到的jdk是17&#xff0c;jdk17是2021年推出的&#…

【K8S系列】深入解析Job

序言 你只管努力&#xff0c;其他交给时间&#xff0c;时间会证明一切。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用来标记二级论点 Kubernetes (k8s) 是一个容器编排平台&#x…

UDP的报文结构

UDP 报文结构 基本上所有的教科书上都是这样画的图, 但实际上 UDP 报文结构不是这样的, 这样显示应该是容易排版. 正确应该如下图 : 端口号 : 每个端口号在 UDP 报文里占两个字节, 取值范围就是: 0 ~ 65535 源 ip 和源端口描述了数据从哪里来, 目的 ip 和目的端口描述了数据去哪…

操作系统基础知识介绍之指令集体系结构:RISC-V寄存器(掺杂与ARM和X86部分比对)

ra : 返回地址寄存器&#xff0c;用来保存函数或宏的返回地址 。 sp : 栈指针寄存器&#xff0c;用来指向栈顶的内存地址 。 gp : 全局指针寄存器&#xff0c;用来指向全局变量的内存地址 。 tp : 线程指针寄存器&#xff0c;用来指向线程局部变量的内存地址 。 t0 - t6 : 临时…

OpenGL加载模型 之网格

基础知识点 我们的工作就是去解析这些导出的模型文件&#xff0c;并将其中的模型数据存储为OpenGL能够使用的数据。一个常见的问题是&#xff0c;导出的模型文件通常有几十种格式&#xff0c;不同的工具会根据不同的文件协议把模型数据导出到不同格式的模型文件中。有的模型文…

【镜像取证篇】仿真碎片-记一次镜像仿真失败的复盘过程

【镜像取证篇】仿真碎片-记一次镜像仿真失败的复盘过程 这个是很久以前的一个镜像实验&#xff0c;当时仿真可以看到Windows的启动界面&#xff0c;但却一直无法正常进入系统&#xff0c;不断的尝试修复&#xff0c;都是显示错误&#xff0c;最后把类型改为IDE后&#xff0c;成…

ESP32-设备驱动TMP102数字温度传感器驱动

TMP102数字温度传感器驱动 文章目录 TMP102数字温度传感器驱动1、TMP102介绍2、硬件准备3、软件准备4、驱动实现1、TMP102介绍 TMP102 器件是一款数字温度传感器,非常适合需要高精度的 NTC/PTC 热敏电阻更换。 该器件提供 0.5C 的精度,无需校准或外部组件信号调理。 器件温度…

Spring Task

1.1介绍 Spring Task是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 定位&#xff1a;定时任务框架 作用&#xff1a;定时自动执行某段Java代码 为什么要在Java程序中使用Spring Task&#xff1f; 应用场景&#xff1a; 1).信用卡每…

C learning_11 (数组和在内存存储的理解、数组越界、数组作为形参)

目录 数组的理解 数组越界 数组作为函数参数 数组的理解 数组的含义 在C语言中&#xff0c;用于存储多个相同类型的元素。它可以被简单地定义为包含多个元素的容器。数组中每个元素都可以通过索引来访问&#xff0c;索引从零开始递增。 C语言中的数组可以包含任何基本数据类…

力扣---LeetCode141/142. 环形链表 (I)和(II) (代码详解+流程图+数学逻辑拓展)

文章目录 前言141. 环形链表 I1.1 链接&#xff1a;1.2 思路&#xff1a;1.3 代码&#xff1a;快慢指针1.4 流程图&#xff1a; 142. 环形链表 II2.1 链接&#xff1a;2.2 思路&#xff1a;2.3 代码&#xff1a;2.4 流程图&#xff1a; 拓展问题及证明(面试常问)&#xff1a;3.…

【雅特力】单片机AT32F421系列入门资料

1. 命名规则 AT32 全系列MCU选型手册.PDF AT32F421F8P7 AT32F421C8T7 (雅特力厂商送样的两个芯片版本) 2. 数据手册 【 数据手册】AT32F421系列引脚定义、电气特性与封装特性.PDF 3. 技术手册 【技术手册】AT32F421系列各外设(Peripheral)完整说明与各寄存器(Register)定…

[架构之路-190]-《软考-系统分析师》-4-据通信与计算机网络-5-图解CRC计算方法与步骤

目录 一、概述&#xff1a; 二、实战演示 假设&#xff1a; 第1步&#xff1a;把多项多项式转化为除数 第2步&#xff1a;把发送数据转换为被除数&#xff1a;在信息序列后加0 第3步&#xff1a;信息序列除以多项式序列 第4步&#xff1a;获得余数&#xff08;CRC校验值…

OpenCV4.x图像处理实例-搭建身份识别系统

搭建身份识别系统 文章目录 搭建身份识别系统1、人脸识别系统介绍2、人脸特征数据提取3、人脸识别模型训练4、从静态图像进行身份识别5、从视频流识别身份在本文中,将介绍如何使用 OpenCV 搭建一个人脸检测与身份识别系统。 为了构建我们的人脸识别系统,我们将首先执行人脸检…

对称加密与非对称加密、证书、SSL/TLS握手过程

文章目录 对称加密(Symmetrical Encryption)&#xff1a;非对称加密(Asymmetric Encryption)&#xff1a;区别&#xff1a;SSL证书TLS1.2握手过程 对称加密(Symmetrical Encryption)&#xff1a; 对称加密&#xff0c;是一种既简单速度又快的加密方式&#xff0c;加密与解密使用…

大数据之PySpark的RDD介绍

文章目录 前言一、RDD简介二、RDD的特性三、RDD的特点总结 前言 #博学谷IT学习技术支持# 之前的文章主要介绍Spark基础知识&#xff0c;例如集群角色、Spark集群运行流程等&#xff0c;接下来会进一步讨论Spark相对核心的知识&#xff0c;让我们拭目以待&#xff0c;同时也期待…

Linux安装Harbor亲测成功

Harbor简介 Harbor 是为企业用户设计的容器镜像仓库开源项目&#xff0c;包括了权限管理(RBAC)、LDAP、审计、安全漏洞扫描、镜像验真、管理界面、自我注册、HA 等企业必需的功能&#xff0c;同时针对中国用户的特点&#xff0c;设计镜像复制和中文支持等功能。 虽然Docker官方…

Android framework学习指南之Launcher启动过程原理分析

前言 Launcher是一个用来显示系统中已经安装的应用程序的应用程序&#xff0c;Launcher 在启动过程中会请求PackageManagerService 返回系统中已经安装的应用程序的信息&#xff0c;并将这些信息封装成一个快捷图标列表显示在系统屏幕上&#xff0c;这样用户可以通过点击这些快…