粒子群优化算法的实践

粒子群优化算法的实践

flyfish

粒子群优化算法(Particle Swarm Optimization,PSO)或者粒子群算法
红叉的地方是理想之地,这些粒子都想去,总结8个字是信息共享,个人决策。

在这里插入图片描述

上完图之后,上代码,再解释

纯纯的PSO实现

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
np.set_printoptions(precision = 4)
# 目标函数
def f(x,y):return (x-3.14)**2 + (y-3.14)**2 + np.sin(3*x+3.14) + np.cos(4*y-3.14)# 绘制三维函数
x, y = np.array(np.meshgrid(np.linspace(0,5,100), np.linspace(0,5,100)))
z = f(x, y)# 求出全局最小值 
x_min = np.around(x.ravel()[z.argmin()],4)
y_min = np.around(y.ravel()[z.argmin()],4)
print("x_min:",x_min)
print("y_min:",y_min)
# 算法的超参数
c1 = c2 = 0.1 #个体记忆 #集体记忆
w = 0.8 #惯性权重  inertia weight constant.# 创建 particles
n_particles = 20 #  20个粒子
np.random.seed(100)
X = np.random.rand(2, n_particles) * 5
V = np.random.randn(2, n_particles) * 0.1print("X:",X)
print("V:",V)# 初始化数据 
pbest = X #  p= personal = cognitive 
pbest_obj = f(X[0], X[1])
gbest = pbest[:, pbest_obj.argmin()]  #g= global = social
gbest_obj = pbest_obj.min()# 迭代一次粒子群优化
def update():global V, X, pbest, pbest_obj, gbest, gbest_obj# 更新参数r1, r2 = np.random.rand(2)V = w * V + c1*r1*(pbest - X) + c2*r2*(gbest.reshape(-1,1)-X)X = X + Vobj = f(X[0], X[1])pbest[:, (pbest_obj >= obj)] = X[:, (pbest_obj >= obj)]pbest_obj = np.array([pbest_obj, obj]).min(axis=0)gbest = pbest[:, pbest_obj.argmin()]gbest_obj = pbest_obj.min()# 等高线图
fig, ax = plt.subplots(figsize=(8,6))
fig.set_tight_layout(True)
img = ax.imshow(z, extent=[0, 5, 0, 5], origin='lower', cmap='viridis', alpha=0.5)
fig.colorbar(img, ax=ax)
ax.plot([x_min], [y_min], marker='x', markersize=5, color="red")
contours = ax.contour(x, y, z, 10, colors='black', alpha=0.4)
ax.clabel(contours, inline=True, fontsize=8, fmt="%.0f")
pbest_plot = ax.scatter(pbest[0], pbest[1], marker='o', color='black', alpha=0.5)
p_plot = ax.scatter(X[0], X[1], marker='o', color='blue', alpha=0.5)
p_arrow = ax.quiver(X[0], X[1], V[0], V[1], color='blue', width=0.005, angles='xy', scale_units='xy', scale=1)
gbest_plot = plt.scatter([gbest[0]], [gbest[1]], marker='*', s=100, color='black', alpha=0.4)
ax.set_xlim([0,5])
ax.set_ylim([0,5])# 粒子群算法的步骤:算法更新和图形显示
def animate(i):title = 'Iteration {:02d}'.format(i)# 更新参数update()# 绘图ax.set_title(title)pbest_plot.set_offsets(pbest.T)p_plot.set_offsets(X.T)p_arrow.set_offsets(X.T)p_arrow.set_UVC(V[0], V[1])gbest_plot.set_offsets(gbest.reshape(1,-1))return ax, pbest_plot, p_plot, p_arrow, gbest_plotanim = FuncAnimation(fig, animate, frames=list(range(1,20)), interval=200, blit=False, repeat=True)
anim.save("PSO_1.gif", dpi=120, writer="imagemagick")print("PSO found best solution at f({})={}".format(gbest, ((gbest_obj))))
print("Global optimal at f({})={}".format([x_min,y_min], (f(x_min,y_min))))

输出

x_min: 2.7273
y_min: 3.1313
X: [[2.717  1.3918 2.1226 4.2239 0.0236 0.6078 3.3537 4.1293 0.6835 2.87554.4566 1.046  0.9266 0.5419 1.0985 4.8931 4.0584 0.8597 4.0811 1.3704][2.1585 4.7001 4.0882 1.6806 0.8771 1.8642 0.0284 1.2621 3.9783 0.07632.9942 3.019  0.5257 1.9097 0.1824 4.4521 4.9046 0.2997 4.4527 2.8845]]
V: [[ 0.0731  0.1362 -0.0326  0.0056  0.0222 -0.1443 -0.0756  0.0816  0.075-0.0456  0.119  -0.1691 -0.1356 -0.1232 -0.0544 -0.0668  0.0007 -0.06130.13   -0.1733][-0.0983  0.0358 -0.1614  0.1471 -0.1188 -0.055  -0.094  -0.0828  0.01090.0508 -0.0862  0.1249 -0.008  -0.089  -0.0882  0.0019  0.0238  0.0014-0.1636 -0.1044]]
PSO found best solution at f([2.7157 3.1329])=-1.7771745572809252
Global optimal at f([2.7273, 3.1313])=-1.7760464968972247

目标函数
f ( x , y ) = ( x − 3.14 ) 2 + ( y − 3.14 ) 2 + sin ⁡ ( 3 x + 1.41 ) + cos ⁡ ( 4 y − 3.14 ) f(x,y) = (x-3.14)^2 + (y-3.14)^2 + \sin(3x+1.41) + \cos(4y-3.14) f(x,y)=(x3.14)2+(y3.14)2+sin(3x+1.41)+cos(4y3.14)

那么,我们如何才能找到这个函数的极小点呢?当然,我们可以采取穷举式搜索:如果我们检查面上每个点的值,我们就可以找到最小点。或者在面上随机找到一些样本点,看看哪个样本点给出的值最低。。然而从形状上也可以注意到,如果找到一个值较小的点,则更容易在其附近找到更小值的点。

假设我们有粒子,我们将粒子 i i i在迭代中的位置表示为 X i ( t ) X^i(t) Xi(t)
在上面的示例中,我们将其作为坐标 X i ( t ) = ( x i ( t ) , y i ( t ) ) . X^i(t) = (x^i(t), y^i(t)). Xi(t)=(xi(t),yi(t)).
除了位置,我们还有每个粒子的速度,表示为 V i ( t ) = ( v x i ( t ) , v y i ( t ) ) V^i(t)=(v_x^i(t), v_y^i(t)) Vi(t)=(vxi(t),vyi(t))
在下一次迭代中,每个粒子的位置将更新为 X i ( t + 1 ) = X i ( t ) + V i ( t + 1 ) X^i(t+1) = X^i(t)+V^i(t+1) Xi(t+1)=Xi(t)+Vi(t+1)

将大写X,拆成两个小写坐标下x,y表示如下
x i ( t + 1 ) = x i ( t ) + v x i ( t + 1 ) y i ( t + 1 ) = y i ( t ) + v y i ( t + 1 ) \begin{aligned} x^i(t+1) &= x^i(t) + v_x^i(t+1) \\ y^i(t+1) &= y^i(t) + v_y^i(t+1) \end{aligned} xi(t+1)yi(t+1)=xi(t)+vxi(t+1)=yi(t)+vyi(t+1)

同时,速度也根据规则进行更新
V i ( t + 1 ) = w V i ( t ) + c 1 r 1 ( p b e s t i – X i ( t ) ) + c 2 r 2 ( g b e s t – X i ( t ) ) V^i(t+1) = w V^i(t) + c_1r_1(pbest^i – X^i(t)) + c_2r_2(gbest – X^i(t)) Vi(t+1)=wVi(t)+c1r1(pbestiXi(t))+c2r2(gbestXi(t))
同样的公式还有如下
方式1
v i j ( t + 1 ) = w ∗ v i j ( t ) + c p r 1 j ( t ) [ y i j ( t ) − x i j ( t ) ] + c g r 2 j ( t ) [ y ^ j ( t ) − x i j ( t ) ] v_{ij}(t + 1) = w * v_{ij}(t) + c_{p}r_{1j}(t)[y_{ij}(t) − x_{ij}(t)] + c_{g}r_{2j}(t)[\hat{y}_{j}(t) − x_{ij}(t)] vij(t+1)=wvij(t)+cpr1j(t)[yij(t)xij(t)]+cgr2j(t)[y^j(t)xij(t)]
方式2

在这里插入图片描述
r1和r2是介于0和1之间的随机数,w,r1,r2是PSO算法的参数

X X X在上述中拆成了小写的 x , y x,y x,y,在代码中就是 X [ 0 ] , X [ 1 ] X[0], X[1] X[0],X[1]
p b e s t i pbest^i pbesti的位置是给出粒子 i i i探索的最好 f ( X ) f(X) f(X)值,Cognitive(personal ) ,代码中的 p b e s t pbest pbest
g b e s t gbest gbest是由群体中的所有粒子探索的,Social(global),代码中的 g b e s t gbest gbest

请注意, p b e s t i pbest^i pbesti X i ( t ) = ( x i ( t ) , y i ( t ) ) . X^i(t) = (x^i(t), y^i(t)). Xi(t)=(xi(t),yi(t)).是两个位置向量

X i ( t ) = ( x i ( t ) , y i ( t ) ) X^i(t) = (x^i(t), y^i(t)) Xi(t)=(xi(t),yi(t))

p b e s t i = ( x i ( t ) , y i ( t ) ) pbest^i=(x^i(t), y^i(t)) pbesti=(xi(t),yi(t)) 粒子 i i i最好的

差异 p b e s t i – X i ( t ) pbest^i – X^i(t) pbestiXi(t)是向量减法。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

使用scikit-opt库实现

pip install scikit-opt

该库封装了7种启发式算法(差分进化算法、遗传算法、粒子群算法、模拟退火算法、蚁群算法、鱼群算法、免疫优化算法)
源码地址

https://github.com/guofei9987/scikit-opt/

在这里插入图片描述
输入

入参	默认值	意义
func	-	目标函数
n_dim	-	目标函数的维度
size_pop	50	种群规模
max_iter	200	最大迭代次数
lb	None	每个参数的最小值
ub	None	每个参数的最大值
w	0.8	惯性权重
c1	0.5	个体记忆
c2	0.5	集体记忆
constraint_ueq	空元组	不等式约束

输出

pso.record_value 每一代的粒子位置、粒子速度、对应的函数值。pso.record_mode = True 才开启记录
pso.gbest_y_hist 历史最优函数值
pso.best_y 最优函数值 (迭代中使用的是 pso.gbest_x, pso.gbest_y)
pso.best_x 最优函数值对应的输入值
import numpy as np
from sko.PSO import PSOdef demo_func(X):x, y = Xreturn (x-3.14)**2 + (y-3.14)**2 + np.sin(3*x+3.14) + np.cos(4*y-3.14)max_iter = 30
# lb	None	每个参数的最小值
# ub	None	每个参数的最大值
pso = PSO(func=demo_func, n_dim=2, pop=40, max_iter=max_iter, lb=[-1, -1], ub=[5, 5])pso.record_mode = True
pso.run()
print('best_x is ', pso.gbest_x, 'best_y is', pso.gbest_y)import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimationrecord_value = pso.record_value
X_list, V_list = record_value['X'], record_value['V']fig, ax = plt.subplots(1, 1)
ax.set_title('title', loc='center')
line = ax.plot([], [], 'b.')X_grid, Y_grid = np.meshgrid(np.linspace(0,5,100), np.linspace(0,5,100))Z_grid = demo_func((X_grid, Y_grid))
ax.contour(X_grid, Y_grid, Z_grid, 10)ax.set_xlim([0,5])
ax.set_ylim([0,5])plt.ion()
p = plt.show()def update_scatter(frame):i, j = frame // 10, frame % 10ax.set_title('iter = ' + str(i))X_tmp = X_list[i] + V_list[i] * j / 10.0plt.setp(line, 'xdata', X_tmp[:, 0], 'ydata', X_tmp[:, 1])return lineani = FuncAnimation(fig, update_scatter, blit=True, interval=25, frames=max_iter * 10)
plt.show()ani.save('PSO_2.gif', writer='pillow')

结果

best_x is  [2.71374964 3.14188032] best_y is [-1.77777509]

增加约束条件实现

在图上画个红色的紧箍,表示理想之地在红色圈内,去那里吧
在这里插入图片描述

import numpy as np
from sko.PSO import PSOdef demo_func(X):x, y = Xreturn (x-3.14)**2 + (y-3.14)**2 + np.sin(3*x+3.14) + np.cos(4*y-3.14)#非线性约束 (x[0] - 1) ** 2 + (x[1] - 1) ** 2 - 1<=0
constraint_ueq = (lambda x: (x[0] - 1) ** 2 + (x[1] - 1) ** 2-1,
)max_iter = 30
# lb	None	每个参数的最小值
# ub	None	每个参数的最大值
pso = PSO(func=demo_func, n_dim=2, pop=40, max_iter=max_iter, lb=[-1, -1], ub=[5, 5],constraint_ueq=constraint_ueq)pso.record_mode = True
pso.run()
print('best_x is ', pso.gbest_x, 'best_y is', pso.gbest_y)import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimationrecord_value = pso.record_value
X_list, V_list = record_value['X'], record_value['V']fig, ax = plt.subplots(1, 1)
ax.set_title('title', loc='center')
line = ax.plot([], [], 'b.')X_grid, Y_grid = np.meshgrid(np.linspace(0,5,100), np.linspace(0,5,100))Z_grid = demo_func((X_grid, Y_grid))
ax.contour(X_grid, Y_grid, Z_grid, 10)ax.set_xlim([0,5])
ax.set_ylim([0,5])draw_circle=plt.Circle((1.8, 1.5), 0.5,fill=False,color='r')
ax.add_artist(draw_circle)plt.ion()
p = plt.show()def update_scatter(frame):i, j = frame // 10, frame % 10ax.set_title('iter = ' + str(i))X_tmp = X_list[i] + V_list[i] * j / 10.0plt.setp(line, 'xdata', X_tmp[:, 0], 'ydata', X_tmp[:, 1])return lineani = FuncAnimation(fig, update_scatter, blit=True, interval=25, frames=max_iter * 10)
plt.show()ani.save('PSO_2.gif', writer='pillow')

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

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

相关文章

Vue JAVA开发常用模板

1.VsCode添加模板 左下角设置》用户代码片段 新建全局代码片段》将模板粘贴仅文件&#xff08;prefix用于指定触发关键字&#xff09; 添加成功过后输入配置的关键字即可使用 1.1 vue2模板 {// Example:"Print to console": {"prefix": "vue2",…

vue实现数字千分位格式化 如6,383,993,037,937.463

1.封装文件&#xff1a;numberToCurrency.js /**实现数字千分位格式化 如6,383,993,037,937.463 */ export function numberToCurrencyNo(value) {if (!value) return 0// 获取整数部分const intPart Math.trunc(value)// 整数部分处理&#xff0c;增加,const intPartFormat …

使用 Go Modules 管理依赖:简明教程

一、GoLang 中包的介绍和定义 包&#xff08;package&#xff09;是多个 Go 源码的集合&#xff0c;是一种高级的代码复用方案Go 语言为我们提供了很多内置包&#xff0c;如 fmt、strconv、strings、sort、errors、times、encoding/json、os、io 等Golang 中的包可以分为三种&…

C++ 实现的Ping类的封装

Ping 使用 Internet 控制消息协议&#xff08;ICMP&#xff09;来测试主机之间的连接。当用户发送一个 ping 请求时&#xff0c;则对应的发送一个 ICMP Echo 请求消息到目标主机&#xff0c;并等待目标主机回复一个 ICMP Echo 回应消息。如果目标主机接收到请求并且网络连接正常…

SpringCloud+Nacos项目集成Seata分布式事务

上一篇&#xff1a; 《 Seata-分布式事务介绍 》&#xff1a; 简单介绍了分布式事务的实现方式&#xff0c;以及详细讲述了Seata-AT模式的两阶段提交步骤流程。 完整示例项目代码地址&#xff1a; https://gitee.com/cnyunze/yz-seata.git Seata快速上手 安装教程Seata Server…

动手学深度学习笔记

1. 深度学习基础与MLP 1.1 框架&#xff1a; 线性回归&#xff1b; Softmax回归&#xff08;实际上用于分类问题&#xff09;&#xff1b; 感知机与多层感知机&#xff1b; 模型选择&#xff1b; 权重衰退&#xff08;weight decay&#xff09;&#xff1b; 丢弃法&…

sql面试题之累计消耗问题

sql中累计求和是我们比较经常遇到的问题&#xff0c;那么与之相反的累计消耗的问题不知你是否挑战过 –问题&#xff1a;在活动大促中&#xff0c;有玩游戏瓜分奖金环节。现有奖金池为3000元&#xff0c;代表奖金池中的初始额度 表中的数据代表每一个用户和其对应的得分&#…

Java 并发编程面试题——Java 线程间通信方式

目录 1.✨Java 线程间有哪些通信方式&#xff1f;1.1.volatile 和 synchronized 关键字1.2.等待/通知机制1.2.1.概述1.2.2.经典范式 1.3.管道输入/输出流1.4.信号量 2.Thread.join() 有什么作用&#xff1f;它的使用场景是什么&#xff1f;3.Java 中需要主线程等待子线程执行完…

java:封装统一的响应体code、data、msg、paging

背景 我们在写接口的时候一般不会直接返回给前端数据&#xff0c;而是会有响应体&#xff0c;比如 code、data、msg&#xff0c;这样就有一个统一的结构方便前端处理&#xff0c;那么今天就来封装一个统一的响应体 封装基本响应体 1、在 config 包里新建 ApiResponse.java …

5+铜死亡+预后模型+分型生信思路,热点搭配免疫相关思路

今天给同学们分享一篇生信文章“The pathogenesis of DLD-mediated cuproptosis induced spinal cord injury and its regulation on immune microenvironment”&#xff0c;这篇文章发表在Front Cell Neurosci期刊上&#xff0c;影响因子为5.3。 结果解读&#xff1a; 基因芯…

LeetCode - 110. 平衡二叉树(C语言,二叉树,配图,简单)

根据题意&#xff0c;我们只需要比较当前节点的左右子树高度差是否小于1&#xff0c;利用分治法&#xff0c;只需要满足&#xff1a; 1. 根节点的左右子树的高度差小于1。 2. 根节点左右子树的满足高度差小于1&#xff0c;在往下走&#xff0c;判断左子树根节点的左右子树是否满…

质量检查管理制度

质量检查管理制度 建立健全质量检查管理制度&#xff0c;明确过程检查、最终检查、质量评定、检查记录和检查报告等要求

40.坑王驾到第六期:这是什么奇葩错误?

一、问题再现 在HbuilderX中引用了一个checkALL模块&#xff0c;正常编译然后启动到微信开发者工具&#xff0c;工具报错&#xff0c;找不到XXXXXX/index2.js。为什么编译后在微信工具中会自动加一个2呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; 二、解决问题 经过清…

【Node.js】基础梳理 6 - MongoDB

写在最前&#xff1a;跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识&#xff0c;需要格外注重实战和官方技术文档&#xff0c;文档建议作为手册使用 系列文章 【Node.js】笔记整理 1 - 基础知识【Node.js】笔记整理 2 - 常用模块【Node.js】笔记整理 3 - n…

【LeetCode】每日一题 2023_12_5 到达首都的最少油耗(树,搜索)

文章目录 刷题前唠嗑题目&#xff1a;到达首都的最少油耗题目描述代码与解题思路 刷题前唠嗑 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 题目&#xff1a;到达首都的最少油耗 题目链接&#xff1a;2477. 到达首都的最少油耗 题目描述 代码与解题思路 …

Python代码编译并生成Docker镜像

Python代码编译并生成Docker镜像 前言 实际python项目交付时往往有针对关键代码进行保护的需求&#xff0c;本文介绍了一种简单可行的方案&#xff1a;1. 在Linux系统上先将 .py 文件编译为 .so 文件&#xff0c;2. 将整个项目打包成Docker镜像&#xff08;解决 .so 文件的环…

【性能测试】业务/吞吐量与存量数据设计关系+压测常见解决方案

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、性能测试中业务…

C语言错误处理之 “信号处理方式<signal.h>及signal函数等内置函数”

目录 前言 signal.h头文件 信号宏 signal函数 实例&#xff1a;在Linux环境下验证signal函数 实例&#xff1a;在Linux中演示保存signal函数的返回值 预定义的信号处理函数&#xff08;简单了解&#xff09; SIG_DFL函数 SIG_IGN函数 raise函数 实例&#xff1a;测试…

leetcode 255.用队列实现栈

255.用队列实现栈 不出意外大概率这几天都会更新 leetcode&#xff0c;如果没有做新的题&#xff0c;大概就会把 leetcode 之前写过的题整理&#xff08;单链表的题目居多一点&#xff09;出来写成博客 今天讲的题蛮容易出错的&#xff08;注意传参啊&#xff0c;最好把队列的…

渗透测试——五、网站漏洞——SQL注入

一、走进DVWA测试网站 1、网站渗透测试步骤 (1)收集信息 1、获取域名的 Whois 信息&#xff0c;获取注册者邮箱、姓名、电话等。2、查询服务器旁站及子域名站点&#xff0c;因为主站一般比较难&#xff0c;所以先看看旁站有没有通用性的CMS或者其他漏洞。3、查看服务器操作系…