赞
踩
在编写自己的代码之前应该了解的是算法的基本结构,具体可参考我之前的文章大纲或者这里简单函数优化亦或者是更为进阶的非线性规划问题和TSP问题
文章虽然简单,但是也能了解基本该设置的参数与具体的算法结构。
普通的遗传算法虽然也能解决一些简单的问题,但是具有很多的缺陷与不足,类似于早熟问题:种群中的所有个体过早的进化为同一状态而停止进化。
在传统的遗传算法上添加:
本篇文章重点在与对添加内容的描述,基本的遗传算法还请转到之前的文章。
更改简单函数优化中的目标函数:
M
a
x
=
sin
(
π
⋅
x
y
)
+
sin
(
y
2
)
x
,
y
∈
[
0
,
2
]
Max=\sin \left( \pi \cdot xy \right) +\sin \left( y^2 \right) \\ x,y\in \left[ 0,2 \right]
Max=sin(π⋅xy)+sin(y2)x,y∈[0,2]
不难观察的是,函数取得最大值为2,
x
,
y
x,y
x,y满足下列条件
{
π
⋅
x
y
=
k
1
π
2
⇒
x
y
=
k
1
2
y
2
=
k
2
π
2
⇒
y
=
k
2
π
2
x
,
y
∈
[
0
,
2
]
k
1
,
k
2
,
k
3
为
任
意
整
数
\left\{
选择了谢菲尔德大学的Matlab遗传算法工具箱实现算法。
工具箱的导入极为简单,可以自行在网上下载导入。
由于本文中关于交叉与变异的操作方法与适应度无关,仅在选择操作中的排序与适应度有关,因此排序决定了遗传算法整体的选取值趋向(最大值还是最小值)。
clc clear close all %% 定义遗传算法参数 NIND=40; %个体数目 NVAR=2; %变量的维数 MAXGEN=10; %最大遗传代数 PRECI=10; %变量的二进制位数 GGAP=0.9; %代沟 MP=10; %多种群的种群数量 Y_max=0; %最优值 px=0.7+(0.9-0.7)*rand(MP,1); %交叉概率(0.7,0.9) pm=0.001+(0.05-0.001)*rand(MP,1); %变异概率(0.001,0.05) Scope_individual=[0 0;2 2]; %个体的自变量范围 FieldD=[rep(PRECI,[1,NVAR]);Scope_individual;rep([1;0;1;1],[1,NVAR])]; %区域描述器 Chrom=cell(1,MP); ObjV=cell(1,MP); gen=0; %初始遗传代数 gen_keep=0; %初始保持代数 MaxObjV=zeros(MP,1); %记录精华种群 MaxChrom=zeros(MP,NVAR*PRECI); %记录精华种群的编码 FitnV=cell(1,MP); SelCh=cell(1,MP); for i=1:MP Chrom{i}=crtbp(NIND,NVAR*PRECI); %初始种群 end for i=1:MP X=bs2rv(Chrom{i},FieldD); %计算初始种群的十进制转换 ObjV{i}=Multi_fun(X); end
这里并未对多种群设置多目标。在前期参数设置阶段中:
将交叉概率与变异概率变换为在相应范围随机变换的向量,代表着各个种群不同的参数。
添加变量的维度,计算得到实际个体的二进制位数为
p
r
e
c
i
⋅
n
v
a
r
preci\cdot nvar
preci⋅nvar,即将二进制转化为十进制时,十进制维度为
n
v
a
r
nvar
nvar。
设置元胞数组独立储存每个种群的个体和适应度。
function ObjV=Multi_fun(X)
[m,~]=size(X);
ObjV=zeros(m,1);
for i=1:m
ObjV(i,1)=sin(pi*X(i,1)*X(i,2))+sin(X(i,2)^2);
end
end
gen=gen+1;
for i=1:MP
FitnV{i}=ranking(-ObjV{i}); %分配适应度值
SelCh{i}=select('sus',Chrom{i},FitnV{i},GGAP); %选择
SelCh{i}=recombin('xovsp',SelCh{i},px(i)); %重组
SelCh{i}=mut(SelCh{i},pm(i)); %变异
X=bs2rv(SelCh{i},FieldD); %计算初始种群的十进制转换
ObjVSel=Multi_fun(X); %计算目标函数值
[Chrom{i},ObjV{i}]=reins(Chrom{i},SelCh{i},1,1,ObjV{i},ObjVSel); %重新插入
end
相关函数的具体讲解参看简单函数优化。虽然都是求最大值,与简单函数优化的过程不同的是,这里并没有在适应度函数内部对优化目标函数进行修改,而是在排序操作上对适应度取了负号,实际与在适应度内部更改效果相同。
[Chrom,ObjV]=Multi_immigration(Chrom,ObjV); %移民操作
function [Chrom,ObjV]=Multi_immigration(Chrom,ObjV)
%%移民算子
MP=length(Chrom);
for i=1:MP
[~,MaxI]=max(ObjV{i});
Total_target=i+1;
if Total_target>MP;Total_target=mod(Total_target,MP);end %保证小于MP
[~,MinI]=min(ObjV{Total_target});
%%目标种群最劣个体替换成源种群最优个体
Chrom{Total_target}(MinI,:)=Chrom{i}(MaxI,:);
ObjV{Total_target}(MinI,:)=ObjV{i}(MaxI,:);
end
end
[MaxObjV,MaxChrom]=Artificial_selection(Chrom,ObjV,MaxObjV,MaxChrom); %人工选择
function [MaxObjV,MaxChrom]=Artificial_selection(Chrom,ObjV,MaxObjV,MaxChrom)
%%人工选择算子
MP=length(Chrom);
for i=1:MP
[MaxY,MaxI]=max(ObjV{i});
if MaxY>MaxObjV(i)
MaxObjV(i)=MaxY;
MaxChrom(i,:)=Chrom{i}(MaxI,:); %单独构成一个种群,长度与种群数相同
end
end
end
%找出并记录每代最优值
Y_current(gen)=max(MaxObjV); %找到精华种群中最优的个体
if Y_current(gen)>Y_max
Y_max=Y_current(gen); %更新最优值
gen_keep=0;
else
gen_keep=gen_keep+1; %最优值保持次数加1
end
对于总循环而言,考察的是在当前进化的程度,而不是进化的总代数。如果在MAXGEN的大循环中最优值保持不变,说明已经进化到很高程度了,再多的进化也无法撼动当前最优值进化的程度,此时退出进化,得到较优解。
x y xy xy | y 2 y^2 y2 |
---|---|
0.04998 0.04998 0.04998 | 1.57051 1.57051 1.57051 |
1 / 2 1/2 1/2 | π / 2 \pi/2 π/2 |
对结果进行验证与预测结果一致。
在这里只是举了一个简单的例子,哪怕不使用多种群遗传算法,单采用遗传算法也能有较好的结果。重点在于多种群算法对传统遗传算法的改进,具体问题要具体分析。
完整代码在 GitHub网站上,如果有条件可以支持一下。现在关注我你就是老粉了
本文内容参考下列文章,如有任何问题还请联系该账号
[1]史峰. MATLAB智能算法30个案例分析[M]. 北京航空航天大学出版社, 2011.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。