% 烟花烟花满天飞
% 2011.6.25
OldHandle = findobj('Type','figure','Tag','FireWork')
if ishandle(OldHandle)
close(OldHandle)
end
% 图形窗口初始化
fig = figure('units','normalized','position',[0.1 0.1 0.8 0.8],...
'menubar','none','name','烟花满天飞',...
'numbertitle','off','color',[0 0 0],'tag','FireWork')
% 烟花炸开前的初始位置
h0 = line(0,0,0,'marker','.',...
'markersize',18,...
'MarkerEdgeColor',[1 1 1],...
'MarkerFaceColor',[1 1 1],...
'EraseMode','xor',...
'color',[0 0 0])
% 设置坐标系显示属性
axis equal
axis([-50 50 -50 50 0 100])
axis off
view(-42,22)
% 设置参数
rate = 1:-0.01:0
% 颜色衰减率
v0 = 45 % 烟花头初始速度
g = -9.8 % 重力加速度
usedtime = -v0/g % 烟花头爆炸前所经历时间
zs = v0*usedtime+0.5*g*usedtime^2 %烟花头爆炸前达到的最高高度
theta = rand(250,1)*2*pi % 各粒子速度的方位角
phi = rand(250,1)*2*pi-pi % 各粒子速度的仰角
age = 20 % 粒子生存期
% 常用颜色矩阵
colormat = [1.0 0.5 0.5
1.0 0.75 0.5
1.0 1.0 0.5
0.75 1.0 0.5
0.5 1.0 0.5
0.5 1.0 0.75
0.5 1.0 1.0
0.5 0.75 1.0
0.5 0.5 1.0
0.75 0.5 1.0
1.0 0.5 1.0
1.0 0.5 0.75]
% 随机产生各粒子对应的颜色序号
colorid = randsample(12,250,true)
% 粒子对应的颜色矩阵
colormat = colormat(colorid,:)
% 粒子颜色与背景色(夜色)的距离
colordist = sqrt(sum(colormat.^2,2))
v1 = 20 % 粒子的初始速度
k = 1 % 颜色衰减率初始序号
timerA = timer('TimerFcn',@TimerFcnA,...
'executionmode','fixedspacing','Period',0.001)
start(timerA)
h = getappdata(gcf,'HandleParticle')
timerB = timer('TimerFcn',{@TimerFcnB},...
'executionmode','fixedspacing','period',0.001)
%--------------------------------------------------------------------------
% 定时器回调函数(烟花头)
%--------------------------------------------------------------------------
function TimerFcnA(timerA,event)
ta = get(timerA,'TasksExecuted')*0.1
if ta <= usedtime
z = v0*ta+0.5*g*ta^2
set(h0,'zdata',z,...
'MarkerEdgeColor',[1 1 1],...
'MarkerFaceColor',[1 1 1])
drawnow
%pause(0.01)
else
delete(h0)
stop(timerA)
x0 = zeros(2,250)
y0 = zeros(2,250)
z0 = zs*ones(2,250)
h = line(x0,y0,z0,'marker','h',...
'markersize',12,...
'MarkerEdgeColor',[1 1 1],...
'MarkerFaceColor',[1 1 1],...
'EraseMode' , 'xor',...
'color',[0 0 0])
setappdata(gcf,'HandleParticle',h)
start(timerB)
end
end
(以下描述,均不是学术用语,仅供大家快乐的阅读)
烟花算法(Firework Algorithm,FWA)是一种受烟花爆炸产生火星,并继续分裂爆炸这一过程启发而得出的算法。算法的思想简单,但具体实现复杂。算法提出时间并不长,但是已经有了不少的改进研究和较为全面的应用。
烟花算法中,每一个烟花的位置都代表了一个可行解。烟花的爆炸产生的火星有两种,正常的火星与特别的火星。每个火星都会爆炸产生数个正常火星,某些火星有一定的概率产生一个特别的火星。正常的火星根据当前火星的振幅随机均匀分布在该火星的周围,而特别的火星将在当前火星附近以正态分布方式产生。每次迭代产生的火星数量多于每一代应有的火星数,算法将参照火星位置的优劣,随机留下指定数量的火星,已保持火星数目的稳定。
烟花算法的主角毫无疑问就是烟花了。
式(1)为适应度值越小越优的情况,而式(2)则是适应度值越大越优的情况。 为一个极小的值,以保证分母不为0。
每个火星产生的正常火星数量也由其适应度值来决定。
其中 表示第i个火星将要产生的正常火星数, 是产生正常火星的总数为一个常数,从式(3),(4)可以看出适应度值越好的火星能够产生更多的正常火星,反之,火星适应度越差,能够产生的火星数越少。
由于式(3),(4)计算出的值为小数,烟花算法中使用式(5)将其转化为整数。
从式(3)和式(4)中可以看出,在每一代中将会产生出 个正常火星。产生的正常火星的位置与当前火星的振幅有关,可以从式(1),(2)看出,适应度越优的火星的振幅越小,那么它产生的正常火星将在它自己周围,而适应度越差的火星的振幅越大,它产生的正常火星将会出现在离自己较远的位置。
当前火星每次爆炸会从D维搜索空间内随机选择z维进行更新从而产生新的火星。正常火星的位置由如下公式产生。
其中z为取值1-D的均匀随机正整数,rand(-1,1)表示-1到1内的均匀随机数。从式(6)中可以看出,正常火星的位置与其振幅有直接关系,振幅越大产生的新火星距当前火星的距离约远。
每次迭代过程中,会产生m个特别的火星,即在这N个火星中随机选择m个火星,每个火星产生一个特别的火星。特别的火星的由下面的公式产生:
由上面的过程可知,在每一代中,有N个火星,将会产生出 个正常火星以及m个特别的火星。但是每一代中只能从这 个火星中选择N个火星保留至下一代。
每次会先从 个火星中选择最优的火星保留至下一代,然后再从中选择N-1个火星。选择某个火星的概率如下:
其中R(X)表示该火星距其他所有火星的距离之和,即距其它火星越远的火星,被选择保留至下一代的概率较大。
个火星,而且
,所有烟花算法每次迭代的计算复杂度要大于其他算法,这简直就是一个作弊行为。别的算法每次只搜索了N个位置,而烟花算法却搜索了 个位置。与其他优化算法对比时,其他算法的种群数量应该取 ,否则这将是一场不公正的对决。
适应度函数还是这个简单的小白鼠
实验一 :标准烟花算法
以上数据来自原论文,现在看一看实验的图像以及实验结果。
从图像可以看出每次只选择保留了5个火星,它们的收敛速度很慢,实验结束时距离目标点还有一段距离。
看看实验结果
从实验结果可以看出,算法的性能很不稳定,而造成这一点的原因很可能是其收敛速度较慢,算法仍在收敛过程中,所以结果看上去很差。将最大迭代次数修改为100代,重新试验,其结果如下:
结果好了一些但还是难以接受,为什么烟花算法的结果不理想呢?
原因可能是保留机制(2.3节)的问题,烟花算法中保留火星的概率是根据该火星与其他火星的距离和,距离群体越大的个体被保留下的概率越大。这样做有什么好处呢?好处是火星相对分散,这是一个对抗局部最优的策略,但是,距离群体较远的个体是一个较差的个体的概率非常大,坏处就是,集中于当前最优位置的火星被保留的概率较小,算法的局部搜索能力将较弱。
实验二 . 随机选择的方式保留火星
为了加快烟花算法的收敛速度,增强局部搜索能力,我移除了标准烟花算法的选择过程,使用随机选择的方式保留火星,当然,最优个体依然会被保留至下一代。其他参数保持不变。
可以看出这次的图像相比实验一收敛速度快了不少,在迭代结束时已经相对在一个较小的区域。这次的结果也明显优于实验一。将选择过程改为随机选择后,由于较优的火星产生的较多且分布在自己周围,因此选择到这些较优的火星的概率也相对较大,算法的收敛速度相对较快。与此同时,算法跳出局部最优的能力比修改前要弱。
对于较简单的问题来说当然是随机选择收敛较快结果较好,而复杂的问题则需要更强的跳出局部最优能力。问题的关键仍然是,我们无法在一开始就知道问题的复杂程度。
实验三 .增加火星的种群数量,减少每代产生的正常火星总数
为什么要减少产生的正常火星数,这样算法搜索的次数减少了,效果不会更差吗?其实与直觉相反,减少正常火星总数,增加火星总群数,实际上是让较优的火星产生的正常火星被保留下来的概率变大了,这样也可以解决实验一中的问题,加快算法的收敛速度。
从图像中可以看出,算法在50代之前已经收敛,但是之后只在小范围内进行搜索。实验图像与之前的描述相符,收敛速度加快但是跳出局部最优能力减弱。看看实验结果,实验结果好了不少且结果更加稳定。
其实实验二与实验三,使用了不同的策略,但都达到了同样的目的——保留更多的优质火星到下一代,它们促进了局部搜索但是挤占了较劣火星的位置,削弱了种群的多样性。
每代留下的火星多了,图像看上去是不是更像烟花?
烟花算法的探究远不止如此,几年前作为一个较新的算法来学习时却已经有了大量的论文和书籍,可见大家对烟花算法已经有了较为深入的研究,而我能做的只是应用算法解决问题以及稍作改进让算法与问题的适应性更高。
烟花算法产生正常火星的过程为算法提供了搜索能力,产生特殊火星的过程和选择过程为算法提供了跳出局部最优的能力。但是个人认为选择过程与其他过程的适应性不是很好。标准的选择过程会丢失掉许多较优的个体,使之前产生的正常火星得到的成果没有保留。
烟花算法其实还有比较多的改进点,对算法产生最大的参数应该就是正常火星的总数以及振幅了。简单粗暴的改进:在每一代可以对这两个参数进行变化或者随机化,让算法的搜索能力与跳出局部最优能力在整个流程中动态变化,以均衡两种能力。
以下指标纯属个人yy,仅供参考
参考文献
Tan Y , Zhu Y . Fireworks Algorithm for Optimization[C]// Advances in Swarm Intelligence, First International Conference, ICSI 2010, Beijing, China, June 12-15, 2010, Proceedings, Part I. Springer-Verlag, 2010. 提取码:yaj0
目录
上一篇 优化算法笔记(十一)群搜索算法
下一篇 优化算法笔记(十三)鲸鱼算法
优化算法matlab实现(十二)烟花算法matlab实现
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)