粒子群优化算法的实践

news2024/11/28 6:42:42

粒子群优化算法的实践

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.1

print("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 + V
    obj = 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_plot

anim = 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.8755
  4.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.0763
  2.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.0613
   0.13   -0.1733]
 [-0.0983  0.0358 -0.1614  0.1471 -0.1188 -0.055  -0.094  -0.0828  0.0109
   0.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 PSO

def demo_func(X):
    x, y = X
    return (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 FuncAnimation

record_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 % 10
    ax.set_title('iter = ' + str(i))
    X_tmp = X_list[i] + V_list[i] * j / 10.0
    plt.setp(line, 'xdata', X_tmp[:, 0], 'ydata', X_tmp[:, 1])
    return line


ani = 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 PSO

def demo_func(X):
    x, y = X
    return (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 FuncAnimation

record_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 % 10
    ax.set_title('iter = ' + str(i))
    X_tmp = X_list[i] + V_list[i] * j / 10.0
    plt.setp(line, 'xdata', X_tmp[:, 0], 'ydata', X_tmp[:, 1])
    return line


ani = FuncAnimation(fig, update_scatter, blit=True, interval=25, frames=max_iter * 10)
plt.show()

ani.save('PSO_2.gif', writer='pillow')

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

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

相关文章

算法通关村——数论问题

数论是一个很重要的学科&#xff0c;覆盖领域极广&#xff0c;小到小学的智力问题&#xff0c;大到世界顶级科学家都一直在研究相关问题&#xff0c;因此其难度跨度非常大。在程序设计里 &#xff0c;也经常会出现数论的问题&#xff0c;但是&#xff0c;这些一般都是比较基本的…

训练自己的YOLOv8姿态估计模型

在不断发展的计算机视觉领域&#xff0c;姿态估计作为一项关键创新脱颖而出&#xff0c;改变了我们理解视觉数据以及与视觉数据交互的方式。 Ultralytics YOLOv8 处于这一转变的最前沿&#xff0c;提供了一个强大的工具来捕捉图像中物体方向和运动的微妙之处。 NSDT工具推荐&am…

Avalonia开发之HelloWrold

前言 本文所有讲解是以VS2022为开发工具&#xff0c;官方提供了VS2022和2019的扩展支持&#xff0c;大家根据自己的是实际情况下载相应的扩展进行安装。 安装扩展 如下图&#xff0c;我们在扩展菜单里面找到扩展管理&#xff0c;如下图&#xff1a; 在扩展管理的搜索栏里面…

解决:docx.opc.exceptions.PackageNotFoundError: Package not found at ‘xxx’

解决&#xff1a;docx.opc.exceptions.PackageNotFoundError: Package not found at ‘xxx’ 文章目录 解决&#xff1a;docx.opc.exceptions.PackageNotFoundError: Package not found at ‘xxx’背景报错问题报错翻译报错位置代码报错原因解决方法今天的分享就到此结束了 背景…

MIT_线性代数笔记:第 12 讲 图、网络、关联矩阵

目录 图和网络 Graphs & Networks关联矩阵&#xff08;Incidence matrices&#xff09;矩阵的零空间矩阵列空间矩阵的左零空间矩阵的行空间 本讲讨论线性代数在物理系统中的应用。 图和网络 Graphs & Networks “图”就是“结点”和“边”的一个集合。 边线上的箭头代…

js实现AES加密解密,简易又全面

常规是直接安装CryptoJS库&#xff0c;但为了减少项目体积&#xff0c;使用这简单的20k文件就ok 一览&#xff1a; 代码中使用的是Pkcs7&#xff0c;但我需要的填充方式是ZeroPadding 所以稍微有修改&#xff1a; q (p.pad {}).ZeroPadding {pad: function (data, blockSi…

波奇学C++:类型转换和IO流

隐式类型转换 int i0; double pi; 强制类型转换 int* pnullptr; int a(int)p; 单参数构造函数支持隐式类型转换 class A { public:A(string a):_a(a){} private:string _a; }; A a("xxxx"); //"xxx" const char* 隐式转换为string 多参数也可以通过{…

c语言指针详解(上)

目录 一、指针的基本概念和用法 二、指针运算 2.1 指针的自增和自减运算 2.2 指针的自增和自减运算 三、数组和指针 四、指针和函数 4.1 在函数中使用指针作为参数和返回值 4.1.1 使用指针作为函数参数 4.1.2 使用指针作为函数返回值 4.2 指针参数的传值和传引用特性 4.2.1 指针…

Visual Studio Code tasks.json中控制任务执行问题面板显示内容的PresentationOptions介绍

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 一、引言 在 Visual Studio Code 中&#xff0c;tasks.json 文件用于配置和控制任务的执行&#xff0c;其中的 presentation配置项可以用来控制任务执行时在终端面板窗口中输出的内容&#xff0c;presentat…

单机无锁线程安全队列-Disruptor

Disruptor 1、基本介绍 说到队列&#xff0c;除了常见的mq中间件&#xff0c;java中也自带线程安全的BlockingQueue&#xff0c;但是BlockingQueue通过在入队和出队时加锁的方式避免并发操作&#xff0c;性能上会大打折扣。 而Disruptor是一个线程安全、低延迟、吞吐量高的队…

代替APP?微信小程序到底好在哪?

2019年是微信小程序宣布登场的一年&#xff0c;它实现了应用程序能被“垂手可得”的愿望。用户只需简单扫一扫或搜索&#xff0c;就能轻松打开应用。与需要在应用市场下载的APP相比&#xff0c;微信小程序可以在微信中被轻易地获取和传播&#xff0c;同时也带来了非凡的使用体验…

102.套接字-Socket网络编程4(TCP通信流程)

目录 TCP编程流程 套接字函数 1.创建套接字 2.绑定地址 3.监听连接请求 4.接受连接 5. 连接到服务器 6. 发送数据 7. 接收数据 8.关闭套接字 服务器端通信流程 示例代码 客户端通信流程 代码示例 TCP编程流程 TCP是一个面向连接的&#xff0c;安全的&#xff0c;流…

单调栈与单调队列算法总结

单调栈 知识概览 单调栈最常见的应用是找到每一个数离它最近的且比它小的数。单调栈考虑的方式和双指针类似&#xff0c;都是先想一下暴力做法是什么&#xff0c;然后再挖掘一些性质如单调性&#xff0c;最终可以把目光集中在比较少的状态中&#xff0c;从而达到降低时间复杂…

【Linux】基础IO--重定向理解Linux下一切皆文件缓冲区

文章目录 一、重定向1.什么是重定向2.dup2 系统调用3.理解输入重定向、输出重定向和追加重定向4.简易shell完整实现 二、理解linux下一切皆文件三、缓冲区1.为什么要有缓冲区2.缓冲区的刷新策略3.缓冲区的位置4.实现一个简易的C语言缓冲区5.内核缓冲区 一、重定向 1.什么是重定…

VMware虚拟机系统CentOS镜像的下载

文章目录 阿里云下载官网下载参考文档 一些小版本可能过时或者其他原因已经不能存在了&#xff0c;只有大版本号最新的&#xff0c;或者其他最新版本 阿里云下载 1-百度搜索&#xff1a;阿里云 2-找到开发者社区 3-找到下载&#xff0c;选择镜像 4-选择系统 5-点击镜像地…

【eNSP实践】eNSP实战篇(2)之简单实现交换机与主机的配置(图文详解)

目录 写在前面涉及知识1、交换机实验1.1 实验条件1.2 实验步骤A、打开eNSP软件&#xff0c;创建拓扑B、搭建主机与交换机连线C、配置交换机和主机D、验证不同网段设备可通性 1.3 通过交换机查看MAC地址 写在最后 写在前面 其实前面文章我有介绍关于路由器的使用&#xff0c;但…

OCP Java17 SE Developers 复习题08

答案 答案 答案 A. This code is correct. Line 8 creates a lambda expression that checks whether the age is less than 5, making option A correct. Since there is only one parameter and it does not specify a type, the parentheses around the parameter are …

TrustZone​之在安全状态之间切换

如果处理器处于NS.EL1,而软件想要转移到S.EL1,应该如何实现呢? 要改变安全状态,无论是向上还是向下,执行都必须经过EL3,如下图所示: 前面的图表显示了在不同安全状态之间移动涉及的步骤的示例序列。逐步进行解释: 进入较高的异常级别需要一个异常。通常,此异常…

网络程序设计

互相连接&#xff0c;发送信息 tcp和udp协议 tcp会有准备&#xff0c;udp不会准备。 8080端口&#xff1a;tomcat端口&#xff0c;java和web相连接 80端口&#xff1a;http 21端口&#xff1a;ftp 套接字 socket&#xff1a;提供给程序可以对外进行连接的接口 ip地址 特…

利用github copilot完成代码,利用正则化完成字符串中信息查找

利用正则化完成字符串中的字符拆解。 下面的代码是实现在“计算机组成原理-计科2101-123456-小明同学.docx”中提取出班级&#xff08;grade&#xff09;&#xff0c;学号&#xff08;id&#xff09;&#xff0c;姓名&#xff08;name&#xff09;。以下的代码都是github copi…