粒子群算法python(含例程代码与详解)
目录
- 1.算法简介
- 2.算法流程
- 3.算法示例
- 4.算法实现
- 5.算法应用
1.算法简介
粒子群算法的思想源于对鸟类捕食行为的研究,模拟鸟集群飞行觅食的行为,鸟之间通过集体的协作使群体达到最优目的。
设想这样的一个场景,一群鸟在随机的搜索食物,在某块区域里有一块食物,所有的鸟都不知道食物在哪里,但是他们可以感受到当前的位置离食物还有多远,此时找到食物的最优策略是什么?答案是:搜寻目前离食物最近的鸟的周围区域,根据自己的飞行经验判断食物的所在。
PSO正是从这种模型中得到了启发:
1.每个寻优问题的解都被想象成一只鸟,称为‘粒子’,所有的粒子都在一个D维空间进行搜索。
2.所有的粒子都由一个fitness function确定适应值以判断目前位置的好坏。
3.每一个粒子都被赋予记忆功能,能记住所搜寻到的最佳位置
4.每一个粒子还有一个速度以决定飞行的距离和方向。这个速度根据本身的飞行经验及同伴的飞行经验进行动态调整。
5.可以看出粒子群算法的基础在于信息的社会共享
D维空间中,有N个粒子;
粒子i位置:xi=(xi1,xi2,…xiD),将xi代入适应函数f(xi)求适应值;
粒子i速度:vi=(vi1,vi2,…viD)
粒子i个体经历过的最好位置:pbesti=(pi1,pi2,…piD)
种群所经历过的最好位置:gbest=(g1,g2,…gD)
通常,在第d(1≤d≤D)维的位置变化范围限定在(Xmin,d,Xmax,dX_{min,d},X_{max,d}Xmin,d,Xmax,d)内,
速度变化范围限定在(−Vmax,d,Vmax,d-V_{max,d},V_{max,d}−Vmax,d,Vmax,d) 内(即在迭代中若
超出了边界值,则该维的速度或位置被限制为该维最大速度或边界
位置)
速度及位置的更新公式
有了上面的了解后,一个很关键的问题就是粒子的速度以及位置如何更新?
粒子i的第d维速度更新公式:
粒子i的第d维位置更新公式
vidkv_{id}^kvidk:第k次迭代粒子i的飞行速度矢量的第d维分量
xidkx_{id}^kxidk:第k次迭代粒子i位置矢量的第d维分量
c1,c2:加速度常数,调节学习最大步长(超参数)
r1,r2:两个随机函数,取值范围[0,1],以增加随机性
w:惯性权重,非负数,调节对解空间的搜索范围。(超参数)
可以看出pso算法一共含有3个超参数。
对于粒子速度更新公式这里多介绍一些:
其速度更新公式包含三个部分:
第一部分为粒子先前的速度
第二部分为‘认知’部分,表示粒子本身的思考,可理解为粒子i当前位置与自己最好位置之间的距离
第三部分为‘社会部分’,表示粒子间的信息共享和合作,可理解为粒子i当前位置与群体最好位置之间的距离。
如下图所示,粒子其运动的过程受以上三个方面的影响:
2.算法流程
- Initial:
初始化粒子群体(群体规模为n),包括随机位置和速度。 - Evaluation:
根据fitness function ,评价每个粒子的适应度。 - Find the Pbest:
对每个粒子,将其当前适应值与其个体历史最佳位置(pbest)对应的适应值做比较,如果当前的适应值更高,则将用当前位置更新历史最佳位置pbest。 - Find the Gbest:
对每个粒子,将其当前适应值与全局最佳位置(gbest)对应的适应值做比较,如果当前的适应值更高,则将用当前粒子的位置更新全局最佳位置gbest。 - Update the Velocity:
根据公式更新每个粒子的速度与位置。 - 如未满足结束条件,则返回步骤2
通常算法达到最大迭代次数或者最佳适应度值的增量小于某个给定的阈值时算法停止。
该算法的流程图如下:
3.算法示例
4.算法实现
以上面的例子为例,该算法的实现如下,如果需要优化其他问题,只需要调整下fitness function即可。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3Ddef fit_fun(x): # 适应函数return sum(100.0 * (x[0][1:] - x[0][:-1] ** 2.0) ** 2.0 + (1 - x[0][:-1]) ** 2.0)class Particle:# 初始化def __init__(self, x_max, max_vel, dim):self.__pos = np.random.uniform(-x_max, x_max, (1, dim)) # 粒子的位置self.__vel = np.random.uniform(-max_vel, max_vel, (1, dim)) # 粒子的速度self.__bestPos = np.zeros((1, dim)) # 粒子最好的位置self.__fitnessValue = fit_fun(self.__pos) # 适应度函数值def set_pos(self, value):self.__pos = valuedef get_pos(self):return self.__posdef set_best_pos(self, value):self.__bestPos = valuedef get_best_pos(self):return self.__bestPosdef set_vel(self, value):self.__vel = valuedef get_vel(self):return self.__veldef set_fitness_value(self, value):self.__fitnessValue = valuedef get_fitness_value(self):return self.__fitnessValueclass PSO:def __init__(self, dim, size, iter_num, x_max, max_vel, tol, best_fitness_value=float('Inf'), C1=2, C2=2, W=1):self.C1 = C1self.C2 = C2self.W = Wself.dim = dim # 粒子的维度self.size = size # 粒子个数self.iter_num = iter_num # 迭代次数self.x_max = x_maxself.max_vel = max_vel # 粒子最大速度self.tol = tol # 截至条件self.best_fitness_value = best_fitness_valueself.best_position = np.zeros((1, dim)) # 种群最优位置self.fitness_val_list = [] # 每次迭代最优适应值# 对种群进行初始化self.Particle_list = [Particle(self.x_max, self.max_vel, self.dim) for i in range(self.size)]def set_bestFitnessValue(self, value):self.best_fitness_value = valuedef get_bestFitnessValue(self):return self.best_fitness_valuedef set_bestPosition(self, value):self.best_position = valuedef get_bestPosition(self):return self.best_position# 更新速度def update_vel(self, part):vel_value = self.W * part.get_vel() + self.C1 * np.random.rand() * (part.get_best_pos() - part.get_pos()) \+ self.C2 * np.random.rand() * (self.get_bestPosition() - part.get_pos())vel_value[vel_value > self.max_vel] = self.max_velvel_value[vel_value < -self.max_vel] = -self.max_velpart.set_vel(vel_value)# 更新位置def update_pos(self, part):pos_value = part.get_pos() + part.get_vel()part.set_pos(pos_value)value = fit_fun(part.get_pos())if value < part.get_fitness_value():part.set_fitness_value(value)part.set_best_pos(pos_value)if value < self.get_bestFitnessValue():self.set_bestFitnessValue(value)self.set_bestPosition(pos_value)def update_ndim(self):for i in range(self.iter_num):for part in self.Particle_list:self.update_vel(part) # 更新速度self.update_pos(part) # 更新位置self.fitness_val_list.append(self.get_bestFitnessValue()) # 每次迭代完把当前的最优适应度存到列表print('第{}次最佳适应值为{}'.format(i, self.get_bestFitnessValue()))if self.get_bestFitnessValue() < self.tol:breakreturn self.fitness_val_list, self.get_bestPosition()if __name__ == '__main__':# test 香蕉函数pso = PSO(4, 5, 10000, 30, 60, 1e-4, C1=2, C2=2, W=1)fit_var_list, best_pos = pso.update_ndim()print("最优位置:" + str(best_pos))print("最优解:" + str(fit_var_list[-1]))plt.plot(range(len(fit_var_list)), fit_var_list, alpha=0.5)
5.算法应用
注意该算法在解决具体问题时需要注意以下几点:
1.种群大小m
m很小很容易陷入局部最优,m很大,pso的优化能力很好,当种群数目增长至一定水平时,再增长将不再有显著的作用。
2.权重因子
对于粒子的速度更新的三部分:
a. 惯性因子w=1表示基本的粒子群算法,w=0表示失去对粒子本身的速度记忆。
b. 自我认知部分的学习因子c1=0表示无私型的粒子群算法,只有社会,没有自我,这样会使群体丧失多样性,从而容易导致陷入局部最优而无法跳出。
c. 社会经验部分的学习因子c2=0表示自我型的粒子群算法,只有自我没有社会,这样导致没有信息的社会共享,算法收敛速度缓慢。
这三个参数的选择非常重要,如何调整这三个参数使算法避免早熟又可以比较快的收敛,对于解决实际问题意义较大。
3.最大速度
速度限制的作用为:维护算法的探索能力与开发能力的平衡。
VmV_mVm较大时,探索能力强,但是粒子容易飞过最优解
VmV_mVm较小时,开发能力强,但是容易陷入局部最优解
VmV_mVm一般设定为每维变量变化范围的10%~20%
4.停止准则
a.最大迭代次数
b.可以接受的满意解(通过fitness function判断是否满意)
5.粒子空间的初始化
较好地选择粒子的初始化空间,将大大缩短收敛时间.初始化空间根据具体问题的不同而不同,根据具体问题进行设定. 该算法为数不多的关键参数的设置却对算法的精度和效率有
着显著影响.
6.线性递减权值(未测)
wmaxw_{max}wmax最大惯性权重,wminw_{min}wmin最小惯性权重,run当前迭代次数,runmaxrun_{max}runmax为算法迭代总次数
较大的w有较好的全局收敛能力,较小的w则有较强的局部收敛能力。因此,随着迭代次数的增加,惯性权重w应不断减少,从而使得粒子群算法在初期具有较强的全局收敛能力,而晚期具有较强的局部收敛能力。
7.收缩因子法(未测)
1999年,Clerc引入收缩因子以保证算法的收敛性,即速度更新公式改为上式,其中,收缩因子K为受φ1 φ2 限制的w。φ1 φ2是需要预先设定的模型参数。
收缩因子法控制系统行为最终收敛,且可以有效搜索不同区域,该法能得到较高质量的解。
8.算法的邻域拓扑结构(未测)
粒子群算法的邻域拓扑结构包括两种,一种是将群体内所有个体都作为粒子的邻域,另一种是只将群体中的部分个体作为粒子的邻域.邻域拓扑结构决定群体历史最优位置,因此该算法分为全局粒子群算法和局部粒子群算法,上面我实现的是全局粒子群算法。
全局粒子群算法
1. 粒子自己历史最优值
2. 粒子群体的全局最优值
局部粒子群算法
1. 粒子自己历史最优值
2. 粒子邻域内粒子的最优值
邻域随迭代次数的增加线性变大,最后邻域扩展到整个粒子群。
实践证明:全局版本的粒子群算法收敛速度快,但是容易陷入局部最优。局部版本的粒子群算法收敛速度慢,但是很难陷入局部最优。现在的粒子群算法大都在收敛速度与摆脱局部最优这两个方面下功夫。其实这两个方面是矛盾的。看如何更好的折中了。
粒子群算法python(含例程代码与详解)相关推荐
- 遗传算法python(含例程代码与详解)
遗传算法 1.算法简介 2.算法流程 3.算法示例 4.算法实现 5.算法应用 遗传算法简称GA(Genetic Algorithms)模拟自然界生物遗传学(孟德尔)和生物进化论(达尔文)通过人工方式 ...
- 粒子群算法python实现: 带活化因子
粒子群算法python实现: 带活化因子 求解一个较复杂的函数 实现 求解一个较复杂的函数 def function(x):#2004年考研题(我这里只求极小值):x^2-6xy+10^2-2yz-z ...
- 主题:基于改进粒子群算法的含源配电网静态重构 利用IEEE-33节点系统进行仿真计算
主题:基于改进粒子群算法的含源配电网静态重构 利用IEEE-33节点系统进行仿真计算 以网络最小损耗为目标函数 基于改进粒子群算法进行重构 可以加入不同数量的分布式电源 包含M文件.模型图.程序框图以 ...
- Python之粒子群算法(含代码实例)
这个算法,咋一听感觉很高级,挺难的,其实学习过后也就那样,原理其实挺简单的.下面是我对粒子群算法的一些个人理解,如有差错,还望指出. 一.粒子群算法简介 Kennedy和Eberhart受人工生命研究 ...
- 6套粒子群算法(内含matlab代码)
粒子群算法(1)----粒子群算法简介 一.粒子群算法的历史 粒子群算法源于复杂适应系统(Complex Adaptive System,CAS).CAS理论于1994年正式提出,CAS中的成员称为主 ...
- 智能优化算法——粒子群算法原理(附代码)
目录 基本概念 算法实现 粒子群算法的构成要素分析 C++程序测试Sphere函数 总结 visual studio2017c++源代码 源文件下载地址 基本概念 粒子群优化算法(particle s ...
- 蚁群算法汇总含matlab代码_数学建模(十四)
蚁群算法模拟自然界蚂蚁群体的觅食行为,常用于旅行商问题(TSP),二维.三维路径规划问题. 将蚁群算法用于优化问题的思路:用蚂蚁的行走路径表示待优化问题的可行解,整个蚂蚁群体群体的所有路径构成待优化问 ...
- 基于xilinx vivado的GTX/GTP ip核设置与例程代码使用详解
本文目录 1 概述 2 参考文档 3 GTX的IP设置 3.1 本例程使用环境 3.2 GTX IP界面的设置情况 3.2.1 GTX IP设置第1页 3.2.2 GTX IP设置第2页 3.2.3 ...
- a*算法matlab代码_蚁群算法(含MATLAB代码)
CSDN-专业IT技术社区-登录blog.csdn.net
最新文章
- 3438亿美元!互联网内容产业新机会
- AM消息中间件OA、ERP消息提醒的必要工具
- 智能车竞赛技术报告 | 双车接力组 - 大连海事大学 - 同舟拾贰队
- 消息队列之RabbitMQ
- 回文子序列_计算回文子序列的总数
- View、Text、Button的drawableLeft左侧图片自定义大小
- 持续集成工具集之四 Jenkins+Maven+Git+Tomcat 项目构建和自动部署
- python小课离线版_断网环境下利用pip安装Python离线安装包
- 关于《精武门》的回忆
- java并发编程实践学习(二)由可重入锁想到的
- 被脱库咋办?KMS 给你解决方案!
- 数学建模暑期集训28:元胞自动机
- 转行学IT:零基础学什么技术好?
- 相机像素尺寸(像元大小)和成像系统分辨率之间的关系
- R语言 使用getGEO()直接进行差异表达分析并显示Entrez_id和Symbol_id
- 华硕raid 0 安装linux,ROG Maxius IX主板技巧篇:组建RAID 0
- 校招/社招/秋招/春招求职指南
- 论文阅读《Direct Sparse Odometry》2
- 留学日本专业比较: 理工科、文科、与研究
- 【我的代码】前端遇上After Effects --- 鼠标悬浮效果(上)