混合粒子群算法的实现

混合粒子群算法将全局粒子群算法与局部粒子群算法结合,其速度更新采用公式

 

其中G(k+1)是全局版本的速度更新公式,而L(k+1)是局部版本的速度更新公式,混合粒子群算法采用H(k+1)的公式。


位置更新公式

 

因为是局部版本与全局版本相结合,所以,粒子群的初始化函数应该与局部版本的相同,这里就不列出了,参看粒子群算法(7)中的LocalInitSwarm函数。

关键还是混合粒子群算法的单步更新函数,函数名为HybridStepPso

代码如下:

view plaincopy to clipboardprint?
01.function [ParSwarm,OptSwarm]=HybridStepPso(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)  
02.% 功能描述:混合粒子群算法。将全局版本与局部版本相混合。基本的粒子群算法的单步更新位置,速度的算法  
03.%  
04.%[ParSwarm,OptSwarm]=LocalStepPsoByCircle(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)  
05.%  
06.%算法思想:全局版本的速度更新公式:vq(k+1)=w*v(k)+c1*r1*(pg-w)+c2*r2*(pq-w)  
07.%pg为个体历史最优,pq为全局最优  
08.%局部版本的速度更新公式:vl(k+1)=w*v(k)+c1*r1*(pg-w)+c2*r2*(pl-w) pl为邻域最优  
09.%现在速度更新公式vh=n*vq+(1-n)*vl;n属于0到1的一个数  
10.% 输入参数:ParSwarm:粒子群矩阵,包含粒子的位置,速度与当前的目标函数值  
11.%输入参数:OptSwarm:包含粒子群个体最优解与全局最优解的矩阵  
12.%输入参数:ParticleScope:一个粒子在运算中各维的范围;  
13.% 输入参数:AdaptFunc:适应度函数  
14.%输入参数:LoopCount:迭代的总次数  
15.%输入参数:CurCount:当前迭代的次数  
16.%  
17.% 返回值:含意同输入的同名参数  
18.%  
19.%用法:[ParSwarm,OptSwarm]=LocalStepPsoByCircle(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)  
20.%  
21.% 异常:首先保证该文件在Matlab的搜索路径中,然后查看相关的提示信息。  
22.%  
23.%编制人:XXX  
24.%编制时间:2010.5.6  
25.%参考文献:XXX  
26.%参考文献:XXX  
27.%  
28.%修改记录  
29.%----------------------------------------------------------------  
30.%2010.5.6  
31.%修改人:XXX  
32.% 添加2*unifrnd(0,1).*SubTract1(row,:)中的unifrnd(0,1)随机数,使性能大为提高  
33.%修改混合因子,从小到大,开始从CurCount/LoopCount开始  
34.%修改C1=2.05,C2=2.05  
35.%修改速度的范围时区间每维范围的0.5(一半)  
36.%参照基于MATLAB的粒子群优化算法程序设计  
37.%  
38.% 总体评价:使用这个版本的调节系数,效果比较好  
39.%  
40. 
41.%容错控制  
42.if nargin~=8  
43.    error('输入的参数个数错误。')  
44.end  
45.if nargout~=2  
46.    error('输出的个数太少,不能保证循环迭代。')  
47.end  
48. 
49.%开始单步更新的操作  
50. 
51.%*********************************************  
52.%***** 更改下面的代码,可以更改惯性因子的变化*****  
53.%---------------------------------------------------------------------  
54.% 线形递减策略  
55.w=MaxW-CurCount*((MaxW-MinW)/LoopCount);  
56.%---------------------------------------------------------------------  
57.%w 固定不变策略  
58.%w=0.7;  
59.%---------------------------------------------------------------------  
60.% 参考文献:陈贵敏,贾建援,韩琪,粒子群优化算法的惯性权值递减策略研究,西安交通大学学报,2006,1  
61.%w 非线形递减,以凹函数递减  
62.%w=(MaxW-MinW)*(CurCount/LoopCount)^2+(MinW-MaxW)*(2*CurCount/LoopCount)+MaxW;  
63.%---------------------------------------------------------------------  
64.%w 非线形递减,以凹函数递减  
65.%w=MinW*(MaxW/MinW)^(1/(1+10*CurCount/LoopCount));  
66.%*****更改上面的代码,可以更改惯性因子的变化*****  
67.%*********************************************  
68.%更改下面代码可以改变混合因子的取值  
69.%-----------------------------------------------  
70.Hybrid=CurCount/LoopCount;  
71.%-----------------------------------------------  
72. 
73.% 得到粒子群群体大小以及一个粒子维数的信息  
74.[ParRow,ParCol]=size(ParSwarm);  
75. 
76.%得到粒子的维数  
77.ParCol=(ParCol-1)/2;  
78.GlobleSubTract1=OptSwarm(1:ParRow,:)-ParSwarm(:,1:ParCol);%粒子自身历史最优解位置减去粒子当前位置  
79.LocalSubTract1=OptSwarm(1:ParRow,:)-ParSwarm(:,1:ParCol);%粒子自身历史最优解位置减去粒子当前位置  
80.LocalSubTract2=OptSwarm(ParRow+1:end-1,:)-ParSwarm(:,1:ParCol);%粒子邻域最优解位置减去粒子当前位置  
81.%*********************************************  
82.%***** 更改下面的代码,可以更改c1,c2的变化*****  
83.c1=2.05;  
84.c2=2.05;  
85.%---------------------------------------------------------------------  
86.%con=1;  
87.%c1=4-exp(-con*abs(mean(ParSwarm(:,2*ParCol+1))-AdaptFunc(OptSwarm(ParRow+1,:))));  
88.%c2=4-c1;  
89.%----------------------------------------------------------------------  
90.%***** 更改上面的代码,可以更改c1,c2的变化*****  
91.%*********************************************  
92.for row=1:ParRow   
93.       GlobleSubTract2=OptSwarm(ParRow*2+1,:)-ParSwarm(row,1:ParCol);%全局最优的位置减去每个粒子当前的位置     
94.       LocalTempV=w.*ParSwarm(row,ParCol+1:2*ParCol)+c1*unifrnd(0,1).*LocalSubTract1(row,:)+c2*unifrnd(0,1).*LocalSubTract2(row,:);  
95.       GlobleTempV=w.*ParSwarm(row,ParCol+1:2*ParCol)+c1*unifrnd(0,1).*GlobleSubTract1(row,:)+c2*unifrnd(0,1).*GlobleSubTract2;  
96.       TempV=Hybrid.*GlobleTempV+(1-Hybrid).*LocalTempV;  
97.   %限制速度的代码  
98.   for h=1:ParCol  
99.       if TempV(:,h)>ParticleScope(h,2)/2.0  
100.           TempV(:,h)=ParticleScope(h,2)/2.0;  
101.       end  
102.       if TempV(:,h)<-ParticleScope(h,2)/2.0  
103.           TempV(:,h)=(-ParticleScope(h,2)+1e-10)/2.0;  
104.           %加1e-10防止适应度函数被零除  
105.       end  
106.   end    
107.     
108.   % 更新速度  
109.   ParSwarm(row,ParCol+1:2*ParCol)=TempV;  
110.     
111.   %*********************************************  
112.   %***** 更改下面的代码,可以更改约束因子的变化*****  
113.   %---------------------------------------------------------------------  
114.   %a=1;  
115.   %---------------------------------------------------------------------  
116.   a=0.729;  
117.   %***** 更改上面的代码,可以更改约束因子的变化*****  
118.   %*********************************************  
119.     
120.   % 限制位置的范围  
121.   TempPos=ParSwarm(row,1:ParCol)+a*TempV;  
122.   for h=1:ParCol  
123.       if TempPos(:,h)>ParticleScope(h,2)  
124.           TempPos(:,h)=ParticleScope(h,2);  
125.       end  
126.       if TempPos(:,h)<=ParticleScope(h,1)  
127.           TempPos(:,h)=ParticleScope(h,1)+1e-10;             
128.       end  
129.   end  
130. 
131.   %更新位置   
132.   ParSwarm(row,1:ParCol)=TempPos;  
133.     
134.   % 计算每个粒子的新的适应度值  
135.   ParSwarm(row,2*ParCol+1)=AdaptFunc(ParSwarm(row,1:ParCol));  
136.   if ParSwarm(row,2*ParCol+1)>AdaptFunc(OptSwarm(row,1:ParCol))  
137.       OptSwarm(row,1:ParCol)=ParSwarm(row,1:ParCol);  
138.   end  
139.end  
140.%for循环结束  
141.%确定邻域的范围  
142.linyurange=fix(ParRow/2);  
143.%确定当前迭代的邻域范围  
144.jiange=ceil(LoopCount/linyurange);  
145.linyu=ceil(CurCount/jiange);  
146.    for row=1:ParRow  
147.        if row-linyu>0&&row+linyu<=ParRow  
148.            tempM =[ParSwarm(row-linyu:row-1,:);ParSwarm(row+1:row+linyu,:)];  
149.              
150.            [maxValue,linyurow]=max(tempM(:,2*ParCol+1));  
151.            if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))  
152.                OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);  
153.            end  
154.        else 
155.            if row-linyu<=0  
156.                %该行上面的部分突出了边界,下面绝对不会突破边界  
157.                if row==1  
158.                    tempM=[ParSwarm(ParRow+row-linyu:end,:);ParSwarm(row+1:row+linyu,:)];  
159.                    [maxValue,linyurow]=max(tempM(:,2*ParCol+1));  
160.                     if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))  
161.                        OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);  
162.                     end  
163.                else 
164.                    tempM=[ParSwarm(1:row-1,:);ParSwarm(ParRow+row-linyu:end,:);ParSwarm(row+1:row+linyu,:)];  
165.                    [maxValue,linyurow]=max(tempM(:,2*ParCol+1));  
166.                     if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))  
167.                        OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);  
168.                     end  
169.                end  
170.            else 
171.                %该行下面的部分突出了边界,上面绝对不会突破边界  
172.                if row==ParRow  
173.                    tempM=[ParSwarm(ParRow-linyu:row-1,:);ParSwarm(1:linyu,:)];  
174.                    [maxValue,linyurow]=max(tempM(:,2*ParCol+1));  
175.                     if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))  
176.                        OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);  
177.                     end  
178.                else 
179.                    tempM=[ParSwarm(row-linyu:row-1,:);ParSwarm(row+1:end,:);ParSwarm(1:linyu-(ParRow-row),:)];    
180.                    [maxValue,linyurow]=max(tempM(:,2*ParCol+1));  
181.                     if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))  
182.                        OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);  
183.                     end  
184.                end  
185.            end  
186.        end  
187.    end%for 
188.    %寻找适应度函数值最大的解在矩阵中的位置(行数),进行全局最优的改变   
189.[maxValue,row]=max(ParSwarm(:,2*ParCol+1));  
190.if AdaptFunc(ParSwarm(row,1:ParCol))>AdaptFunc(OptSwarm(ParRow*2+1,:))  
191.    OptSwarm(ParRow*2+1,:)=ParSwarm(row,1:ParCol);  
192.end  
193.   
function [ParSwarm,OptSwarm]=HybridStepPso(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)
% 功能描述:混合粒子群算法。将全局版本与局部版本相混合。基本的粒子群算法的单步更新位置,速度的算法
%
%[ParSwarm,OptSwarm]=LocalStepPsoByCircle(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)
%
%算法思想:全局版本的速度更新公式:vq(k+1)=w*v(k)+c1*r1*(pg-w)+c2*r2*(pq-w)
%pg为个体历史最优,pq为全局最优
%局部版本的速度更新公式:vl(k+1)=w*v(k)+c1*r1*(pg-w)+c2*r2*(pl-w) pl为邻域最优
%现在速度更新公式vh=n*vq+(1-n)*vl;n属于0到1的一个数
% 输入参数:ParSwarm:粒子群矩阵,包含粒子的位置,速度与当前的目标函数值
%输入参数:OptSwarm:包含粒子群个体最优解与全局最优解的矩阵
%输入参数:ParticleScope:一个粒子在运算中各维的范围;
% 输入参数:AdaptFunc:适应度函数
%输入参数:LoopCount:迭代的总次数
%输入参数:CurCount:当前迭代的次数
%
% 返回值:含意同输入的同名参数
%
%用法:[ParSwarm,OptSwarm]=LocalStepPsoByCircle(ParSwarm,OptSwarm,AdaptFunc,ParticleScope,MaxW,MinW,LoopCount,CurCount)
%
% 异常:首先保证该文件在Matlab的搜索路径中,然后查看相关的提示信息。
%
%编制人:XXX
%编制时间:2010.5.6
%参考文献:XXX
%参考文献:XXX
%
%修改记录
%----------------------------------------------------------------
%2010.5.6
%修改人:XXX
% 添加2*unifrnd(0,1).*SubTract1(row,:)中的unifrnd(0,1)随机数,使性能大为提高
%修改混合因子,从小到大,开始从CurCount/LoopCount开始
%修改C1=2.05,C2=2.05
%修改速度的范围时区间每维范围的0.5(一半)
%参照基于MATLAB的粒子群优化算法程序设计
%
% 总体评价:使用这个版本的调节系数,效果比较好
%

%容错控制
if nargin~=8
    error('输入的参数个数错误。')
end
if nargout~=2
    error('输出的个数太少,不能保证循环迭代。')
end

%开始单步更新的操作

%*********************************************
%***** 更改下面的代码,可以更改惯性因子的变化*****
%---------------------------------------------------------------------
% 线形递减策略
w=MaxW-CurCount*((MaxW-MinW)/LoopCount);
%---------------------------------------------------------------------
%w 固定不变策略
%w=0.7;
%---------------------------------------------------------------------
% 参考文献:陈贵敏,贾建援,韩琪,粒子群优化算法的惯性权值递减策略研究,西安交通大学学报,2006,1
%w 非线形递减,以凹函数递减
%w=(MaxW-MinW)*(CurCount/LoopCount)^2+(MinW-MaxW)*(2*CurCount/LoopCount)+MaxW;
%---------------------------------------------------------------------
%w 非线形递减,以凹函数递减
%w=MinW*(MaxW/MinW)^(1/(1+10*CurCount/LoopCount));
%*****更改上面的代码,可以更改惯性因子的变化*****
%*********************************************
%更改下面代码可以改变混合因子的取值
%-----------------------------------------------
Hybrid=CurCount/LoopCount;
%-----------------------------------------------

% 得到粒子群群体大小以及一个粒子维数的信息
[ParRow,ParCol]=size(ParSwarm);

%得到粒子的维数
ParCol=(ParCol-1)/2;
GlobleSubTract1=OptSwarm(1:ParRow,:)-ParSwarm(:,1:ParCol);%粒子自身历史最优解位置减去粒子当前位置
LocalSubTract1=OptSwarm(1:ParRow,:)-ParSwarm(:,1:ParCol);%粒子自身历史最优解位置减去粒子当前位置
LocalSubTract2=OptSwarm(ParRow+1:end-1,:)-ParSwarm(:,1:ParCol);%粒子邻域最优解位置减去粒子当前位置
%*********************************************
%***** 更改下面的代码,可以更改c1,c2的变化*****
c1=2.05;
c2=2.05;
%---------------------------------------------------------------------
%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
       GlobleSubTract2=OptSwarm(ParRow*2+1,:)-ParSwarm(row,1:ParCol);%全局最优的位置减去每个粒子当前的位置  
       LocalTempV=w.*ParSwarm(row,ParCol+1:2*ParCol)+c1*unifrnd(0,1).*LocalSubTract1(row,:)+c2*unifrnd(0,1).*LocalSubTract2(row,:);
       GlobleTempV=w.*ParSwarm(row,ParCol+1:2*ParCol)+c1*unifrnd(0,1).*GlobleSubTract1(row,:)+c2*unifrnd(0,1).*GlobleSubTract2;
       TempV=Hybrid.*GlobleTempV+(1-Hybrid).*LocalTempV;
   %限制速度的代码
   for h=1:ParCol
       if TempV(:,h)>ParticleScope(h,2)/2.0
           TempV(:,h)=ParticleScope(h,2)/2.0;
       end
       if TempV(:,h)<-ParticleScope(h,2)/2.0
           TempV(:,h)=(-ParticleScope(h,2)+1e-10)/2.0;
           %加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循环结束
%确定邻域的范围
linyurange=fix(ParRow/2);
%确定当前迭代的邻域范围
jiange=ceil(LoopCount/linyurange);
linyu=ceil(CurCount/jiange);
    for row=1:ParRow
        if row-linyu>0&&row+linyu<=ParRow
            tempM =[ParSwarm(row-linyu:row-1,:);ParSwarm(row+1:row+linyu,:)];
           
            [maxValue,linyurow]=max(tempM(:,2*ParCol+1));
            if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))
                OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);
            end
        else
            if row-linyu<=0
                %该行上面的部分突出了边界,下面绝对不会突破边界
                if row==1
                    tempM=[ParSwarm(ParRow+row-linyu:end,:);ParSwarm(row+1:row+linyu,:)];
                    [maxValue,linyurow]=max(tempM(:,2*ParCol+1));
                     if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))
                        OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);
                     end
                else
                    tempM=[ParSwarm(1:row-1,:);ParSwarm(ParRow+row-linyu:end,:);ParSwarm(row+1:row+linyu,:)];
                    [maxValue,linyurow]=max(tempM(:,2*ParCol+1));
                     if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))
                        OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);
                     end
                end
            else
                %该行下面的部分突出了边界,上面绝对不会突破边界
                if row==ParRow
                    tempM=[ParSwarm(ParRow-linyu:row-1,:);ParSwarm(1:linyu,:)];
                    [maxValue,linyurow]=max(tempM(:,2*ParCol+1));
                     if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))
                        OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);
                     end
                else
                    tempM=[ParSwarm(row-linyu:row-1,:);ParSwarm(row+1:end,:);ParSwarm(1:linyu-(ParRow-row),:)]; 
                    [maxValue,linyurow]=max(tempM(:,2*ParCol+1));
                     if maxValue>AdaptFunc(OptSwarm(ParRow+row,:))
                        OptSwarm(ParRow+row,:)=tempM(linyurow,1:ParCol);
                     end
                end
            end
        end
    end%for
    %寻找适应度函数值最大的解在矩阵中的位置(行数),进行全局最优的改变
[maxValue,row]=max(ParSwarm(:,2*ParCol+1));
if AdaptFunc(ParSwarm(row,1:ParCol))>AdaptFunc(OptSwarm(ParRow*2+1,:))
    OptSwarm(ParRow*2+1,:)=ParSwarm(row,1:ParCol);
end
 


 

 

注意代码的91行到96行,这几行就是混合粒子群速度更新公式,其他部分基本与前面的实现一样。

最后还是一个把这两个函数组装在一起的函数,同样采用LocalPsoProcessByCircle函数,详细见粒子群算法(7)的内容,最后还是给出一个应用实例。

view plaincopy to clipboardprint?
01.Scope=[-10 10;-10 10;-10 10;-10 10;-10 10;-10 10;-10 10;-10 10;-10 10;-10 10];//粒子每维的限制范围  
02.qun=20;//粒子群的规模  
03.lizi=10;//每个粒子的维数  
04.[Result,OnLine,OffLine,MinMaxMeanAdapt,BestofStep]=LocalPsoProcessByCircle(qun,lizi,Scope,@localinitswarm,@Hybridsteppso,@Rastrigin,0,0,1000,0); 
Scope=[-10 10;-10 10;-10 10;-10 10;-10 10;-10 10;-10 10;-10 10;-10 10;-10 10];//粒子每维的限制范围
qun=20;//粒子群的规模
lizi=10;//每个粒子的维数
[Result,OnLine,OffLine,MinMaxMeanAdapt,BestofStep]=LocalPsoProcessByCircle(qun,lizi,Scope,@localinitswarm,@Hybridsteppso,@Rastrigin,0,0,1000,0);


注意:在这个LocalPsoProcessByCircle函数中,使用HybridStepPso作为单步更新的函数,其余基本与局部粒子群算法相同。

经过本人的实际测试,运行条件相同,最好的是局部版本的PSO,混合的PSO并不像有些文献上说的那么好,也许是我实现的不对,如果有那个大侠实现的效果更好,可以给我联系,我们可以共享代码。

同时也希望那些砖家、叫兽们共享你们的效果非常好的代码。

本人已经实现了一个PSO的工具箱,不过效果不好,本人水平低劣,又需要的可以联系我。

 

不知道CSDN能不能做链接下载,如果可以,请告诉我,我做个链接,大家可以随便下载,共同交流


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/niuyongjie/archive/2010/05/17/5602104.aspx

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值