群智能算法(遗传算法, 粒子群算法, 蚁群算法原理与实例分析)

解决函数极值问题(二元), 采用三种群智能算法实现, 并进行比较分析

1. 问题重述

求解函数: f ( x , y ) = 6.452 ( x + 0.125 y ) ( cos ⁡ x − cos ⁡ ( 2 y ) ) 2 0.8 + ( x − 4.2 ) 2 + 2 ( y − 7 ) 2 + 3.226 y f(x, y)=\frac{6.452(x+0.125 y)(\cos x-\cos (2 y))^{2}}{\sqrt{0.8+(x-4.2)^{2}+2(y-7)^{2}}}+3.226 y f(x,y)=0.8+(x4.2)2+2(y7)2 6.452(x+0.125y)(cosxcos(2y))2+3.226y的最大值, 其中 x ∈ [ 0 , 10 ) , y ∈ [ 0 , 10 ) x \in[0,10), \quad y \in[0,10) x[0,10),y[0,10)

1.1 解决步骤

  • 利用现成函数绘制图形并求解出在给定区间的最大值
  • 选用群智能算法(遗传算法, 粒子群算法, 蚁群算法), 初步设定参数, 分析结果
  • 改变参数分析算法的性能
  • 总结

1.2 问题粗析

利用Matlab绘制函数图形,及使用函数计算最大值如下, 可得函数在该区间的最大值在99.99附近.
函数图形
代码如下:

% 代码1 粗略绘制函数图形并求最值
clc
clear
clf
x = linspace(0,10,1000);
y = linspace(0,10,1000);
[X,Y] = meshgrid(x,y);
Z = 6.452*(X+0.125.*Y).*((cos(X)-cos(2.*Y)).^2)./sqrt(0.8+(X-4.2).^2+2.*(Y-7).^2)+3.226.*Y;
mesh(X,Y,Z)
hold on

2. 遗传算法求解

2.1 步骤

  • 实数编码
  • 群体设定
  • 适应度函数
  • 选择(复制)
  • 交叉
  • 变异

2.2 结果

利用Matlab的GA函数, 首先用默认参数进行试验, 发现易陷入局部最优解(如下图)在这里插入图片描述
代码如下:

% 代码2 遗传算法
fun = @(x) 1/(6.452*(x(1)+0.125.*x(2)).*((cos(x(1))-cos(2.*x(2))).^2)./sqrt(0.8+(x(1)-4.2).^2+2.*(x(2)-7).^2)+3.226.*x(2));
nvars = 2;
A = [1, 0; 0, 1; -1, 0; 0, -1];                             % Ax不大于b
b = [10; 10; 0; 0];
lb = [];
ub = [];
nonlcon = [];
IntCon  = [];
options = optimoptions(@ga)
[x,fval,exitFlag,output,population,scores] = ga(fun,nvars,A,b,[],[],lb,ub,nonlcon,IntCon,options)

通过optimoptions函数对GA算法的options参数进行修改, 测试结果发现, 在种群规模不太小(>20), 将交配概率与变异概率分别设置为0.8和0.2, 容易找到最优解.
此时, 最优解的坐标为(6.0914, 7.7991, 99.9953).
在这里插入图片描述
代码如下:

fun = @(x) 1/(6.452*(x(1)+0.125.*x(2)).*((cos(x(1))-cos(2.*x(2))).^2)./sqrt(0.8+(x(1)-4.2).^2+2.*(x(2)-7).^2)+3.226.*x(2));
nvars = 2;
A = [1, 0; 0, 1; -1, 0; 0, -1];                             % Ax不大于b
b = [10; 10; 0; 0];
lb = [];
ub = [];
nonlcon = [];
IntCon  = [];

options = optimoptions(@ga, ...
                     'PopulationType', 'doubleVector',...
                     'PopulationSize', 50,...               % 种群规模
                     'EliteCount', 1,...                    % 最佳个体保存
                     'CrossoverFraction', 0.8, ...          % 交配概率
                     'MigrationDirection', 'forward',...
                     'MigrationInterval', 20,...
                     'MigrationFraction', 0.2,...           % 变异概率
                     'Generations', 100,...                 % 迭代次数
                     'TimeLimit', Inf,...
                     'FitnessLimit', -Inf,...
                     'StallTest', 'averageChange',...
                     'StallTimeLimit', Inf,...
                     'TolFun',1.0e-06,...
                     'Tolcon',1.0e-03,...
                     'NonlinConAlgorithm','auglag',...
                     'InitialPenalty', 10,...
                     'PenaltyFactor', 100,...
                     'PlotInterval', 1,...
                     'MutationFcn', {@mutationadaptfeasible [1] [1]},...    % 修改
                     'CreationFcn', @gacreationlinearfeasible,...           % 修改
                     'FitnessScalingFcn', @fitscalingrank,...
                     'SelectionFcn', @selectionstochunif,...
                     'CrossoverFcn', @crossoverintermediate,...             % 修改
                     'Display', 'final',...
                     'Vectorized', 'off')
[x,fval,exitFlag,output,population,scores] = ga(fun,nvars,A,b,[],[],lb,ub,nonlcon,IntCon,options)

2.3 结果分析

结果收敛较好, 种群中绝大多数个体较为集中.population
代码如下:

clc
clf
figure(2)
plot(population(:,1),population(:,2),'*r')
xlim([6.05 6.10])
ylim([7.79 7.81])

2.4 遗传算法小结

  1. 在代码调试的过程中, 先是用默认参数进行试验, 发现如不设置参数, 能得出正确结果, 但是在使用optimoptions函数获取options参数后, 再赋值成一模一样的参数, 则得不到理想结果, 容易陷入局部最优解.
    问题解决: 通过手动赋值所有参数, 采取控制变量法,每次修改其中一个参数, 最终对 ′ M u t a t i o n F c n ′ , ′ C r e a t i o n F c n ′ , ′ C r o s s o v e r F c n ′ 'MutationFcn', 'CreationFcn', 'CrossoverFcn' MutationFcn,CreationFcn,CrossoverFcn三个参数进行默认值的修改(依据警告以及 d o c u m e n t a t i o n documentation documentation), 最终确定当
    ′ M u t a t i o n F c n ′ = @ m u t a t i o n a d a p t f e a s i b l e [ 1 ] [ 1 ] 'MutationFcn'={@mutationadaptfeasible [1] [1]} MutationFcn=@mutationadaptfeasible[1][1],
    ′ C r e a t i o n F c n ′ = @ g a c r e a t i o n l i n e a r f e a s i b l e 'CreationFcn'=@gacreationlinearfeasible CreationFcn=@gacreationlinearfeasible,
    ′ C r o s s o v e r F c n ′ = @ c r o s s o v e r i n t e r m e d i a t e 'CrossoverFcn'=@crossoverintermediate CrossoverFcn=@crossoverintermediate
    时, 算法得到正确结果.
  2. 解决问题1后, 对种群规模, 交配概率, 变异概率等参数进行修改, 结果显示, 在在种群规模不太小(>20), 将交配概率与变异概率分别设置为0.8和0.2, 容易找到最优解.
  3. 在使用遗传算法对二元函数进行最值求解时, 没有选用根据步骤逐行书写代码, 而是使用Matlab自带的GA函数, 通过optimoptions对参数进行准确配置, 进而得到结果.
  4. 逐行书写代码有利于加深算法的数学理解, 原理的实现. 但在工程性方面, 自行书写代码性能不如算法工程师所写的GA函数, 因此, 在充分理解原理的基础上, 直接调用函数(或使用APP), 不仅有利于之后的再次使用, 而且对于各种参数的配置有了一定经验, 对于使用遗传算法解决其他类型问题有一定帮助.

3. 粒子群算法求解

3.1 步骤

  • 下载工具箱, 并在Matlab中设置工具箱的路径;
  • 定义待优化函数 t e s t f u n c test_func testfunc;
  • 调用PSO算法的核心函数: p s o _ T r e l e a _ v e c t o r i z e d ( ) pso\_Trelea\_vectorized() pso_Trelea_vectorized().

3.2 结果

通过下载安装 P S O t PSOt PSOt工具箱, 对 t e s t _ f u n c . m test\_func.m test_func.m t e s t _ m a i n . m test\_main.m test_main.m文件进行编写, 设置初始参数后, 结果如下图所示.在这里插入图片描述

由图可知, 在迭代了大约700次后, PSO算法得出最大值点坐标(6.0914, 7.7991, 99.9953), 与遗传算法获得结果一致.
代码如下:

% test_func函数
function z=test_func(in)
nn=size(in);
x=in(:,1);
y=in(:,2);
nx=nn(1);
   for i=1:nx
       temp = 1/(6.452*(x(i)+0.125.*y(i)).*((cos(x(i))-cos(2.*y(i))).^2)./sqrt(0.8+(x(i)-4.2).^2+2.*(y(i)-7).^2)+3.226.*y(i));
       z(i,:) = temp;
   end
% test_main.m文件
clear
clc
x_range=[0,10];     %参数x变化范围
y_range=[0,10];     %参数y变化范围
range = [x_range;y_range];     %参数变化范围(组成矩阵)
Max_V = 0.2*(range(:,2)-range(:,1));  %最大速度取变化范围的10%~20%
n=2;                     %待优化函数的维数,此例子中仅x、y两个自变量,故为2
pso_Trelea_vectorized('test_func',n,Max_V,range)  %调用PSO核心模块

3.3 结果分析

PSO算法中, 调用 p s o _ T r e l e a _ v e c t o r i z e d ( ) pso\_Trelea\_vectorized() pso_Trelea_vectorized()函数的 P S O p a r a m s PSOparams PSOparams参数含义如下表所示(自己查资料总结):

参数含义
P(1)命令窗显示的间隔数, 默认为100, 0则不显示中间过程
P(2)最大迭代次数, 如算法不收敛, 自动停止, 默认为2000
P(3)初始粒子数, 越多则越有可能收敛到全局最优值, 默认为24
P(4)加速度参数, 影响局部最优值, 默认为2
P(5)加速度参数, 影响全局最优值, 默认为2
P(6)初始时刻加权值, 默认0.9
P(7)收敛时刻加权值, 默认0.4
P(8)当迭代次数超过此值时, 加权取其最小, 默认为1500
P(9)终止算法的阈值, 连续两次迭代中对于的种群最优值小于此阈值时,算法停止, 默认为1e-25
P(10)终止算法的阈值, 连续n次迭代函数的梯度没有变化,则算法停止
P(11)说明优化的情况, NaN表示非约束下的优化问题
P(12)0则表示通常的PSO算法
P(13)0表示随机产生种子, 1表示用户自行产生种子

3.4 小结

  1. 在调用 p s o _ T r e l e a _ v e c t o r i z e d ( ) pso\_Trelea\_vectorized() pso_Trelea_vectorized()函数过程中, 出现 f o r c e r o w forcerow forcerow函数无法识别的问题, 通过查看PSOt文件夹, 发现在子文件夹路径下存在 f o r c e r o w . m forcerow.m forcerow.m文件, 将PSOt及其子文件夹全部添加到搜索路径后, 问题解决.
  2. 在使用粒子群算法对二元函数进行最值求解时, 通过网络下载PSOt工具箱, 编写 t e s t _ f u n c . m 函数 test\_func.m函数 test_func.m函数,设置参数 x , y x,y x,y的变化范围,最大速度的取值,待优化函数的维数等参数, 进行调用, 得到结果.逐行书写代码有利于加深算法的数学理解, 原理的实现. 但在工程性方面, 自行书写代码性能不如算法工程师所写的 P s o _ P r e l e a _ v e c t o r i z e d Pso\_Prelea\_vectorized Pso_Prelea_vectorized函数, 因此, 在充分理解原理的基础上, 直接调用函数(或使用APP), 不仅有利于之后的再次使用, 而且对于各种参数的配置有了一定经验, 对于使用粒子群算法解决其他类型问题有一定帮助.
  3. 粒子群算法适合解决二元函数最优值问题, 仅需要调整少数几个参数即可实现函数的优化.
本框架提供了有关粒子群算法(PSO)遗传算法(GA)的完整实现,以及一套关于改进、应用、测试、结果输出的完整框架。 本框架对粒子群算法遗传算法进行逻辑解耦,对其中的改进点予以封装,进行模块化,使用者可以采取自己对该模块的改进替换默认实现组成新的改进算法已有算法进行对比试验。试验结果基于Excel文件输出,并可通过设定不同的迭代结束方式选择试验数据的输出方式,包括: 1. 输出随迭代次数变化的平均达优率数据(设定终止条件区间大于0)。 2. 输出随迭代次数变化的平均最优值数据(设定终止条件区间等于0)。 本框架了包含了常用基准函数的实现以及遗传算法粒子群算法对其的求解方案实现和对比,如TSP,01背包,Banana函数,Griewank函数等。并提供大量工具方法,如KMeans,随机序列生成无效序列修补方法等等。 对遗传算法的二进制编码,整数编码,实数编码,整数序列编码(用于求解TSP等),粒子群算法的各种拓扑结构,以及两种算法的参数各种更新方式均有实现,并提供接口供使用者实现新的改进方式并整合入框架进行试验。 其中还包括对PSO进行离散化的支持接口,和自己的设计一种离散PSO方法及其用以求解01背包问题的实现样例。 欢迎参考并提出宝贵意见,特别欢迎愿意协同更新修补代码的朋友(邮箱starffly@foxmail.com)。 代码已作为lakeast项目托管在Google Code: http://code.google.com/p/lakeast http://code.google.com/p/lakeast/downloads/list 某些类的功能说明: org.lakest.common中: BoundaryType定义了一个枚举,表示变量超出约束范围时为恢复到约束范围所采用的处理方式,分别是NONE(不处理),WRAP(加减若干整数个区间长度),BOUNCE(超出部分向区间内部折叠),STICK(取超出方向的最大限定值)。 Constraint定义了一个代表变量约束范围的类。 Functions定义了一系列基准函数的具体实现以供其他类统一调用。 InitializeException定义了一个代表程序初始化出现错误的异常类。 Randoms类的各个静态方法用以产生各种类型的随机数以及随机序列的快速产生。 Range类的实现了用以判断变量是否超出约束范围以及将超出约束范围的变量根据一定原则修补到约束范围的方法。 ToStringBuffer是一个将数组转换为其字符串表示的类。 org.lakeast.ga.skeleton中: AbstractChromosome定义了染色体的公共方法。 AbstractDomain是定义问题域有关的计算参数的抽象类。 AbstractFactorGenerator定义产生交叉概率和变异概率的共同方法。 BinaryChromosome是采用二进制编码的染色体的具体实现类。 ConstantFactorGenerator是一个把交叉概率和变异概率定义为常量的参数产生器。 ConstraintSet用于在计算过程中保存和获取应用问题的各个维度的约束。 Domain是遗传算法求解中所有问题域必须实现的接口。 EncodingType是一个表明染色体编码类型的枚举,包括BINARY(二进制),REAL(实数),INTEGER(整型)。 Factor是交叉概率和变异概率的封装。 IFactorGenerator参数产生器的公共接口。 Population定义了染色体种群的行为,包括种群的迭代,轮盘赌选择和交叉以及最优个体的保存。 org.lakeast.ga.chromosome中: BinaryChromosome二进制编码染色体实现。 IntegerChromosome整数编码染色体实现。 RealChromosome实数编码染色体实现。 SequenceIntegerChromosome整数序列染色体实现。 org.lakeast.pso.skeleton中: AbstractDomain提供一个接口,将粒子的位置向量解释到离散空间,同时不干扰粒子的更新方式。 AbstractFactorGenerator是PSO中参数产生器的公共抽象类。 AbstractParticle定义了PSO种群中粒子的基本行为,最主要是实现了如何根据现有位置计算得到下一代粒子的位置的合法值。 ConstraintSet用于在粒子迭代过程中保存和获取应用问题的各个维度的约束。 AbstractSwarm.java各种拓扑结构的PSO种群的抽象父类,主要实现了种群迭代过程中计算流程的定义以及中间数据被如何输出到测试工具类。 Domain是PSO算法求解中所有问题域必须实现的接口。 DynamicFatorGenerator若种群在迭代过程中,w,c1,c2随迭代次数发生变化,那么它们的产生器需要继承这个抽象类。 Factor封装了w,c1,c2三个参数的字面值。 Location用于保存和获取迭代中粒子的位置和速度向量的数值。 NeighborhoodBestParticle定义了采用邻域版本的PSO算法的具体实现。主要是实现了如何根据邻域版本的PSO算法计算下一迭代中的粒子速度。 RingTopoSwarm定义环拓扑结构的具体实现,主要是定义了如何获取粒子的邻域粒子的方法。 StaticTopoSwarm静态拓扑结构的PSO算法的抽象父类。 org.lakeast.pso.swarm中包含粒子群拓扑结构的各种实现,基本见名知意。 对各种问题的求解样例位于org.lakeast.main包中,以...TaskTest结尾,基本见名知意。 以ShafferF6DomainTaskTes对ShafferF6函数进行求解(采用的是PSO,遗传算法样例参见TSPValueTaskTest)为例说明求解过程如下: 1. 入口函数位于org.lakeast.main.ShafferF6DomainTaskTest中,go函数执行。 2. 在go函数中,首先指定迭代次数(numberOfIterations),测试多少轮(testCount,多次运行以得到平均达优值),种群大小(popSize),邻域大小(neighborhoodSize),迭代结束条件(exitCondition,由于制定了迭代次数,所以设定为[0,0],也就是只有达到指定迭代次数才退出)。 3. 以testCount,numberOfIterations以及迭代结束条件exitCondition为参数构建TestBatch类的实例batch。这个类用来进行管理参测试的各种具体算法,且把数据结果按指定的格式输出为Excel文件。 4. 指定PSO中的因子产生方法,采用ExponentFactorGenerator和ConstrictFactorGenerator两种方式(实现位于org.lakeast.pso.gen包)。 5. Y表示参测试的算法数目。 6. Testable是所有可以被TestBatch测试的类需要实现的接口,以提供TestBatch生成结果Excel文件所需要的数据。 7. Domain接口是所有可以被算法解决的问题所需要实现的接口,比如说明该问题所需要的粒子位置约束范围,速度约束范围,以及适值评估的公司等。这里的Domain被实例化为ShafferF6Domain,也就是按照ShafferF6函数评估适值。 8. RingTopoSwarm是用来封装环拓扑邻域结构的类,NeighboordBestParticle是配合该类来实现按邻域最优更新速度而不是全局最优来更新。 9. 各个测试算法都被加入到TestBatch以后,batch.run()开始执行算法比较过程并输出结果Excel文件到C盘根目录(输出路径可在Testable接口中配置,除了生成Excel文件外,还可以通过修改log4j.properties在制定的位置产生运行结果日志)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清上尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值