粒子群算法组卷_粒子群(PSO)算法概念及代码实现

f9bff561f22ccce7c0987fee9670da8e.png

粒子群算法的由来及思想

粒子群算法最早是由两名美国的科学家基于群鸟觅食,寻找最佳觅食区域的过程所提出来的,作为一种智能算法,PSO模拟的就是最佳决策的过程,鸟群觅食类似于人类的决策过程,想想在你做出选择之前,是不是会受到自己的经验(局部最优)以及周围人的经历(全局最优)的影响?同样的道理,群鸟在觅食的过程当中,每一只鸟的初始位置都处于随机状态,当然也不知道最佳的觅食点在何处,并且每只鸟的飞行方向也是随机的。可以认为,在觅食的初期,鸟群的运动轨迹都是杂乱无章的,随着时间的推移,处于随机位置的鸟类通过群内的相互学习、共享觅食信息,每一只鸟在每一次的觅食过程中结合自己的经验和同伴传送的信息估计目前所处的位置能够找到食物有多大的价值。基于这样的搜索方式,粒子群算法(Particle Swarm Optimization,PSO)应运而生。

基本概念

每只鸟在某处位置能够找到食物的可能可以通过适应值来刻画,每只鸟能够记住自己的觅食位置,并且找到其中的最佳位置(局部最优),鸟群中所有个体的最佳位置就可以看做整个鸟群的最佳觅食点(全局最优)。可以预见的是,整个鸟群的觅食活动总体上一定是往这个全局最优的觅食区域运动的,通过鸟群觅食位置的不断移动即不断地迭代,速度的不断更新,鸟群往该最优位置步步逼近。

  • 鸟群中的每一个个体都可以当做一个粒子,鸟群即可被看做粒子群。假设一个有M个粒子的粒子群在一个N维空间内寻找最优位置,那么可以对每个粒子赋予一个“位置”:

  • 对于每一个粒子而言,该位置即为问题的一个潜在解,在这个位置能觅到食物的可能性有多大呢?既可以通过将
    带入目标函数计算其适应值,根据适应值大小来衡量其优劣。在每一次的搜寻过程中,记录每个粒子的最优位置:

  • 在本次觅食搜寻过程中,所有粒子最优位置的最优解即可当做整个粒子群的最佳觅食位置:

  • 反复进行食物的搜寻过程(进行迭代),直至找到全局最优解为止。当然在每一次位置的寻找之后,应该对粒子的速度和所在位置进行更新,记第i个粒子的速度为:

  • 粒子的速度及位置更新的方式如下:

  1. 其中
  2. 是一个非负数,称为惯性因子,对算法的收敛起到很大的作用,其值越大,粒子飞跃的范围就越广,更容易找到全局最优,但是也会错失局部搜寻的能力。
  3. 分别为局部和全局最优位置。
  4. 加速常数
    也是非负常数,是调整局部最优值和全局最优值权重的参数,如果前者为0说明搜寻过程中没有自身经验只有社会经验,容易陷入局部最优解;若后者为0,即只有社会经验,没有自身经验,常常会陷入局部最优解中,不能飞越该局部最优区域。
  5. 是[0,1]范围之内的随机数,
    是约束因子,目的是控制速度的权重。

从上面速度和位置分量的改变规则我们可以看到,速度的存在的根本作用还是为了改变粒子的位置,计算新一轮粒子的适应值,其中的参数的设置也会影响到对全局最优解的搜寻。在一般情况下,我们会对粒子的速度分量进行限制,

,如果粒子的速度分量在更新之后超过最大飞翔速度,则应该根据不同的情况进行优化问题的设定。

迭代终止条件根据具体问题而定,一般达到预定最大迭代次数或者粒子群目前为止搜寻到的最优位置满足目标函数的最小容许误差。

PSO算法的主要实现步骤

  1. 初始化粒子群。包括粒子的初始位置及速度,惯性因子等参数值

粒子数M一般选取20~40个,不过对于一些特殊的难题需要更多的粒子,粒子数量越多,搜索范围就越广,越容易找到全局最优解,但是也会带来更大的计算消耗。

2. 评价各个粒子的初始适应值。

3. 将初始的适应值作为各个粒子的局部最优解,保存各粒子的最优位置。并找到其中的最优值,作为全局最优解的初值,并记录其位置

4. 更新粒子速度及位置

5. 计算更新后粒子的适应值,更新每个粒子的局部最优值以及整个粒子群的全局最优值。

6. 重复4~5直至满足迭代结束条件

86a9b4c62a1bc9b5427c3d77c7e7fddc.png
图1 程序设计流程图

粒子群算法的matlab程序实现

  • 问题1:求解
    之间的最小值
% 目标函数
function f=target(x)
%x in[0,9]
f=x+6*sin(4.*x)+9*cos(5.*x);
end

主程序:PSO.m

%looking for min-functinal value using "Practicle Swarm Optimization"function [Gbest_x,Gbest_y]=PSO()
%Parameter settings
lower_bound = 0;
higher_bound = 9;
particle = 20;                            % 粒子个数
max_iteration = 100;                      % 最大迭代数
dimension = 1;                            % 粒子位置的维度,即自变量个数
c1 = 2;                                   % 加速常数1,控制局部最优解
c2 = 2;                                   % 加速常数2,控制全局最优解
w = 0.6;                                  % 惯性因子
vmax = 0.8;                               % 速度最大值
precision=0.001;                          % 精度设置%Initialize
x = lower_bound+rand(particle,dimension).*(higher_bound-lower_bound);
v = 2*rand(particle,dimension);
Pbest_x=x;                                % 将初始位置设置为局部最优解的位置
Pbest_y=target(x);                        % 各个粒子的函数值作为其局部最优解
Gbest_y=inf;                              % 全局最优解的初始值设置为inf
Gbest_x = x(1,:);                         % 初始全局最优位置设定为第一个粒子的位置
k=1;
f=zeros(particle,1);%plot the function
horizon = linspace(0,9,500);
vertical = target(horizon);
plot(horizon,vertical);
hold on
[m,index] = min(vertical);
text(horizon(index)+0.5,m,['{F_{min}}= ',num2str(m)])
pic_num = 1;while k<=max_iterationflagx=Gbest_x;flagy=Gbest_y;% 搜寻各个粒子的局部最优for i=1:particlef(i) = target(x(i,:));if f(i)<Pbest_y(i)Pbest_y(i)=f(i);      % Personal best function valuePbest_x(i)=x(i,:);    % Personal best variableendend% 更新全局最优位置及适应值[Gbest_y,index] = min(Pbest_y);Gbest_x = x(index,:);% 每一次搜寻之后更新粒子的速度及位置for n=1:particlev(n,:)=w*v(n,:)+c1*rand()*(Pbest_x(n,:)-x(n,:))+c2*rand()*(Gbest_x-x(n,:));% 速度越界操作for p=1:dimensionif v(n,p)>vmaxv(n,p)=vmax;elseif v(n,p)<-vmaxv(n,p)=-vmax;endendx(n,:)=x(n,:)+v(n,:);end% 获取动态搜寻过程gif图figure(1)scatter(Gbest_x,target(Gbest_x))hold onh1=text(6,-4,['X by TSO=',num2str(Gbest_x)]);h2=text(6,-6,['Y by TSO=',num2str(target(Gbest_x))]);pause(0.2)drawnow;F=getframe(gcf);I=frame2im(F);[I,map]=rgb2ind(I,256);if pic_num == 1imwrite(I,map,'PSO.gif','gif', 'Loopcount',inf,'DelayTime',0.2);elseimwrite(I,map,'PSO.gif','gif','WriteMode','append','DelayTime',0.2);enddelete(h1);delete(h2)pic_num = pic_num + 1;% 如果迭代前后全局最优解的差小于精度要求退出if abs(flagx-Gbest_x)<precision&&abs(flagy-Gbest_y)<precisionbreakelsek=k+1;endendstring=['Min-value by TSO is ',num2str(Gbest_y),', where x= ',num2str(Gbest_x)];
title(string)

其中一次运行结果:

>> [Gbest_x,Gbest_y]=PSO();
>> Gbest_x
Gbest_x =4.3744
>> Gbest_y
Gbest_y =-10.4199

77f777d49227405c8fdd86dfbc9a4d66.gif
图2 PSO算法求一元函数最小值

可见,最终在x=4.3744处找到的全局最优解-10.4199,与函数的最小值

=- 10.4122相差不大。手链效果也较好。
  • 问题2:PSO算法求解背包问题

背包问题:现有一小偷入室盗窃,可以偷窃的物品数量共有12件,物品对应的价值(万)为[5;10;13;4;3;11;13;10;8;16;7;4]; 重量(千克)为[2;5;18;3;2;5;10;4;11;7;14;6]。若小偷能拿的物品总质量最大为46kg,如何选取物品使得总价值最大?

%目标函数
function f = target_BAG(x,value,weight,ratio,restriction)
Money = sum(x*value);
Lost = sum(x*weight);
if Lost < restrictionf = Money;
elsex=~x;Money = sum(x*value);f = Money-round((Lost-restriction)*ratio);
end

目标函数用于计算小偷所投物品的质量及价值,如果此时的重量超过了限制,就将所偷物品价值减小。

function [GBest_x,GBest_y,Record]= PSO_BAG()
value = [5;10;13;4;3;11;13;10;8;16;7;4];    % 物品重量
weight = [2;5;18;3;2;5;10;4;11;7;14;6];     % 物品价值
restriction = 46;                           % 背包重量限制
practicle = 20;                             % 粒子数
max_iteration = 100;
dimension = size(value,1);                  
ratio = 2.5; 
c1 = 2;                                   
c2 = 2;                                   
wmin = 0.6;
wmax = 0.8;
vmax = 0.8;                               
time=1;
%Initialize
x = round(rand(practicle,dimension));             % 背包问题中的粒子取值为0或1,代表选择物品或不选择物品
v=rand(practicle,dimension)*(2*vmax)-vmax;PBest_x = x;
PBest_y = zeros(1,dimension);
for i=1:practiclePBest_y(i) = target_BAG(PBest_x(i,:),value,weight,ratio,restriction);    %将总价值作为局部最优解
endGBest_x = ones(1,dimension);
GBest_y = 0;
Record = zeros(1,max_iteration);
for j=1:practicleif PBest_y(j)>GBest_yGBest_y = PBest_y(j);GBest_x = x(j,:);end
endwhile time<=max_iteration% Personal-Best searchingfor i=1:practiclef = target_BAG(x(i,:),value,weight,ratio,restriction);if f>PBest_y(i)PBest_y(i)=f;PBest_x(i,:)=x(i,:);end% Global Best searchingif PBest_y(i) > GBest_yGBest_y = PBest_y(i);GBest_x = PBest_x(i,:);end% Updating the speed and positionw=wmin+rand()*(wmax-wmin);      % weight is dynamicv(i,:) = w*v(i,:) + c1*rand()*(PBest_x(i,:)-x(i,:)) + c2*rand()*(GBest_x-x(i,:));for ii=1:dimensionif (v(i,ii)<-vmax)||(v(i,ii)>vmax)v(i,ii)=rand*(2*vmax)-vmax;endendvv(i,:)=1./(1+exp(-v(i,:)));for k=1:dimensionif vv(i,k)>randx(i,k)=1;elsex(i,k)=0;endendendRecord(k) = GBest_y;time = time+1;
endM = GBest_y;           % the value of the bag
N = GBest_x*weight;    % the weight of the bag
disp('---------------------------------------')
disp(['The final steal value is:',num2str(M)]);
disp(['The final steal weight is:',num2str(N)]);
string=strcat('Steal items:',num2str(GBest_x));
disp(string)

其中一次运行结果:

---------------------------------------
The final steal value is:76
The final steal weight is:44
Steal items:1  1  0  1  1  1  1  1  0  1  0  1选取第1,2,4,5,6,7,8,10,12个物品,总价值为76,总重量为44.

当然,PSO是一个基于概率的随机自搜索算法,每次的搜索结果都不尽相同,但是若算法的收敛性表现的较好,也可以认为对算法的设计是合理的。


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

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

相关文章

装饰器模式java_Java 8的装饰器模式

装饰器模式java在最近的一篇文章中&#xff0c;我描述了装饰器模式如何挽救了我的一天。 我给出了一个小代码段&#xff0c;其中包含创建装饰器的最简单方法&#xff0c;但承诺Java 8会有更好的方法。 这里是&#xff1a; 用Java 8装饰 HyperlinkListener listener this::ch…

C语言-反转字符串

实例代码// //实现功能&#xff1a;输入一个字符串&#xff0c;然后将该字符串反向输出 //#include "stdio.h" #include "string.h"#define N 50void convert_str(char str[N]);void convert_str(char str[N]){int j;char temp;for (int i 0; i < strl…

信捷步进指令的使用_步进电机驱动器的模式

步进电动机和步进电动机驱动器构成步进电机驱动系统。步进电动机驱动系统的性能&#xff0c;不但取决于步进电动机自身的性能&#xff0c;也取决于步进电动机驱动器的优劣。对步进电动机驱动器的研究几乎是与步进电动机的研究同步进行的。步进电机驱动器有三种基本的步进电机驱…

jersey客户端_每个客户使用Jersey处理的Cookie

jersey客户端许多REST服务会将cookie用作身份验证/授权方案的一部分。 这是一个问题&#xff0c;因为默认情况下&#xff0c;旧的Jersey客户端将使用单例CookieHandler.getDefault &#xff0c;大多数情况下该值为null&#xff0c;如果不为null&#xff0c;则在多线程服务器环境…

C语言灵魂篇|指针作为函数返回值

C语言允许函数的返回值是一个指针&#xff08;地址&#xff09;&#xff0c;我们将这样的函数称为指针函数。下面的例子定义了一个函数 strlong()&#xff0c;用来返回两个字符串中较长的一个&#xff1a;#include #includechar *strlong(char *str1, char *str2){ if(strlen(s…

css 样式尾部带感叹号是什么意思_CSS书写规范

推荐大家看看百度FEX前端团队和腾讯AlloyTeam前端团队的CSS代码规范。fex-team/styleguide​github.comCode Guide by AlloyTeam​alloyteam.github.io1. 样式属性顺序单个样式规则下的属性在书写时&#xff0c;应按功能进行分组&#xff0c;组之间需要有一个空行。同时要以Pos…

c++返回指针时候注意提防_Java 8陷阱–提防Files.lines()

c返回指针时候注意提防Java8中有一个非常不错的新功能&#xff0c;它使您可以在一个内衬中从文件中获取字符串流。 List lines Files.lines(path).collect(Collectors.toList());您可以像处理任何其他Stream一样操作Stream&#xff0c;例如&#xff0c;您可能需要filter&…

C语言精髓篇|函数的参数和返回值

如果把函数比喻成一台机器&#xff0c;那么参数就是原材料&#xff0c;返回值就是最终产品&#xff1b;从一定程度上讲&#xff0c;函数的作用就是根据不同的参数产生不同的返回值。函数的参数在函数定义中出现的参数可以看做是一个占位符&#xff0c;它没有数据&#xff0c;只…

oc引导win方法_[OC更新]机械革命X1/X6TIS标压测试版更新

加关注这种话银家怎么好意思说出口嘛更新机型机械革命X1 i5-7300hq机械革命X1 i7-7700hq机械革命X6tis i5-7300hq机械革命X6tis i7-7700hq更新内容基于OC0.6.2 MOD版本编译修复WIN下电脑被识别为MBP导致电竞中心打不开问题修复INTEL网卡在BIG SUR下不识别问题禁用secureboot mo…

java 打开gc日志_在运行时打开GC日志记录

java 打开gc日志总是有下一个JVM表现不佳。 而且&#xff0c;您内心深知&#xff0c;如果您只有少数启动选项可以公开一些有关正在发生的事情的信息&#xff0c;那么您可能就有机会真正修复该死的东西。 但是不&#xff0c;您需要的标志&#xff08; -XX&#xff1a; HeapDumpO…

C 和C语言条件运算符的区别

条件运算符&#xff08;conditional operator&#xff09;有时候也称为三元运算符&#xff08;ternary operator&#xff0c;或者trinary operator&#xff09;&#xff0c;因为它是唯一需要 3 个操作数的运算符&#xff1a;条件 ? 表达式1 : 表达式2条件运算操作会首先计算条…

oracle 执行带参数的sql语句_当用EXECUTE IMMEDIATE执行SQL语句中的参数个数也是动态的?用什么方法实现?...

当用EXECUTE IMMEDIATE执行SQL语句中的参数个数也是动态的&#xff1f;用什么方法实现&#xff1f;描述详细一点就是&#xff1a;在要执行的SQL语句中所用到(: parameter)这种参数的个数&#xff0c;因具体条件不同&#xff0c;而不同&#xff0c;而在执行语句EXECUTE IMMEDIAT…

xsl调用java方法传参_Java中的XSL转换:一种简单的方法

xsl调用java方法传参XSL转换 &#xff08;XSLT&#xff09;是将一个XML文档转换为另一个XML文档的强大机制。 但是&#xff0c;在Java中&#xff0c;XML操作相当冗长和复杂。 即使是简单的XSL转换&#xff0c;也必须编写几十行代码—如果需要适当的异常处理和日志记录&#xff…

C 运算符和语句总结

运算符&#xff1a; C 表达式中的左值和右值&#xff1a;当一个对象被用作左值时&#xff0c;用的是对象的身份&#xff08;内存中的位置&#xff09;。当作为右值时&#xff0c;用的是对象的值&#xff08;内容&#xff09;。或者说&#xff0c;lvalue:具有存贮性质的对象&…

# 遍历结构体_C#学习笔记05--枚举/结构体

一.枚举当变量的取值范围是固定的几个, 例如性别--男,女; 英雄类型 -- 法师, 刺客.战士, 射手等等. 这时就可以使用枚举类型, 会更加简洁方便.1.1.定义:访问修饰符 enum 枚举类型名 {成员1,成员2,成员3,... }public enum Days{Mon 1,Tue,Wed,Thu,Fri,Sat,Sun}enum: 是枚举的…

单例嵌套 ios_嵌套类型的前5个用例

单例嵌套 ios前几天&#xff0c;关于reddit进行了有趣的讨论&#xff0c;即静态内部类。 什么时候太多&#xff1f; 首先&#xff0c;让我们回顾一下Java的基本历史知识。 Java语言提供了四个级别的嵌套类 &#xff0c;通过“ Java语言”&#xff0c;我的意思是这些构造仅是“…

C语言中枚举enum的用法

本文举例说明C语言中enum枚举关键字的用法。用来同时定义多个常量利用enum定义月份的例子如下。#include enum week {Mon1,Tue,Wed,Thu,Fri,Sat,Sun}; int main() {printf("%d",Tue); return 0; }这样定义Mon的值为1之后&#xff0c;Tue的值就被默认定义为2&#…

苹果更新未知错误17_iOS 13 新功能,静音未知来电

果粉俱乐部让科技更好的服务生活点击上方「蓝字」加入我们iOS 13 正式版系统已经推出了快三周时间&#xff0c;苹果在新系统当中带来了诸多功能改进&#xff0c;包括大家盼望已久的深色模式&#xff0c;新的音量调节设置&#xff0c;自定义流量下载限制等等。除此之外&#xff…

C/C 语言中extern的用法

声明外部变量现代编译器一般采用按文件编译的方式&#xff0c;因此在编译时&#xff0c;各个文件中定义的全局变量是互相透明的&#xff0c;也就是说&#xff0c;在编译时&#xff0c;全局变量的可见域限制在文件内部。下面举一个简单的例子。创建一个工程&#xff0c;里面含有…

设置公共请求参数_封装一个useFetch实现页面销毁取消请求

前端业务经常会出现这样一类问题&#xff0c;当用户网速过慢或是其他特殊情况下&#xff0c;该页面的请求还未完成&#xff0c;用户就已经点击其他页面跳出去了。理想状态下请求也是应该终止掉的&#xff0c;所以我们应该想办法将请求和页面卸载关联在一起。1 使用AbortControl…