粒子群算法(PSO)的Python实现(求解多元函数的极值)

粒子群算法(PSO)的Python实现(求解多元函数的极值)PSO是寻优算法中比较简单的一种,本文用Python简单实现了PSO算法,用来求解一个五元函数的最大值,并与MATLAB的fmincon函数的运行结果做比较。

大家好,又见面了,我是你们的朋友全栈君。

PSO算法算是寻优算法中比较简单的一种,其大概思想是:
在这里插入图片描述
现在我们计算:
在这里插入图片描述
的极大值,每一个变量的取值范围都是(1,25)。
Python代码为:

# -*- coding: utf-8 -*-
""" @Time : 2020/9/13 10:08 @Author :KI @File :pso.py @Motto:Hungry And Humble """
import math
import random
import numpy as np
import matplotlib.pyplot as plt
import pylab as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
class PSO:
def __init__(self, dimension, time, size, low, up, v_low, v_high):
# 初始化
self.dimension = dimension  # 变量个数
self.time = time  # 迭代的代数
self.size = size  # 种群大小
self.bound = []  # 变量的约束范围
self.bound.append(low)
self.bound.append(up)
self.v_low = v_low
self.v_high = v_high
self.x = np.zeros((self.size, self.dimension))  # 所有粒子的位置
self.v = np.zeros((self.size, self.dimension))  # 所有粒子的速度
self.p_best = np.zeros((self.size, self.dimension))  # 每个粒子最优的位置
self.g_best = np.zeros((1, self.dimension))[0]  # 全局最优的位置
# 初始化第0代初始全局最优解
temp = -1000000
for i in range(self.size):
for j in range(self.dimension):
self.x[i][j] = random.uniform(self.bound[0][j], self.bound[1][j])
self.v[i][j] = random.uniform(self.v_low, self.v_high)
self.p_best[i] = self.x[i]  # 储存最优的个体
fit = self.fitness(self.p_best[i])
# 做出修改
if fit > temp:
self.g_best = self.p_best[i]
temp = fit
def fitness(self, x):
""" 个体适应值计算 """
x1 = x[0]
x2 = x[1]
x3 = x[2]
x4 = x[3]
x5 = x[4]
y = math.floor((x2 * np.exp(x1) + x3 * np.sin(x2) + x4 + x5) * 100) / 100
# print(y)
return y
def update(self, size):
c1 = 2.0  # 学习因子
c2 = 2.0
w = 0.8  # 自身权重因子
for i in range(size):
# 更新速度(核心公式)
self.v[i] = w * self.v[i] + c1 * random.uniform(0, 1) * (
self.p_best[i] - self.x[i]) + c2 * random.uniform(0, 1) * (self.g_best - self.x[i])
# 速度限制
for j in range(self.dimension):
if self.v[i][j] < self.v_low:
self.v[i][j] = self.v_low
if self.v[i][j] > self.v_high:
self.v[i][j] = self.v_high
# 更新位置
self.x[i] = self.x[i] + self.v[i]
# 位置限制
for j in range(self.dimension):
if self.x[i][j] < self.bound[0][j]:
self.x[i][j] = self.bound[0][j]
if self.x[i][j] > self.bound[1][j]:
self.x[i][j] = self.bound[1][j]
# 更新p_best和g_best
if self.fitness(self.x[i]) > self.fitness(self.p_best[i]):
self.p_best[i] = self.x[i]
if self.fitness(self.x[i]) > self.fitness(self.g_best):
self.g_best = self.x[i]
def pso(self):
best = []
self.final_best = np.array([1, 2, 3, 4, 5])
for gen in range(self.time):
self.update(self.size)
if self.fitness(self.g_best) > self.fitness(self.final_best):
self.final_best = self.g_best.copy()
print('当前最佳位置:{}'.format(self.final_best))
temp = self.fitness(self.final_best)
print('当前的最佳适应度:{}'.format(temp))
best.append(temp)
t = [i for i in range(self.time)]
plt.figure()
plt.plot(t, best, color='red', marker='.', ms=15)
plt.rcParams['axes.unicode_minus'] = False
plt.margins(0)
plt.xlabel(u"迭代次数")  # X轴标签
plt.ylabel(u"适应度")  # Y轴标签
plt.title(u"迭代过程")  # 标题
plt.show()
if __name__ == '__main__':
time = 50
size = 100
dimension = 5
v_low = -1
v_high = 1
low = [1, 1, 1, 1, 1]
up = [25, 25, 25, 25, 25]
pso = PSO(dimension, time, size, low, up, v_low, v_high)
pso.pso()

运行结果:
在这里插入图片描述
收敛过程:
在这里插入图片描述
可以看出,不到10次就收敛了。

matlab代码:

z=@(x)-(x(2)*exp(x(1))+x(3)*sin(x(2))+x(4)*x(5));
x0=[1;1;1;1;1];
[x,feval]=fmincon(z,x0,[],[],[],[],[1;1;1;1;1],[25;25;25;25;25])

运行结果:

x =
25.0000
25.0000
13.1400
1.0002
1.0002
feval =
-1.8001e+12

如果想要利用上述代码求极小值,可以有以下两种办法:

  1. 将fitness函数中的返回值改为-y,此时如果求出的值为z,那么函数的极小值就为-z。
  2. 将第34行代码处的temp改为一个很大的值;将第42、83、85以及93行代码处的”>“改为”<“。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/130988.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • ARM_控制器

    ARM_控制器ARM_控制器1.GPIO控制器:(gpio口的通用函数接口定义在gpiolib.c文件中,声明则在gpio.h中)linux-3.10\include\linux\gpio.hlinux-3

  • ac测评题库_队长小翼剧场版

    ac测评题库_队长小翼剧场版给定一个 N×M 的棋盘,有一些格子禁止放棋子。问棋盘上最多能放多少个不能互相攻击的骑士(国际象棋的“骑士”,类似于中国象棋的“马”,按照“日”字攻击,但没有中国象棋“别马腿”的规则)。输入格式第一行包含三个整数 N,M,T,其中 T 表示禁止放置的格子的数量。接下来 T 行每行包含两个整数 x 和 y,表示位于第 x 行第 y 列的格子禁止放置,行列数从 1 开始。输出格式输出一个整数表示结果。数据范围1≤N,M≤100输入样例:2 3 0输出样例:4#include<b

  • 处理高并发的六种方法

    处理高并发的六种方法处理高并发的六种方法1:系统拆分,将一个系统拆分为多个子系统,用dubbo来搞。然后每个系统连一个数据库,这样本来就一个库,现在多个数据库,这样就可以抗高并发。2:缓存,必须得用缓存。大部分的高并发场景,都是读多写少,那你完全可以在数据库和缓存里都写一份,然后读的时候大量走缓存不就得了。毕竟人家redis轻轻松松单机几万的并发啊。没问题的。所以你可以考的虑考虑你的项目里,那些承载主要请求读场景…

  • sklearn安装教程_sklearn库的使用

    sklearn安装教程_sklearn库的使用Sklearn(全称Scikit-Learn)是基于Python语言的机器学习工具,是机器学习中的常用第三方模块。它建立在NumPy,SciPy和Matplotlib之上。因此,在安装sklearn之前,需要先安装其三个依赖库numpy+scipy+matplotlib,具体安装步骤如下:1.进入官网下载相应的模块安装地址如下https://www.lfd.uci.edu/~gohlke/pythonlibs网站中包含了python中所需的子库。进去之后查找比较麻烦,可以在网址后

    2022年10月18日
  • MCTS学习笔记「建议收藏」

    MCTS学习笔记「建议收藏」MCTS树学习MCTS,即蒙特卡罗树搜索,是一类搜索算法树的统称,可以较为有效地解决一些搜索空间巨大的问题。如一个8*8的棋盘,第一步棋有64种着法,那么第二步则有63种,依次类推,假如我们把第一步棋作为根节点,那么其子节点就有63个,再往下的子节点就有62个……如果不加干预,树结构将会繁杂,MCTS采用策略来对获胜性较小的着法不予考虑,如第二步的63种着法中有10种是不可能胜利的,那么这十个…

  • 微信集赞作弊_朋友圈分享集赞是非法行为吗

    微信集赞作弊_朋友圈分享集赞是非法行为吗从古至今,无论是征战沙场的猛将,还是心怀天下的文豪,抑或探索人生真理的大哲学家,都将“独立、自由”等当做人之所以为人的奋斗目标和根本标准。但可惜的是,无论是外来环境、文化的影响,还是内在的个人成长过程,都缺乏对“独立、自由”的尊重和支撑。而在当下的移动互联网时代,以微信为代表的社交应用,更是在某种程度上扼杀着大众的独立和自由。虽然这并不是微信有意去做…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号