粒子群算法查找函数最小值

news2024/11/24 13:08:02

实现 函数 F01、F06 的优化测试

以下内容是现有算法的运行结果、调参分析、及代码实现,用于给其他人提供参考,懒得改了hh

1. 运行结果

  1. 参数

    w = 0.5 (可更改)
    c1 = 2.0 (可更改)
    c2 = 2.0 (可更改)
    swarmSize = 30 (可更改)
    v_max = 5 (可更改)
    v_min = -5 (可更改)
    dimension = 2
    iterations = 1000 (可更改)

  2. 输出(因为粒子群算法有一定随机性,所以给出三组输出样例)

    • 第一组

      • 控制台

      • 收敛图像

    • 第二组

    • 第三组

  3. 小结:根据上述输出我们知道,在上述参数的配置下,函数收敛情况不错,并且最终也得到了相当高精度的结果,即解向量特别趋近于 [0,0] 了

2. 调参分析

  1. 为什么要调参?粒子群算法的核心是个体位置和速度的更新,而个体位置和速度的更新取决于其自身因素(自身速度),社会因素(粒子群最佳位置),认知因素(历史最佳位置)决定,因此每一个因素的变化都会导致算法收敛程度的改变
  2. 调参——自身因素,因为自身因素包括惯性权重和原本速度两个方面,因此我们可以对惯性权重和速度范围进行调整,并观察结果
    • 在其他参数不变的情况下,w = 0.9,我们发现函数收敛情况变得不好了

    • w = 0.1,我们发现,函数收敛情况变好了


    • 小结:惯性权重减少,使得粒子探索空间的能力减弱,但是收敛的精度大大提高。因为这里测试的两个函数是单峰函数,因此不需要考虑因为w过小导致粒子群陷入局部优化的问题,因此可以推导,对于单峰函数的优化,w 取小一点效果会更好。另外,更改 v_min\v_max 一定程度上也是更改粒子群的搜索空间的广度,与更改 w 具有类似的作用,故而不进行调参测试

  3. 调参——社会因素&认知因素
    • 在其他参数不变的情况下,c1 = 1.0,c2=3.0,即社会因素更强,相比于初始情况,没有过大变化


    • c1 = 3.5, c2 = 0.5,显然,F06 收敛效果变好,即当粒子的运动更多关注自身历史最佳位置时,其搜索效果可能会改变


3. 代码实现

import random
import math
from matplotlib import pyplot as plt

w = 0.5  # 惯性权重,①取值大有利于全局搜索,不利于局部搜索,②取值小有利于局部搜索,不利于全局搜索,容易陷入“局部最优”
c1 = 2.0  # “认知部分” 的加速因子
c2 = 2.0  # “社会部分” 的加速因子
swarmSize = 30  # 粒子规模
v_max = 5  # 粒子最大速度
v_min = -5  # 粒子的最小速度

dimension = 2  # 搜索空间的维度,也是位置向量和速度向量的维度,也是粒子的维度
iterations = 100  # 收敛次数/迭代次数


class Particle:
    """ 粒子群中粒子的定义 """

    def __init__(self, domain):
        """ 粒子初始化 """
        self.velocity = []  # 速度向量
        self.pos = []  # 位置向量
        self.pBest = []  # 最佳位置
        self.domain = domain  # 二维向量,表示粒子位置向量每个维度变量的取值范围(这里规定粒子每个维度的变量的取值范围相同)

        for i in range(dimension):
            self.pos.append((domain[1] - domain[0]) *
                            random.random() + domain[0])  # 初始化粒子的位置向量,随机数范围在 [下限,上限)
            self.velocity.append(0.01 * random.random() +
                                 v_min)  # 初始化粒子的速度向量,随机数范围在 [v_min,v_max)
            self.pBest.append(self.pos[i])  # 初始化粒子的历史最佳位置向量,初始时刻即当前位置
        return

    def updateVelocity(self, gBest):
        """ 更新速度向量 """
        ''' gBest 表示当前粒子群的最优位置,需要作参数传入 '''
        for i in range(dimension):
            r1 = random.random()
            r2 = random.random()
            cognitive = c1 * r1 * (self.pBest[i] - self.pos[i])  # 认知部分的分量
            social = c2 * r2 * (gBest[i] - self.pos[i])  # 社会部分的分量
            self.velocity[i] = w * self.velocity[i] + \
                               cognitive + social  # 更新速度向量
        return

    def updatePosition(self):
        """ 更新位置向量 """
        for i in range(dimension):
            self.pos[i] = self.pos[i] + self.velocity[i]
        return

    def satisfyConstraints(self):
        """ 让当前粒子的位置向量和速度向量满足限制条件 """
        for i in range(dimension):
            x = self.pos[i]  # 满足位置向量的限制条件,即应该在其取值范围之间

            if x > self.domain[1]:
                self.pos[i] = self.domain[1]
            elif x < self.domain[0]:
                self.pos[i] = self.domain[0]

            v = self.velocity[i]  # 更新速度向量的限制条件,即应该在 [v_min, v_max] 范围内
            if v > v_max:
                self.velocity[i] = v_max
            elif v < v_min:
                self.velocity[i] = v_min
        return


class ParticleSwarmOptimizer:
    """ POS 优化器的定义 """

    def __init__(self, optimizeFun):
        """ 优化器的初始化:即初始化一个粒子种群 """
        self.swarm = []  # 粒子群
        self.gBest = []  # 粒子群的最佳位置

        self.visual_y = []  # 作图纵坐标,用于记录每次迭代粒子群最佳位置的函数值
        self.visual_x = []  # 作图横坐标,用于记录迭代次数

        self.optimizeFun = optimizeFun  # 函数类的实例对象

        for i in range(swarmSize):
            particle = Particle(self.optimizeFun.domain)
            self.swarm.append(particle)  # 初始化一个粒子种群

        self.gBest = self.swarm[0].pBest  # 获取粒子群初始状态的最佳位置
        for i in range(swarmSize):
            pBest = self.swarm[i].pBest
            if self.f(pBest) > self.f(self.gBest):  # 在我们看来,适应度
                self.gBest = pBest

        return

    def optimize(self):
        """ 优化函数 """
        for i in range(iterations):
            ''' STEP 1 更新每个粒子的速度向量、位置向量 '''
            for k in range(swarmSize):
                self.swarm[k].updateVelocity(self.gBest)
                self.swarm[k].updatePosition()
                self.swarm[k].satisfyConstraints()

            ''' STEP 2 更新每个粒子的历史最佳位置 '''
            for l in range(swarmSize):
                if self.f(self.swarm[l].pos) > self.f(self.swarm[l].pBest):
                    self.swarm[l].pBest = self.swarm[l].pos

            ''' STEP 3 找到全局最佳值 '''
            for j in range(swarmSize):
                pBest = self.swarm[j].pBest
                if self.f(pBest) > self.f(self.gBest):  # 将每个粒子的最佳位置和粒子群最佳位置比较,从而获得最好的位置
                    self.gBest = pBest

            self.visual_x.append(i)
            self.visual_y.append(self.optimizeFun.fun(self.gBest[0], self.gBest[1]))

        return self.gBest

    def f(self, solution):
        """ 计算 solution 的函数值,因为我们用于查找最小值,所以函数值取负值就是适应值 """
        return -self.optimizeFun.fun(solution[0], solution[1])

    def visualize(self):
        plt.title("Function Convergent Image")  # 图片标题
        plt.xlabel("iterations")  # x 轴变量名称
        plt.ylabel("Value Of Function")  # y 轴变量名称
        plt.plot(self.visual_x, self.visual_y, label=self.optimizeFun.funName)  # 逐点画图

        plt.legend()  # 画出曲线图标
        plt.show()  # 画出图像


class OptimizeFunctions:
    """ 函数类,其中存储了待优化的函数及其变量的取值范围(我们假定函数自变量每个维度的取值范围相同) """

    def __init__(self, key):
        """ 根据传入的 key 初始化 domain 和 fun """
        if key == 1:
            self.domain = self.__domain_01  # 存储变量的取值范围
            self.fun = self.__f01  # 存储用于优化的函数
            self.funName = r"$f(x)=\Sigma_{i=1}^nx_i^2$"  # 特定格式的函数表达式字符串
        elif key == 6:
            self.domain = self.__domain_06
            self.fun = self.__f06
            self.funName = r"$f(x)=20[1-e^{-0.2\sqrt{\frac{1}{2}\Sigma_{i=1}^2x_i^2}}]+e-e^{\frac{1}{2}\Sigma_{i=1}^2cos2\pi x_i}$"

    __domain_01 = [-100, 100]
    __domain_06 = [-32, 32]

    def __f01(self, x1, x2):
        return x1 * x1 + x2 * x2

    def __f06(self, x1, x2):
        return 20 * (1 - math.exp(-0.2 * math.sqrt(0.5 * (x1 * x1 + x2 * x2)))) + math.exp(1) - math.exp(
            0.5 * (math.cos(2 * math.pi * x1) + math.cos(2 * math.pi * x2)))


def main():
    optimizeFun = OptimizeFunctions(1)
    optimizer = ParticleSwarmOptimizer(optimizeFun)
    x = optimizer.optimize()
    optimizer.visualize()
    print("函数 01 优化得到最小值位置为", x)

    optimizeFun = OptimizeFunctions(6)
    optimizer = ParticleSwarmOptimizer(optimizeFun)
    x = optimizer.optimize()
    optimizer.visualize()
    print("函数 06 优化得到最小值位置为", x)


if __name__ == '__main__':
    main()

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

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

相关文章

2.每天进步一点点-Python爬虫需要了解一下基础的web相关内容

14天学习训练营导师课程&#xff1a; 杨鑫《Python 自学编程基础》 杨鑫《 Python 网络爬虫基础》 杨鑫《 Scrapy 爬虫框架实战和项目管理》 文章目录1.网络请求过程1.1通过 URL 查找服务器 IP1.2三次握手建立 TCP 连接1.3发送 HTTP 请求1.4服务器响应请求1.5浏览器解析 HTML1.…

21年-自研-笔试题

目录背景题目1、Object的常用方法2、 和 equals 的区别是什么&#xff1f;equals3、以下代码的运行结果4、以下代码的运行结果5、String, StringBuilder&#xff0c;StringBuffer6、ArrayList和LinkedList7、一些常用的线程安全的集合类8、以下代码的运行结果9、完成下面的代码…

Java环境准备——JDK下载和安装、IDEA下载和安装

一、JDK下载及安装 1、必要性&#xff1a;JDK是整个Java开发的核心。 2、下载网址&#xff1a;Java Downloads | Oracle 3、选择下载JDK17的原因&#xff1a;JDK17 是Java的长期支持版本。 4、下载到本地后&#xff0c;双击进行安装&#xff0c;然后点击下一步&#xff0c;安…

AI物品分类识别管理系统uniapp源码带文档教程

技术架构 技术框架&#xff1a;SpringBoot2 Mysql5.7 Mybatis-Plus uniapp Swagger2 RuoYi-fast swagger-bootstrap-ui 运行环境&#xff1a;jdk8 IntelliJ IDEA maven 宝塔面板 百度智能云平台服务 本地api接口端搭建教程 后端需要准备相关的IDE和JDK8开发环境 , 前…

GIT技巧

目录 基础命令 commit 、branch merge rebase 高级特性 自由修改提交树 cherry-pick rebase 远程仓库命令 基础命令 commit 、branch Git Commit Git 仓库中的提交记录保存的是你的目录下所有文件的快照&#xff0c;就像是把整个目录复制&#xff0c;然后再粘贴一样…

Linux内核中ideapad-laptop.c文件全解析6

接前一篇文章《Linux内核中ideapad-laptop.c文件全解析5》&#xff0c;地址为&#xff1a; Linux内核中ideapad-laptop.c文件全解析5_蓝天居士的博客-CSDN博客 上一篇详细分析了ideapad_debugfs_init&#xff0c;本篇详细分析ideapad_input_init。 ideapad_input_init ideap…

Word控件Spire.Doc 【图像形状】教程(7): 如何使用 C# 在 Word 中替换图像

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

b站黑马JavaScript的Ajax案例代码——聊天机器人案例

目录 目标效果&#xff1a; 更换的新接口&#xff1a; 1.机器人智能回复接口&#xff1a;http://www.liulongbin.top:3006/api/robot 2.机器人语音接口&#xff1a;http://www.liulongbin.top:3006/api/synthesize 重点原理&#xff1a; 1.jQuery中trim方法 2.jquery中a…

Hive数据查询语言-DQL-含示例演练(Select查询数据、Join查询)

文章目录1. Select查询数据1.1 基础语法1.1.1 select_ecpr1.1.2 ALL、DISTINCT1.1.3 WHERE1.1.4 分区查询、分区裁剪1.1.5 GROUP BY1.1.6 HAVING1.1.7 LIMIT1.1.8 执行顺序1.2 高阶语法1.2.1 ORDER BY1.2.2 CLUSTER BY1.2.4 Union联合查询1.2.5 from子查询&#xff08;Subqueri…

Allegro自动沿着目标任意形状走线操作指导

Allegro自动沿着目标任意形状走线操作指导 Allegro有个非常好用的功能,支持自动沿着目标任意形状走线,对于异形板框走线尤其方便,以下图为例,需要沿着这个外形走一段线 具体操作如下 点击add connect命令 点击空白处 鼠标右击选择contour命令 出现一个对话框,当前是…

03【Spring AOP、CGBLIB代理】

文章目录03【Spring AOP、CGBLIB代理】一、AOP前奏1.1 案例1.1.1 需求设计1.1.2 需求修改1.1.3 需求增加1.1.4 分析存在的问题1.2 动态代理1.2.1 定义接口&#xff1a;1.2.2 日志代理类1.2.3 缓存代理类&#xff1a;1.2.4 测试类二、AOP2.1 AOP 概述2.1.1 纵向编程2.1.2 纵横配…

【Java进阶篇】第六章 IO流

文章目录一、IO流的概述1、流2、流的分类3、Java IO流的四大块4、流的两大特性5、java.io包下的16个常用流二、文件专属流1、java.io.FileInputStream2、java.io.FileOutputStream3、java.io.FileReader4、java.io.FileWriter三、缓冲流与转换流1、java.io.BufferedReader2、ja…

【面试题】深度解析Java多线程中的 run() 与 start() 有什么区别?

【面试题】深度解析Java多线程中的 run() 与 start() 有什么区别&#xff1f; 大多数人的回答 start() run() 深入底层源码的解析 run() 与 start() 为什么我们不能直接调用 run() 方法&#xff1f; 如何证明 start() 会调用 run() 方法&#xff1f; JVM -> OS执行全…

Nodejs -- 数据库基本概念的介绍及在Express中操作数据库

文章目录1. 数据库的基本概念1.1 什么是数据库1.2 常见的数据库及分类1.3 传统型数据库的数据组织结构1.3.1 Excel的数据组织结构1.3.2 传统型数据库的数据组织结构1.3.3 实际开发中库、表、行、字段的关系2. 在Express中操作MySQL2.1 在项目中操作数据库的步骤2.2 安装与配置m…

Java编程案例:买飞机票

编程案例&#xff1a; 一、目的 复习前半段课程学习的Java编程知识&#xff0c;能够使用所学的知识解决问题&#xff0c;提升同学们的编程能力。 二、涉及到的知识点 变量、数组。运算符&#xff1a;基本运算符、关系运算符、逻辑运算符…程序流程控制&#xff1a;if、switc…

np.meshgrid()函数

文章目录(1)自己理解(2)官方解释(3)参数:3.1 x1, x2,…, xn:array_like3.2 sparse:bool, optional 默认false3.3 copy:bool, optional(1)自己理解 np.meshgrid(a, b,indexing "xy") 函数会返回 b.shape() 行 &#xff0c;a.shape() 列的二维数组。 因此 i, j 都是 …

【序列召回推荐】(task6)多兴趣召回Comirec-SA

note Comirec-SA基于attention的多兴趣建模&#xff0c;论文中先通过attention提取单一兴趣&#xff0c;再推广到多兴趣建模。另外使用贪心算法优化带有准确度多样性的目标函数。DR把MIND的attention换成argmax&#xff08;还有初始化方式不同、序列胶囊到兴趣胶囊用可学习权重…

2.线性代数基础

1.矩阵 2. 特殊矩阵 正交矩阵 AATE&#xff08;E为单位矩阵&#xff0c;AT表示“矩阵A的转置矩阵”。&#xff09;或ATAE&#xff0c;则n阶实矩阵A称为正交矩阵 正交矩阵有如下性质&#xff1a; A是正交矩阵&#xff0c;AT也是正交矩阵A的各行是单位向量且两两正交&#xff0…

html实现ezuikit.js萤石云直播监控,ezuikit.js实时监控实现,萤石云实时监控简单实现

效果图 实现 下面的播放url获取&#xff1a;登录萤石云->控制台->我的资源->设备列表->列表中&#xff1a;查看通道->监控地址 appKey和appSecret获取&#xff1a;登录萤石云->控制台->我的账号->应用信息->右侧&#xff1a;应用密钥 下载ezuikit…

(服务器客户端)网络通信是怎么实现的?7000字爆肝----原来java网络编程技术功不可没(多线程,URL,InetAddressm,TCP,UDP)集结

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏 java ⭐java网络编程技术⭐ 文章目录⭐java网络编程技术⭐&#x1f468;‍&#x1f4bb;一&#xff0c;URL类…