当前位置: 首页 > 编程日记 > 正文

粒子群算法(1)----粒子群简要

一、历史粒子群算法

从复杂适应系统衍生PSO算法(Complex Adaptive System,CAS)。CAS理论于1994年正式提出,CAS中的成员称为主体。比方研究鸟群系统,每一个鸟在这个系统中就称为主体。主体有适应性,它能够与环境及其它的主体进行交流,而且依据交流的过程学习积累经验改变自身结构与行为。

整个系统的演变或进化包括:新层次的产生(小鸟的出生);分化和多样性的出现(鸟群中的鸟分成很多小的群);新的主题的出现(鸟寻找食物过程中。不断发现新的食物)。

所以CAS系统中的主体具有4个基本特点(这些特点是粒子群算法发展变化的依据):

首先,主体是主动的、活动的。

主体与环境及其它主体是相互影响、相互作用的。这样的影响是系统发展变化的主要动力。

环境的影响是宏观的,主体之间的影响是微观的,宏观与微观要有机结合。

最后,整个系统可能还要受一些随机因素的影响。

粒子群算法就是对一个CAS系统---鸟群社会系统的研究得出的。

粒子群算法( Particle Swarm Optimization, PSO)最早是由EberhartKennedy1995年提出。它的基本概念源于对鸟群觅食行为的研究。设想这样一个场景:一群鸟在随机搜寻食物,在这个区域里仅仅有一块食物,全部的鸟都不知道食物在哪里,可是它们知道当前的位置离食物还有多远。那么找到食物的最优策略是什么呢?最简单有效的就是搜寻眼下离食物近期的鸟的周围区域。

PSO算法就从这样的生物种群行为特性中得到启示并用于求解优化问题。

PSO中,每一个优化问题的潜在解都能够想象成d维搜索空间上的一个点,我们称之为粒子Particle),全部的粒子都有一个被目标函数决定的适应值(Fitness Value ),每一个粒子另一个速度决定他们飞翔的方向和距离,然后粒子们就追随当前的最优粒子在解空间中搜索。Reynolds对鸟群飞行的研究发现。鸟仅仅是追踪它有限数量的邻居但终于的总体结果是整个鸟群好像在一个中心的控制之下.即复杂的全局行为是由简单规则的相互作用引起的。

二、粒子群算法的详细表述

上面罗嗦了半天。那些都是科研工作者写论文的语气,只是,PSO的历史就像上面说的那样。

以下通俗的解释PSO算法。

PSO算法就是模拟一群鸟寻找食物的过程,每一个鸟就是PSO中的粒子。也就是我们须要求解问题的可能解。这些鸟在寻找食物的过程中,不停改变自己在空中飞行的位置与速度。大家也能够观察一下,鸟群在寻找食物的过程中,開始鸟群比較分散,逐渐这些鸟就会聚成一群。这个群忽高忽低、忽左忽右。直到最后找到食物。这个过程我们转化为一个数学问题。

寻找函数  y=1-cos(3*x)*exp(-x)的在[0,4]最大值。

该函数的图形例如以下:

x=0.9350-0.9450,达到最大值y=1.3706

为了得到该函数的最大值,我们在[04]之间随机的洒一些点,为了演示,我们放置两个点,而且计算这两个点的函数值。同一时候给这两个点设置在[04]之间的一个速度。

以下这些点就会依照一定的公式更改自己的位置,到达新位置后。再计算这两个点的值,然后再依照一定的公式更新自己的位置。直到最后在y=1.3706这个点停止自己的更新。这个过程与粒子群算法作为对比例如以下:

这两个点就是粒子群算法中的粒子。

该函数的最大值就是鸟群中的食物

计算两个点函数值就是粒子群算法中的适应值,计算用的函数就是粒子群算法中的适应度函数。

更新自己位置的一定公式就是粒子群算法中的位置速度更新公式。

以下演示一下这个算法执行一次的大概过程:

第一次初始化

第一次更新位置

第二次更新位置

21次更新

最后的结果(30次迭代)

最后全部的点都集中在最大值的地方。

呵呵,如今粒子群算法的大概思想就讲到这里。下节介绍标准的粒子群算法。

粒子群算法(2)----标准的粒子群算法

在上一节的叙述中,唯一没有给大家介绍的就是函数的这些随机的点(粒子)是怎样运动的,仅仅是说依照一定的公式更新。

这个公式就是粒子群算法中的位置速度更新公式。

以下就介绍这个公式是什么。在上一节中我们求取函数y=1-cos(3*x)*exp(-x)的在[0,4]最大值。并在[0,4]之间放置了两个随机的点。这些点的坐标如果为x1=1.5。 x2=2.5;这里的点是一个标量,可是我们常常遇到的问题可能是更一般的情况--x为一个矢量的情况。比方二维的情况 z=2*x1+3*x22的情况。这个时候我们的每一个粒子为二维,记粒子P1(x11,x12),P2=(x21,x22),P3=(x31,x32)......Pn=(xn1,xn2)。这里n为粒子群群体的规模,也就是这个群中粒子的个数,每一个粒子的维数为2

更一般的是粒子的维数为q,这样在这个种群中有n个粒子,每一个粒子为维。

n个粒子组成的群体对Q维(就是每一个粒子的维数)空间进行搜索。

每一个粒子表示为:xi=(xi1,xi2,xi3,...,xiQ),每一个粒子相应的速度能够表示为vi=(vi1,vi2,vi3,....,viQ)。每一个粒子在搜索时要考虑两个因素:

1。自己搜索到的历史最优值 ppi=(pi1,pi2,....,piQ)i=1,2,3,....,n

2。全部粒子搜索到的最优值pgpg=(pg1,pg2,....,pgQ)。注意这里的pg仅仅有一个。

以下给出粒子群算法的位置速度更新公式:

这里有几个重要的參数须要大家记忆。由于在以后的解说中将会常常常使用到:

它们是:

是保持原来速度的系数,所以叫做惯性权重。

是粒子跟踪自己历史最优值的权重系数,它表示粒子自身的认识。所以叫认知

通常设置为2

是粒子跟踪群体最优值的权重系数。它表示粒子对整个群体知识的认识,所以叫做社会知识,常常叫做社会

通常设置为2

[0,1]区间内均匀分布的随机数。

是对位置更新的时候。在速度前面加的一个系数,这个系数我们叫做约束因子。

通常设置为1

这样一个标准的粒子群算法就结束了。

以下对整个主要的粒子群的过程给一个简单的图形表示:

推断终止条件可是设置适应值到达一定的数值或者循环一定的次数。

注意:这里的粒子是同一时候跟踪自己的历史最优值与全局(群体)最优值来改变自己的位置预速度的,所以又叫做全局版本号的标准粒子群优化算法。

粒子群算法(3)----标准的粒子群算法(局部版本号)

在全局版的标准粒子群算法中,每一个粒子的速度的更新是依据两个因素来变化的,这两个因素是:1. 粒子自己历史最优值pi2.  粒子群体的全局最优值pg如果改变粒子速度更新公式,让每一个粒子的速度的更新依据以下两个因素更新,A. 粒子自己历史最优值piB. 粒子邻域内粒子的最优值pnk

其余保持跟全局版的标准粒子群算法一样。这个算法就变为局部版的粒子群算法。

一般一个粒子的邻域随着迭代次数的添加而逐渐添加,開始第一次迭代,它的邻域为0,随着迭代次数邻域线性变大,最后邻域扩展到整个粒子群,这时就变成全局版本号的粒子群算法了。

经过实践证明:全局版本号的粒子群算法收敛速度快。可是easy陷入局部最优。局部版本号的粒子群算法收敛速度慢,可是非常难陷入局部最优。如今的粒子群算法大都在收敛速度与摆脱局部最优这两个方面下功夫。事实上这两个方面是矛盾的。看怎样更好的折中了。

依据取邻域的方式的不同,局部版本号的粒子群算法有非常多不同的实现方法。

第一种方法:依照粒子的编号取粒子的邻域。取法有四种:1。环形取法 2。随机环形取法 3,轮形取法 4,随机轮形取法。

1  环形随机环形

轮形 4随机轮形

由于后面有以环形取法实现的算法,对环形取法在这里做一点点说明:以粒子1为例。当邻域是0的时候,邻域是它本身,当邻域是1时。邻域为28;当邻域是2时,邻域是2378......。以此类推,一直到邻域为4,这个时候,邻域扩展到整个样例群体。

据文献介绍(国外的文献)。採用轮形拓扑结构,PSO的效果非常好

另外一种方法:依照粒子的欧式距离取粒子的邻域

在第一种方法中。依照粒子的编号来得到粒子的邻域,可是这些粒子事实上可能在实际位置上并不相邻。于是Suganthan提出基于空间距离的划分方案,在迭代中计算每一个粒子与群中其它粒子的距离。记录不论什么2个粒子间的的最大距离为dm。对每一粒子依照||xa-xb||/dm计算一个比值。

当中||xa-xb||是当前粒子ab的距离。而选择阈值frac依据迭代次数而变化。当另一粒子b满足||xa-xb||/dm<frac时,觉得b成为当前粒子的邻域。

这样的办法经过实验。取得较好的应用效果。可是由于要计算全部粒子之间的距离,计算量大。且须要非常大的存储空间,所以。该方法一般不常常使用。

粒子群算法(4)----粒子群算法分类

粒子群算法主要分为4个大的分支:

1)标准粒子群算法的变形

在这个分支中。主要是对标准粒子群算法的惯性因子、收敛因子(约束因子)、认知部分的c1社会部分的c2进行变化与调节。希望获得好的效果。

惯性因子的原始版本号是保持不变的。后来有人提出随着算法迭代的进行,惯性因子须要逐渐减小的思想。算法開始阶段。大的惯性因子能够是算法不easy陷入局部最优。到算法的后期,小的惯性因子能够使收敛速度加快。使收敛更加平稳,不至于出现振荡现象。

经过本人測试,动态的减小惯性因子w,的确能够使算法更加稳定,效果比較好。可是递减惯性因子採用什么样的方法呢?人们首先想到的是线型递减,这样的策略的确非常好。可是是不是最优的呢?于是有人对递减的策略作了研究。研究结果指出:线型函数的递减优于凸函数的递减策略,可是凹函数的递减策略又优于线型的递减,经过本人測试,实验结果基本符合这个结论。可是效果不是非常明显。

对于收敛因子,经过证明如果收敛因子取0.729,能够确保算法的收敛,可是不能保证算法收敛到全局最优,经过本人測试,取收敛因子为0.729效果较好。

对于社会与认知的系数c2,c1也有人提出:c1先大后小,而c2先小后大的思想,由于在算法执行初期,每一个鸟要有大的自己的认知部分而又比較小的社会部分,这个与我们自己一群人找东西的情形比較接近。由于在我们找东西的初期。我们基本依靠自己的知识取寻找。而后来。我们积累的经验越来越丰富,于是大家開始逐渐达成共识(社会知识)。这样我们就開始依靠社会知识来寻找东西了。

2007年希腊的两位学者提出将收敛速度比較快的全局版本号的粒子群算法与不easy陷入局部最优的局部版本号的粒子群算法相结合的办法,利用的公式是

vn*v(全局版本号)+(1n*v(局部版本号)       速度更新公式,v代表速度

wk1)=w(k)v                     位置更新公式

该算法在文献中讨论了系数n取各种不同情况的情况,而且执行来了20000次来分析各种系数的结果。

2)粒子群算法的混合

这个分支主要是将粒子群算法与各种算法相混合,有人将它与模拟退火算法相混合。有些人将它与单纯形方法相混合。可是最多的是将它与遗传算法的混合。依据遗传算法的三种不同算子能够生成3中不同的混合算法。

粒子群算法与选择算子的结合,这里相混合的思想是:在原来的粒子群算法中。我们选择粒子群群体的最优值作为pg。可是相结合的版本号是依据全部粒子的适应度的大小给每一个粒子赋予一个被选中的概率,然后依据概率对这些粒子进行选择,被选中的粒子作为pg,其它的情况都不变。这样的算法能够在算法执行过程中保持粒子群的多样性。可是致命的缺点是收敛速度缓慢。

粒子群算法与杂交算子的结合,结合的思想与遗传算法的基本一样,在算法执行过程中依据适应度的大小。粒子之间能够两两杂交,比方用一个非常easy的公式

w(新)=n×w1+(1n×w2

w1w2就是这个新粒子的父辈粒子。

这样的算法能够在算法的执行过程中引入新的粒子,可是算法一旦陷入局部最优。那么粒子群算法将非常难摆脱局部最优。

粒子群算法与变异算子的结合。结合的思想:測试全部粒子与当前最优的距离,当距离小于一定的数值的时候,能够拿出全部粒子的一个百分比(如10%)的粒子进行随机初始化。让这些粒子又一次寻找最优值。

3)二进制粒子群算法

最初的PSO是从解决连续优化问题发展起来的.Eberhart等又提出了PSO的离散二进制版.用来解决project实际中的组合优化问题。他们在提出的模型中将粒子的每一维及粒子本身的历史最优、全局最优限制为10,而速度不作这样的限制。用速度更新位置时,设定一个阈值,当速度高于该阈值时。粒子的位置取1,否则取0

二进制PSO与遗传算法在形式上非常类似,但实验结果显示,在大多数測试函数中。二进制PSO比遗传算法速度快,尤其在问题的维数添加时

4)协同粒子群算法

协同PSO,该方法将粒子的D维分到D个粒子群中。每一个粒子群优化一维向量,评价适应度时将这些分量合并为一个完整的向量。比如第i个粒子群,除第i个分量外。其它D-1个分量都设为最优值,不断用第i个粒子群中的粒子替换第i个分量。直到得到第i维的最优值,其它维同样。为将有联系的分量划分在一个群,可将D维向量分配到m个粒子群优化,则前D mod m个粒子群的维数是D/m的向上取整。

m(D mod m)个粒子群的维数是D/m的向下取整。协同PSO在某些问题上有更快的收敛速度。但该算法easy被欺骗。

主要的粒子群算法的分支就着4个。大部分的粒子群算法都环绕着这4个分支在变化。当中粒子群算法的变形居多。从根本上来说。差点儿没有什么新的思想的提出。

粒子群算法(5)-----标准粒子群算法的实现

标准粒子群算法的实现思想基本依照粒子群算法(2)----标准的粒子群算法的讲述实现。主要分为3个函数。第一个函数为粒子群初始化函数

InitSwarm(SwarmSize......AdaptFunc)其主要作用是初始化粒子群的粒子,并设定粒子的速度、位置在一定的范围内。本函数所採用的数据结构例如以下所看到的:

ParSwarm记录的是粒子的位置、速度与当前的适应度值,我们用W来表示位置。用V来代表速度,用F来代表当前的适应度值。在这里我们如果粒子个数为N,每一个粒子的维数为D

W1,1

W1,2

...

W1,D

V1,1

V1,2

...

V1,D-1

V1,D

F1

1个粒子

W2,1

W2,2

...

W2,D

V2,1

V2,2

...

V2,D-1

V2,D

F2

2个粒子

...

...

...

...

...

...

...

...

...

...

.......

WN-1,1

WN-1,2

...

WN-1,D-1

VN-1,1

VN-1,2

...

VN-1,D-1

VN-1,D

FN-1

N-1个粒子

WN,1

WN,2

...

WN,D

VN,1

VN,2

...

VN,D-1

VN,D

FN

N个粒子

OptSwarm记录每一个粒子的历史最优解(粒子历史最好的适应度)以及全部粒子搜索到的全局最优解。

Wg代表全局最优解。W.,1代表每一个粒子的历史最优解。粒子群初始化阶段表OptSwarm的前N行与表ParSwarm中的同样,而Wg的值为表ParSwarm中适应度值的最大值相应的行。

Wj,1

Wj,2

...

Wj,D-1

Wj,D

1个粒子的历史最优解

Wk,1

Wk,2

...

Wk,D-1

Wk,D

2个粒子的历史最优解

...

...

...

...

...

...

Wl,1

Wl,2

...

Wl,D-1

Wl,D

N-1个粒子的历史最优解

Wm,1

Wm,2

...

Wm,D-1

Wm,D

N个粒子的历史最优解

Wg,1

Wg,2

...

Wg,D-1

Wg,D

全局粒子的历史最优解

依据这样的思想MATLAB代码例如以下:

function [ParSwarm,OptSwarm]=InitSwarm(SwarmSize,ParticleSize,ParticleScope,AdaptFunc)

%功能描写叙述:初始化粒子群,限定粒子群的位置以及速度在指定的范围内

%[ParSwarm,OptSwarm,BadSwarm]=InitSwarm(SwarmSize,ParticleSize,ParticleScope,AdaptFunc)

%

%输入參数:SwarmSize:种群大小的个数

%输入參数:ParticleSize:一个粒子的维数

%输入參数:ParticleScope:一个粒子在运算中各维的范围;

%         ParticleScope格式:

%           3维粒子的ParticleScope格式:

%                                   [x1Min,x1Max

%                                    x2Min,x2Max

%                                    x3Min,x3Max]

%

%输入參数:AdaptFunc:适应度函数

%

%输出:ParSwarm初始化的粒子群

%输出:OptSwarm粒子群当前最优解与全局最优解

%

%使用方法[ParSwarm,OptSwarm,BadSwarm]=InitSwarm(SwarmSize,ParticleSize,ParticleScope,AdaptFunc);

%

%异常:首先保证该文件在Matlab的搜索路径中,然后查看相关的提示信息。

%

%编制人:XXX

%编制时间:2007.3.26

%參考文献:无

%

%容错控制

if nargin~=4

error('输入的參数个数错误。

')

end

if nargout<2

error('输出的參数的个数太少,不能保证以后的执行。');

end

[row,colum]=size(ParticleSize);

if row>1|colum>1

error('输入的粒子的维数错误,是一个11列的数据。');

end

[row,colum]=size(ParticleScope);

if row~=ParticleSize|colum~=2

error('输入的粒子的维数范围错误。

');

end

%初始化粒子群矩阵

%初始化粒子群矩阵,全部设为[0-1]随机数

%rand('state',0);

ParSwarm=rand(SwarmSize,2*ParticleSize+1);

%对粒子群中位置,速度的范围进行调节

for k=1:ParticleSize

ParSwarm(:,k)=ParSwarm(:,k)*(ParticleScope(k,2)-ParticleScope(k,1))+ParticleScope(k,1);

%调节速度。使速度与位置的范围一致

ParSwarm(:,ParticleSize+k)=ParSwarm(:,ParticleSize+k)*(ParticleScope(k,2)-ParticleScope(k,1))+ParticleScope(k,1);

end

%对每一个粒子计算其适应度函数的值

for k=1:SwarmSize

ParSwarm(k,2*ParticleSize+1)=AdaptFunc(ParSwarm(k,1:ParticleSize));

end

%初始化粒子群最优解矩阵

OptSwarm=zeros(SwarmSize+1,ParticleSize);

%粒子群最优解矩阵全部设为零

[maxValue,row]=max(ParSwarm(:,2*ParticleSize+1));

%寻找适应度函数值最大的解在矩阵中的位置(行数)

OptSwarm=ParSwarm(1:SwarmSize,1:ParticleSize);

OptSwarm(SwarmSize+1,:)=ParSwarm(row,1:ParticleSize);

以下的函数BaseStepPso实现了标准全局版粒子群算法的单步更新位置速度的功能

function [ParSwarm,OptSwarm]=BaseStepPso(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)

%功能描写叙述:全局版本号:主要的粒子群算法的单步更新位置,速度的算法

%

%[ParSwarm,OptSwarm]=BaseStepPso(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)

%

%输入參数:ParSwarm:粒子群矩阵,包括粒子的位置。速度与当前的目标函数值

%输入參数:OptSwarm:包括粒子群个体最优解与全局最优解的矩阵

%输入參数:ParticleScope:一个粒子在运算中各维的范围;

%输入參数:AdaptFunc:适应度函数

%输入參数:LoopCount:迭代的总次数

%输入參数:CurCount:当前迭代的次数

%

%返回值:含意同输入的同名參数

%

%使用方法:[ParSwarm,OptSwarm]=BaseStepPso(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)

%

%异常:首先保证该文件在Matlab的搜索路径中,然后查看相关的提示信息。

%

%编制人:XXX

%编制时间:2007.3.26

%參考文献:XXX

%參考文献:XXX

%

%改动记录

%----------------------------------------------------------------

%2007.3.27

%改动人:XXX

加入2*unifrnd(0,1).*SubTract1(row,:)中的unifrnd(0,1)随机数,使性能大为提高

%參照基于MATLAB的粒子群优化算法程序设计

%

总体评价:使用这个版本号的调节系数,效果比較好

%

%容错控制

if nargin~=8

error('输入的參数个数错误。

')

end

if nargout~=2

error('输出的个数太少,不能保证循环迭代。

')

end

%開始单步更新的操作

%*********************************************

%*****更改以下的代码,能够更改惯性因子的变化*****

%---------------------------------------------------------------------

%线形递减策略

w=MaxW-CurCount*((MaxW-MinW)/LoopCount);

%---------------------------------------------------------------------

%w固定不变策略

%w=0.7;

%---------------------------------------------------------------------

%參考文献:陈贵敏,贾建援,韩琪,粒子群优化算法的惯性权值递减策略研究,西安交通大学学报。20061

%w非线形递减,以凹函数递减

%w=(MaxW-MinW)*(CurCount/LoopCount)^2+(MinW-MaxW)*(2*CurCount/LoopCount)+MaxW;

%---------------------------------------------------------------------

%w非线形递减,以凹函数递减

%w=MinW*(MaxW/MinW)^(1/(1+10*CurCount/LoopCount));

%*****更改上面的代码,能够更改惯性因子的变化*****

%*********************************************

%得到粒子群群体大小以及一个粒子维数的信息

[ParRow,ParCol]=size(ParSwarm);

%得到粒子的维数

ParCol=(ParCol-1)/2;

SubTract1=OptSwarm(1:ParRow,:)-ParSwarm(:,1:ParCol);

%*********************************************

%*****更改以下的代码。能够更改c1,c2的变化*****

c1=2;

c2=2;

%---------------------------------------------------------------------

%con=1;

%c1=4-exp(-con*abs(mean(ParSwarm(:,2*ParCol+1))-AdaptFunc(OptSwarm(ParRow+1,:))));

%c2=4-c1;

%----------------------------------------------------------------------

%*****更改上面的代码,能够更改c1,c2的变化*****

%*********************************************

for row=1:ParRow

SubTract2=OptSwarm(ParRow+1,:)-ParSwarm(row,1:ParCol);

TempV=w.*ParSwarm(row,ParCol+1:2*ParCol)+2*unifrnd(0,1).*SubTract1(row,:)+2*unifrnd(0,1).*SubTract2;

%限制速度的代码

for h=1:ParCol

if TempV(:,h)>ParticleScope(h,2)

TempV(:,h)=ParticleScope(h,2);

end

if TempV(:,h)<-ParticleScope(h,2)

TempV(:,h)=-ParticleScope(h,2)+1e-10;

%1e-10防止适应度函数被零除

end

end  

%更新速度

ParSwarm(row,ParCol+1:2*ParCol)=TempV;

%*********************************************

%*****更改以下的代码,能够更改约束因子的变化*****

%---------------------------------------------------------------------

%a=1;

%---------------------------------------------------------------------

a=0.729;

%*****更改上面的代码,能够更改约束因子的变化*****

%*********************************************

%限制位置的范围

TempPos=ParSwarm(row,1:ParCol)+a*TempV;

for h=1:ParCol

if TempPos(:,h)>ParticleScope(h,2)

TempPos(:,h)=ParticleScope(h,2);

end

if TempPos(:,h)<=ParticleScope(h,1)

TempPos(:,h)=ParticleScope(h,1)+1e-10;           

end

end

%更新位置 

ParSwarm(row,1:ParCol)=TempPos;

%计算每一个粒子的新的适应度值

ParSwarm(row,2*ParCol+1)=AdaptFunc(ParSwarm(row,1:ParCol));

if ParSwarm(row,2*ParCol+1)>AdaptFunc(OptSwarm(row,1:ParCol))

OptSwarm(row,1:ParCol)=ParSwarm(row,1:ParCol);

end

end

%for循环结束

%寻找适应度函数值最大的解在矩阵中的位置(行数),进行全局最优的改变 

[maxValue,row]=max(ParSwarm(:,2*ParCol+1));

if AdaptFunc(ParSwarm(row,1:ParCol))>AdaptFunc(OptSwarm(ParRow+1,:))

OptSwarm(ParRow+1,:)=ParSwarm(row,1:ParCol);

end

这两个函数给出以后。须要一个函数来把这两个函数组装起来。以此实现一个完整的粒子群算法,这个函数就是PsoProcess

代码例如以下:

function [Result,OnLine,OffLine,MinMaxMeanAdapt]=PsoProcess(SwarmSize,ParticleSize,ParticleScope,InitFunc,StepFindFunc,AdaptFunc,IsStep,IsDraw,LoopCount,IsPlot)

%功能描写叙述:一个循环n次的PSO算法完整过程,返回这次执行的最小与最大的平均适应度,以及在线性能与离线性能

%[Result,OnLine,OffLine,MinMaxMeanAdapt]=PsoProcess(SwarmSize,ParticleSize,ParticleScope,InitFunc,StepFindFunc,AdaptFunc,IsStep,IsDraw,LoopCount,IsPlot)

%输入參数:SwarmSize:种群大小的个数

%输入參数:ParticleSize:一个粒子的维数

%输入參数:ParticleScope:一个粒子在运算中各维的范围;

%         ParticleScope格式:

%           3维粒子的ParticleScope格式:

%                                   [x1Min,x1Max

%                                    x2Min,x2Max

%                                    x3Min,x3Max]

%

%输入參数:InitFunc:初始化粒子群函数

%输入參数:StepFindFunc:单步更新速度。位置函数

%输入參数:AdaptFunc:适应度函数

%输入參数:IsStep:是否每次迭代暂停;IsStep0,不暂停。否则暂停。缺省不暂停

%输入參数:IsDraw:是否图形化迭代过程;IsDraw0。不图形化迭代过程,否则,图形化表示。

缺省不图形化表示

%输入參数:LoopCount:迭代的次数。缺省迭代100

%输入參数:IsPlot:控制是否绘制在线性能与离线性能的图形表示;IsPlot=0,不显示;

%                 IsPlot=1;显示图形结果。缺省IsPlot=1

%

%返回值:Result为经过迭代后得到的最优解

%返回值:OnLine为在线性能的数据

%返回值:OffLine为离线性能的数据

%返回值:MinMaxMeanAdapt为本次完整迭代得到的最小与最大的平均适应度

%

%使用方法[Result,OnLine,OffLine,MinMaxMeanAdapt]=PsoProcess(SwarmSize,ParticleSize,ParticleScope,InitFunc,StepFindFunc,AdaptFunc,IsStep,IsDraw,LoopCount,IsPlot);

%

%异常:首先保证该文件在Matlab的搜索路径中。然后查看相关的提示信息。

%

%编制人:XXX

%编制时间:2007.3.26

%參考文献:XXXXX%

%改动记录:

%加入MinMaxMeanAdapt,以得到性能评估数据

%改动人:XXX

%改动时间:2007.3.27

%參考文献:XXX.

%容错控制

if nargin<4

error('输入的參数个数错误。')

end

[row,colum]=size(ParticleSize);

if row>1|colum>1

error('输入的粒子的维数错误,是一个11列的数据。

');

end

[row,colum]=size(ParticleScope);

if row~=ParticleSize|colum~=2

error('输入的粒子的维数范围错误。

');

end

%设置缺省值

if nargin<7

IsPlot=1;

LoopCount=100;

IsStep=0;

IsDraw=0;

end

if nargin<8

IsPlot=1;

IsDraw=0;

LoopCount=100;

end

if nargin<9

LoopCount=100;

IsPlot=1;

end

if nargin<10

IsPlot=1;

end

%控制是否显示2维以下粒子维数的寻找最优的过程

if IsDraw~=0

DrawObjGraphic(ParticleSize,ParticleScope,AdaptFunc);

end

%初始化种群       

[ParSwarm,OptSwarm]=InitFunc(SwarmSize,ParticleSize,ParticleScope,AdaptFunc)

%在測试函数图形上绘制初始化群的位置

if IsDraw~=0

if 1==ParticleSize

for ParSwarmRow=1:SwarmSize

plot([ParSwarm(ParSwarmRow,1),ParSwarm(ParSwarmRow,1)],[ParSwarm(ParSwarmRow,3),0],'r*-','markersize',8);

text(ParSwarm(ParSwarmRow,1),ParSwarm(ParSwarmRow,3),num2str(ParSwarmRow));

end

end

if 2==ParticleSize

for ParSwarmRow=1:SwarmSize

stem3(ParSwarm(ParSwarmRow,1),ParSwarm(ParSwarmRow,2),ParSwarm(ParSwarmRow,5),'r.','markersize',8);

end

end

end

%暂停让抓图

if IsStep~=0

disp('開始迭代。按随意键:')

pause

end

%開始更新算法的调用

for k=1:LoopCount

%显示迭代的次数:

disp('----------------------------------------------------------')

TempStr=sprintf('第 %g 此迭代',k);

disp(TempStr);

disp('----------------------------------------------------------')

%调用一步迭代的算法

[ParSwarm,OptSwarm]=StepFindFunc(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,0.95,0.4,LoopCount,k)

%在目标函数的图形上绘制2维以下的粒子的新位置

if IsDraw~=0

if 1==ParticleSize

for ParSwarmRow=1:SwarmSize

plot([ParSwarm(ParSwarmRow,1),ParSwarm(ParSwarmRow,1)],[ParSwarm(ParSwarmRow,3),0],'r*-','markersize',8);

text(ParSwarm(ParSwarmRow,1),ParSwarm(ParSwarmRow,3),num2str(ParSwarmRow));

end

end

if 2==ParticleSize

for ParSwarmRow=1:SwarmSize

stem3(ParSwarm(ParSwarmRow,1),ParSwarm(ParSwarmRow,2),ParSwarm(ParSwarmRow,5),'r.','markersize',8);

end

end

end

XResult=OptSwarm(SwarmSize+1,1:ParticleSize);

YResult=AdaptFunc(XResult);    

if IsStep~=0

XResult=OptSwarm(SwarmSize+1,1:ParticleSize);

YResult=AdaptFunc(XResult);    

str=sprintf('%g步迭代的最优目标函数值%g',k,YResult);

disp(str);

disp('下次迭代,按随意键继续');

pause

end

%记录每一步的平均适应度

MeanAdapt(1,k)=mean(ParSwarm(:,2*ParticleSize+1));

end

%for循环结束标志

%记录最小与最大的平均适应度

MinMaxMeanAdapt=[min(MeanAdapt),max(MeanAdapt)];

%计算离线与在线性能

for k=1:LoopCount

OnLine(1,k)=sum(MeanAdapt(1,1:k))/k;

OffLine(1,k)=max(MeanAdapt(1,1:k));

end

for k=1:LoopCount

OffLine(1,k)=sum(OffLine(1,1:k))/k;

end

%绘制离线性能与在线性能曲线

if 1==IsPlot

figure

hold on

title('离线性能曲线图')

xlabel('迭代次数');

ylabel('离线性能');

grid on

plot(OffLine);

figure

hold on

title('在线性能曲线图')

xlabel('迭代次数');

ylabel('在线性能');

grid on

plot(OnLine);

end

%记录本次迭代得到的最优结果

XResult=OptSwarm(SwarmSize+1,1:ParticleSize);

YResult=AdaptFunc(XResult);

Result=[XResult,YResult];

这里给出一个使用的样例代码,并分别解释各參数的含义:

%打开计时器

tic;

%

Scope=[-50 50

-50 50

-50 50

-50 50

-50 50

-50 50

-50 50

-50 50

-50 50

-50 50];

[v,on,off,minmax]=PsoProcess(20,10,Scope,@initswarm,@BasestepPSO,@Griewank,0,0,4000,0);

toc

在上面的代码中函数PsoProcess中的20代表粒子群的规模为20个,10代表每一个粒子的维数为10Scope是粒子的每一维的范围。同一时候也是速度的范围,@initswarm是初始化函数的句柄,@BasestepPSO是单步更新的函数句柄,@Griewank是适应度评价函数的句柄。4000代表真个算法循环4000次终止,其它參数參见说明文档。

粒子群算法(6)-----几个适应度评价函数

以下给出几个适应度评价函数。并给出图形表示

头几天机子种了病毒,又一次安装了系统。不小心把程序全部格式化了,痛哭。!

没办法,好多程序不见了。如今把这几个典型的函数又一次编写了。把他们给出来,就算粒子群算法的一个结束吧!

痛恨病毒!!

!!

第一个函数:Griewank函数,图形例如以下所看到的:

适应度函数例如以下:(为了求最大值,我去了全部函数值的相反数)

function y=Griewank(x)
%Griewan函数
%输入x,给出相应的y,x=(0,0,…,0)处有全局极小点0.
%编制人:
%编制日期:
[row,col]=size(x);
if row>1
    error('输入的參数错误');
end
y1=1/4000*sum(x.^2);
y2=1;
for h=1:col
    y2=y2*cos(x(h)/sqrt(h));
end
y=y1-y2+1;
y=-y;

绘制函数图像的代码例如以下:

function DrawGriewank()
%绘制Griewank函数图形
x=[-8:0.1:8];
y=x;
[X,Y]=meshgrid(x,y);
[row,col]=size(X);
for l=1:col
    for h=1:row
        z(h,l)=Griewank([X(h,l),Y(h,l)]);
    end
end
surf(X,Y,z);
shading interp

第二个函数:Rastrigin函数。图形例如以下所看到的:

适应度函数例如以下:(为了求最大值,我去了全部函数值的相反数)

function y=Rastrigin(x)
%Rastrigin函数
%输入x,给出相应的y,x=(0,0,…,0)处有全局极小点0.
%编制人:
%编制日期:
[row,col]=size(x);
if row>1
    error('输入的參数错误');
end
y=sum(x.^2-10*cos(2*pi*x)+10);
y=-y;

绘制函数图像的代码例如以下:

function DrawRastrigin()
%绘制Rastrigin函数图形
x=[-5:0.05:5];
y=x;
[X,Y]=meshgrid(x,y);
[row,col]=size(X);
for l=1:col
    for h=1:row
        z(h,l)=Rastrigin([X(h,l),Y(h,l)]);
    end
end
surf(X,Y,z);
shading interp

粒子群有如此惨败。

相关文章:

Android Studio Day03-2(常用操作)

&#xff08;1&#xff09;选择文本 1.CtrlA 选中全文 2.在将光标置于任意的单词中时按住CtrlW&#xff0c;选中整个词 继续按CtrlW 选中的区域将扩大&#xff0c;扩大至包含任意数量的相邻的单词 按CtrlwShift 进行区域的缩小 &#xff08;2&#xff09;Undo和Redo&…

Blender数字雕刻终极指南学习教程

CGBoost–Blender中的3D雕刻大师–数字雕刻终极指南 大小&#xff1a;29G 含课程项目文件 Master 3D Sculpting in Blender – The Ultimate Guide to Digital Sculpting 本课程教你所有重要的Blender雕刻基础知识&#xff0c;以及如何仅使用免费工具从头开始创建令人惊叹的3D雕…

生产指挥调度系统_市安全生产应急救援指挥中心将大型装载机械设备储备信息纳入应急指挥调度系统...

为拓展应急救援力量体系&#xff0c;发挥社会力量在开展全市重特大突发事件应急救援中的重要作用&#xff0c;近日&#xff0c;市安全生产应急救援指挥中心在加强应急指挥信息平台“一网七库”建设的基础上&#xff0c;成功对接甘肃省非道路移动机械监管平台&#xff0c;做到数…

java.sql.Exception:setString 只能处理少于 32766 个字符的字符串

java.sql.Exception:setString 只能处理少于 32766 个字符的字符串 解决方式是 : 升级ojdbc的版本, 将原来的 ojdbc14_10.2.0.2.0.jar 升级到 ojdbc6_11.2.0.1.0.jar这边行方用的是 oracle版本是 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0maven 安装到本地…

无需自己输入include这些的方法

使用项目模板为 windows 桌面向导 c 不用空白项 直接默认 不用勾选其他

第二次团队冲刺2

实现了查询的webservice服务端&#xff0c;做了查询时等待界面&#xff0c;对查询速度做了一点优化。 还写了一个入馆须知模块&#xff0c;介绍图书馆借阅规则。 还有借阅个人信息没做出来&#xff0c;还没进行界面优化。 转载于:https://www.cnblogs.com/318abc/p/4569576.htm…

Android StudioDay03-3(键盘导航)

Android Studio Day03-3(键盘导航) (1)打开Select In 快捷键&#xff1a;altF1 如下图&#xff1a; &#xff08;2&#xff09;打开Class CtrlN Class操作允许用后导航到特定的JAVA类&#xff09;&#xff0c;因此此操作也只能在Java文件中使用。 Android studio已…

虚幻中的风格化环境制作学习教程

Learn Squared-Tyler Smith-虚幻中的风格化环境 信息: 像AAA游戏开发者一样在虚幻引擎中创建风格化的环境。行业领先的游戏艺术家泰勒史密斯将教你在虚幻引擎中构建美丽的实时世界的规划、构建、集成和优化阶段使用多种巧妙的技术。 大小解压后&#xff1a;22G 时长6h 13m 19…

【转】oracle PLSQL基础学习

【转】oracle PLSQL基础学习 --oracle 练习&#xff1b;/**************************************************PL/SQL编程基础***************************************************************/--firstday--》》》数据类型-- Create tablecreate table T_CSCUSTOMER( CUST_NO…

python如何创建不同元素的矩阵_python – 如何在数据帧中创建矩阵元素的数...

我在.TXT文件中有3个参数’A’,’B’,’C’的数据集,在我用2420矩阵打印后,我需要收集’A’,’B’,’C’的第一个元素熊猫数据帧中的长数组,然后是每个第二个元素,然后是第3个,直到第480个元素为止. 所以我的数据在文本文件中是这样的&#xff1a; 我的数据是txt文件如下&#…

wps多窗口打开

在wps中打开wps文档不在一个窗口的方法如下&#xff1a; 1、启动wps文档&#xff0c;点击wps文字→选项&#xff0c;在弹出的选项对话框点击视图选项卡&#xff0c;勾选 在任务栏中显示所有窗口&#xff1b;

RHEL7.0系列 修改字符终端分辨率

由于是在VM里面安装的&#xff0c;完了之后终端界面的分辨率非常高&#xff0c;很难操作 因为RHEL7用了grub2&#xff0c;而不再是grub了&#xff0c;在grub2中要修改的文件是/boot/grub2/grub.cfg; 这里有一张分辨率的对照表&#xff08;在grub.cfg中添加vgaask,系统重启后就会…

Java Day01-1

1.JAVA语言介绍 &#xff08;1&#xff09;特点&#xff1a;可移植性&#xff0c;平台无关性&#xff0c;面相对性&#xff0c;健壮性&#xff0c;分布式&#xff0c;多线程 &#xff08;2&#xff09;版本&#xff1a;JavaSE&#xff08;标准版&#xff09;、JavaME&#xf…

Autocad 3D 完全学习教程

Autocad 3D 完全学习教程 你会学到什么 如何使用AutoCAD三维基本特征 了解如何在AutoCAD中创建和开发三维模型 准备实体、网格和曲面几何图形 不同的命令2d和3D 要求 不需要事先了解 18章 63节讲座 全长5小时7分 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译…

[转]JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分

首先这是现在最基本的分层方式&#xff0c;结合了SSH架构。modle层就是对应的数据库表的实体类。Dao层是使用了Hibernate连接数据库、操作数据库&#xff08;增删改查&#xff09;。Service层&#xff1a;引用对应的Dao数据库操作&#xff0c;在这里可以编写自己需要的代码&…

springmvc工作流程简单易懂_三极管的结构和工作特性,简单易懂

今天&#xff0c;我们来认识另一种十分重要的半导体器件&#xff1a;三极管。生活中&#xff0c;授课、集会、维持秩序等场合需要用到扩音器、音响等设备&#xff0c;这些设备之所以能够放大声音是因为它们都包含放大器&#xff0c;而放大器的核心部件就是三极管。那三极管究竟…

多个excel文件(内含多个工作表)查找

1.在父目录查找处输入关键词 2.将找到的文件进去查找-工作簿

git ssh key创建和github使用

github拉代码需要ssh验证 git是分布式的代码管理工具&#xff0c;远程的代码管理是基于ssh的&#xff0c;所以要使用远程的git则需要ssh的配置。一 、设置git&#xff1a;设置git的user name和email&#xff1a;$ git config --global user.name "xxx"$ git config -…

C语言常见面试题:什么是变量?变量有哪些作用?

变量是编程中的一个基本概念,其定义和用法因编程语言和上下文而异。但通常来说,变量是用于存储数据的容器,这些数据可以是数字、文本、布尔值等。总的来说,变量在编程中扮演着重要的角色,它们使得我们能够有效地存储、操作和使用数据。不同的编程语言和上下文可能会对变量的具体定义和使用方式有所不同,但上述作用是通用的。总的来说,变量和常量都是编程中重要的概念,它们各自有其特定的用途和特性。在编程中正确地使用它们可以帮助我们更好地组织和控制程序的行为。变量和常量在编程中都是重要的概念,但它们之间存在明显的区别。

Java Day01-2

一、字节码的解释 字节码&#xff1a;是一种在Java运行系统&#xff08;JVM&#xff09;中执行的更高度优化的指令集。 C/C 是一种编译型的语言; 文件经过编辑&#xff0c;编译&#xff0c;执行之后生成的是一种.exe的可执行文件。 Java&#xff1a;是一种解释型的语言&…

SparkSQL和Hadoop(面向数据科学家和大数据分析师)

了解HDFS命令、Hadoop、Spark SQL、SQL查询、ETL和数据分析| Spark Hadoop集群虚拟机|完全解决的问题 你会学到什么 作为本课程的一部分&#xff0c;学生将获得在Spark Hadoop环境中工作的实践经验&#xff0c;该环境是免费且可下载的。 学生将有机会在沙箱环境中使用Hadoop集…

uva 401.Palindromes

题目链接&#xff1a;https://uva.onlinejudge.org/index.php?optioncom_onlinejudge&Itemid8&pageshow_problem&problem342 题目意思&#xff1a;给出一段字符串&#xff08;大写字母数字组成&#xff09;。判断是否为回文串 or 镜像串 or 回文镜像串 or 什么都不…

python解压_python解压缩

解压缩 如果我们给出一个列表&#xff0c;我们需要一次性取出多个值&#xff0c;我们是不是可以用下面的方式实现呢&#xff1f; name_list [chen, python, jason] x name_list[0] y name_list[1] z name_list[2] print(fx:{x}, y:{y}, z:{z}) #输出&#xff1a; x:chen, y…

用Construct 2制作入门小游戏~

今天在软导课上了解到了Construct 2这个神器&#xff0c;本零基础菜鸟决定尝试做一个简单的小游戏&#xff08;实际上是入门的教程啊 首先呢&#xff0c;肯定是到官网下载软件啊&#xff0c;点击我下载~ 等安装完毕后我便按照新手教程开始捣鼓了 ①先下载素材&#xff08;准…

zabbix 客户端安装

zabbix 客户端安装zabbix版本为&#xff1a;zabbix-2.4.5Linux 客户端安装1.防火墙开启iptables -A INPUT -p tcp --dport 10050 -j ACCEPTiptables -A INPUT -p udp --dport 10050 -j ACCEPT2.安装zabbix####zabbix 安装包可去zabbix.com 官网上下载tar zxvf zabbix-2.4.5.tar…

Java Day02-1

一、变量和常量 &#xff08;1&#xff09;java中的变量 1.使用标识符为变量取名字 2.变量声明的时候要给出它是八大类型中的哪一种类型&#xff0c;然后根据具体的类型为其分配适合的空间 3.变量就是可以变化的量&#xff0c;他里面的内容可以改变&#xff0c;本身自己是属…

Unity与C#创建一个3D平台游戏 Learn to Create a 3D Platformer Game with Unity C#

游戏开发变得容易了。使用Unity学习C#并创建您自己的3D平台&#xff01; 你会学到什么 学习现代通用编程语言C#。 了解Unity中3D开发的功能 发展强大的可转移的解决问题的技能 了解游戏开发过程 了解面向对象编程在实践中是如何工作的 MP4 |视频:h264&#xff0c;1280720 |音…

struts2笔记01-环境搭建

1、官网下载struts2 struts-2.3.28-all.zip&#xff0c;这个包可谓应有尽有&#xff0c;以后全靠它了&#xff01; 2、jar包怎么选&#xff1f; (1)struts-2.3.28-all\struts-2.3.28\lib\*.jar,可以选这个目录下的所有jar包&#xff0c;不过是不是太多了&#xff1f;应该没有必…

php 生成动态键值 数组_你的PHP项目遇到性能问题了吗?看完这篇性能分析恍然大悟...

你的项目中遇到性能问题了吗&#xff1f;遇到性能问题你是如何解决的呢&#xff1f;你的解决方式是否正确呢&#xff1f;下面就跟大家一起分享php项目的性能问题。PHP语言级性能分析php在什么情况下会遇到性能问题呢&#xff1f;在讨论性能问题时&#xff0c;我们要明白&#x…

前来推荐一本比较喜欢的读物——《浪潮之巅》

基本属性 书籍介绍&#xff1a;《浪潮之巅》是一本介绍IT行业兴衰变化的书&#xff0c;书中的内容最早发表在Google黑板报上&#xff0c;经过几年的积累并整理成书。 作者介绍&#xff1a;吴军&#xff0c;美国约翰霍普金斯大学计算机科学博士&#xff0c;其人写作风格风趣幽默…