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

news/2024/4/26 5:50:53/文章来源:https://blog.csdn.net/weixin_52401264/article/details/128096576

实现 函数 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 pltw = 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])  # 初始化粒子的历史最佳位置向量,初始时刻即当前位置returndef 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  # 更新速度向量returndef updatePosition(self):""" 更新位置向量 """for i in range(dimension):self.pos[i] = self.pos[i] + self.velocity[i]returndef 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_maxelif v < v_min:self.velocity[i] = v_minreturnclass 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].pBestif self.f(pBest) > self.f(self.gBest):  # 在我们看来,适应度self.gBest = pBestreturndef 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].pBestif self.f(pBest) > self.f(self.gBest):  # 将每个粒子的最佳位置和粒子群最佳位置比较,从而获得最好的位置self.gBest = pBestself.visual_x.append(i)self.visual_y.append(self.optimizeFun.fun(self.gBest[0], self.gBest[1]))return self.gBestdef 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_06self.fun = self.__f06self.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 * x2def __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.luyixian.cn/news_show_38994.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Echart 柱状图,X轴斜着展示

option { color: [‘#3398DB’], tooltip: { trigger: ‘axis’, axisPointer: { // 坐标轴指示器&#xff0c;坐标轴触发有效 type: ‘shadow’ // 默认为直线&#xff0c;可选为&#xff1a;‘line’ | ‘shadow’ } }, grid: { left: ‘3%’, right: ‘4%’, bottom: ‘3%’…

iPhone升级iOS 16后出现提示“面容ID不可用”怎么办?

最近&#xff0c;很多用户在苹果社区反馈&#xff0c;iPhone升级iOS 16后Face ID不能用了&#xff0c;尝试重置Face ID时&#xff0c;系统会弹窗提示“面容ID不可用&#xff0c;稍后尝试设置面容ID。” 如果你的iPhone在没有摔落手机或是手机进水的情况下出现这个弹窗&#xff…

【uniapp小程序】路由跳转navigator传参封装

文章目录&#x1f34d;前言&#x1f34b;正文1、看官网1.1 navigator API 介绍1.2、路由跳转参数传递1.3、五种常见的跳转方式1.3.1 uni.navigateTo(OBJECT)1.3.2 uni.redirectTo(OBJECT)1.3.3 uni.reLaunch(OBJECT)1.3.4 uni.switchTab(OBJECT)1.3.5 uni.navigateBack(OBJECT)…

图的初识·基本概念

文章目录基本概念图有两种基本形式无向图的表示有向图的表示基本概念 图结构也是数据结构的一部分。而且还有一点小难。图是由多个结点链接而成的&#xff0c;但是一个结点可以同时连接多个其他结点&#xff0c;多个节点也可以同时指向一个节点。【多对多的关系】 图结构是任意…

如何从报表控件FastReport .NET中连接到 PostgreSQL 数据库?

FastReport.NET官方版下载 Fastreport是目前世界上主流的图表控件&#xff0c;具有超高性价比&#xff0c;以更具成本优势的价格&#xff0c;便能提供功能齐全的报表解决方案&#xff0c;连续三年蝉联全球文档创建组件和库的“ Top 50 Publishers”奖。 慧都科技是Fast Repor…

mysql索引类别和失效场景

首先&#xff0c;我们为什么要使用索引&#xff0c;索引有什么作用呢&#xff1f; 索引可以用来快速查询数据表中有某一特定值的记录&#xff0c;大大加快数据的查询速度&#xff1b;在列上创建了索引之后&#xff0c;查找数据时可以直接根据该列上的索引找到对应记录行的位置…

YOLO X 改进详解

YOLO X 主要改进&#xff1a; Anchor-Free: FCOSDecoupled detection headAdvanced label assigning strategy Network structure improvement Decoupled detection head 对比于YOLO V5, YOLO X 在detection head上有了改进。YOLO V5中&#xff0c;检测头是通过卷积同时预…

视频编解码 - RTP 与 RTCP

目录 RTP 实时传输协议 RTCP协议 将H264 RTP打包 RTP 实时传输协议 音视频数据传输&#xff0c;先将原始数据经过编码压缩后&#xff0c;将码流打包成一个个RTP包&#xff0c;再将码流传输到接收端。 打包的作用 接收端要正确地使用这些音视频编码数据&#xff0c;不仅仅需…

JaVers:自动化数据审计

在开发应用程序时&#xff0c;我们经常需要存储有关数据如何随时间变化的信息。此信息可用于更轻松地调试应用程序并满足设计要求。在本文中&#xff0c;我们将讨论 JaVers 工具&#xff0c;该工具允许您通过记录数据库实体状态的更改来自动执行此过程。 Javers如何工作&#x…

vue Router

Vue项目各文件含义 1.src文件夹 是我们真正敲代码的文件夹&#xff0c; 2.assets放静态资源 3.components放组件 4.App.vue主组件 5.main.js项目的入口文件 Vue Router 在router/index.js路由文件中配置路由&#xff0c;设置路由跳转规则 import Vue from vue import Vu…

android Framework 中用到了哪些跨进程通信方式?

文章目录Linux 有哪些跨进程的通信方式&#xff1f;管道本地 Socket共享内存信号Linux 有哪些跨进程的通信方式&#xff1f; Binder 机制是Android基于Linux的一种独特的IPC机制。我们常用的AMS&#xff0c;PMS 等都是通过Binder机制来完成跨进程通信的&#xff0c;那么除了Bin…

【并发】深入理解Java线程的底层原理

线程基础知识 线程与进程 进程 操作系统会以进程为单位&#xff0c;分配系统资源&#xff08;CPU时间片、内存等资源&#xff09;&#xff0c;进程是资源分配的最小单位。 当一个程序被运行&#xff0c;从磁盘加载这个程序的代码至内存&#xff0c;这时就开启了一个进程。 线…

使用 Mason 创建自己的 Flutter brick

使用 Mason 创建自己的 Flutter brick 原文 https://medium.com/gytworkz/create-your-own-flutter-brick-using-mason-7abc70d0324e 前言 谁不喜欢用最少的努力完成大部分事情呢&#xff1f;我当然知道! &#xff01;Mason 帮我完成了几个简单的步骤。 在本文中&#xff0c;我…

Redis——》数据类型:List(列表)

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 Redis——》数据类型&#xff1a;List&#xff08;列表&#xff09;一、简介…

复现黑客在后门中藏匿后门

PHP实现在后门中藏匿后门 在攻击渗透的时候会传入shell后门方便进行远控。其中的后门包括多种类型&#xff0c;大马是功能最全的直接提供了可视化的界面方便攻击者进行提权、扫描、上传等一系列的操作。 但有很多hacker不讲武德&#xff0c;在写好的大马中藏入自己的后门&…

VBA Regex 正则表达式应用介绍

. VBA正则表达式介绍 正则表达式或 RegEx 用于在字符串中查找特定的字符。 本文将展示一个 VBA RegEx 示例,并演示为什么在 VBA 中使用正则表达式如此强大。 正则表达式是一个比较大的话题,关于这方面的书很多。 同时也是一个让许多人感到害怕的话题,因为它的语法比较神秘和…

C++入门笔记

C 入门笔记Functions in CC header Files下面主要是我学习C的一个笔记&#xff0c;记录学习中遇到的一些重点事项。下面是视频的连接https://www.bilibili.com/video/BV1Ay4y1i7Z6/?p10&spm_id_from333.1007.top_right_bar_window_history.content.click&vd_sourcee6e…

记录--两行CSS让页面提升了近7倍渲染性能!

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 对于前端人员来讲&#xff0c;最令人头疼的应该就是页面性能了&#xff0c;当用户在访问一个页面时&#xff0c;总是希望它能够快速呈现在眼前并且是可交互状态。如果页面加载过慢&#xff0c;你…

第四章. Pandas进阶—时间序列

第四章. Pandas进阶 4.9 时间序列 1.重采样&#xff08;resample&#xff09; 在Pandas中&#xff0c;对时间序列频率的调整称为重采样&#xff0c;即时间序列从一个频率转换到另一个频率的过程&#xff0c;由周统计变成月统计 1).语法&#xff1a; 4.8章 第4点 已介绍过&…

MySQL数据库行级锁之间隙锁、临键锁

间隙锁 默认情况下&#xff0c;InnoDB在 REPEATABLE READ事务隔离级别运行&#xff0c;InnoDB使用 next-key 锁进行搜索和索引扫描&#xff0c;以防止幻读。 索引上的等值查询(唯一索引)&#xff0c;给不存在的记录加锁时, 优化为间隙锁 。索引上的等值查询(非唯一普通索引)&…