遗传算法
一、定义
遗传算法(Genetic Algorithm, GA)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。
遗传算法以一种群体中的所有个体为对象,并利用随机化技术指导对一个被编码的参数空间进行高效搜索。其中,选择、交叉和变异构成了遗传算法的遗传操作;参数编码、初始群体的设定、适应度函数的设计、遗传操作设计、控制参数设定五个要素组成了遗传算法的核心内容。
二、特点
- 遗传算法从问题解的串集开始搜索,而不是从单个解开始。这是遗传算法与传统优化算法的极大区别。传统优化算法是从单个初始值迭代求最优解的;容易误入局部最优解。遗传算法从串集开始搜索,覆盖面大,利于全局择优。
- 遗传算法同时处理群体中的多个个体,即对搜索空间中的多个解进行评估,减少了陷入局部最优解的风险,同时算法本身易于实现并行化。
- 遗传算法基本上不用搜索空间的知识或其它辅助信息,而仅用适应度函数值来评估个体,在此基础上进行遗传操作。适应度函数不仅不受连续可微的约束,而且其定义域可以任意设定。这一特点使得遗传算法的应用范围大大扩展。
- 遗传算法不是采用确定性规则,而是采用概率的变迁规则来指导他的搜索方向。
- 具有自组织、自适应和自学习性。遗传算法利用进化过程获得的信息自行组织搜索时,适应度大的个体具有较高的生存概率,并获得更适应环境的基因结构。
- 此外,算法本身也可以采用动态自适应技术,在进化过程中自动调整算法控制参数和编码精度,比如使用模糊自适应法。
三、基本运算过程
a)初始化:设置进化代数计数器t=0,设置最大进化代数T,随机生成M个个体作为初始群体P(0)。
b)个体评价:计算群体P(t)中各个个体的适应度。
c)选择运算:将选择算子作用于群体。选择的目的是把优化的个体直接遗传到下一代或通过配对交叉产生新的个体再遗传到下一代。选择操作是建立在群体中个体的适应度评估基础上的。
d)交叉运算:将交叉算子作用于群体。遗传算法中起核心作用的就是交叉算子。
e)变异运算:将变异算子作用于群体。即是对群体中的个体串的某些基因座上的基因值作变动。群体P(t)经过选择、交叉、变异运算之后得到下一代群体P(t+1)。
f)终止条件判断:若t=T,则以进化过程中所得到的具有最大适应度个体作为最优解输出,终止计算。
流程图
四、代码实现
4.1Schaffer()函数
数学表达式:
代码:
function y=Schaffer(x)
[row,col]=size(x);
if row>1
error('输入的参数错误');
end
y1=x(1,1);
y2=x(1,2);
temp=y1^2+y2^2;
y=0.5-(sin(sqrt(temp))^2-0.5)/(1+0.001*temp)^2;
y=-y;
4.2Griewank()函数
数学表达式:
代码:
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;
4.3Rastrigin()函数
数学表达式:
代码:
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;
4.4Drawfunc(label)函数
作用:根据lable值画出待优化的函数,只画出二维情况作为可视化输出
部分代码解释:
[X,Y] = meshgrid(x,y)
%基于向量x和向量y中包含的坐标返回二维网格坐标。
%X是一个矩阵,其中每一行都是复制x;Y是一个矩阵,其中每一列都是复制y。
%矩阵X的行数是length(y);矩阵Y的列数是length(x)。
shading interp
%可以实现对不平滑的图像进行平滑
代码:
function Drawfunc(label)
x=-5:0.05:5;%1行201列的向量
if label==1
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
xlabel('x1-axis'),ylabel('x2-axis'),zlabel('f-axis');
title('mesh');
end
if label==2
y = x;
[X,Y] = meshgrid(x,y);
[row,col] = size(X);
for l = 1 :col
for h = 1 :row
z(h,l) = Schaffer([X(h,l),Y(h,l)]);
end
end
surf(X,Y,z);
shading interp
xlabel('x1-axis'),ylabel('x2-axis'),zlabel('f-axis');
title('mesh');
end
if label==3
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
xlabel('x1-axis'),ylabel('x2-axis'),zlabel('f-axis');
title('mesh');
end
4.5fun()函数
作用:函数用于计算粒子适应度值
代码:
function y = fun(x,label)
%函数用于计算粒子适应度值
%x input 输入粒子
%y output 粒子适应度值
if label==1
y=-Rastrigin(x);
elseif label==2
y=-Schaffer(x);
else
y=-Griewank(x);
end
4.6主程序GA.m
% Optimizing a function using Simple Genetic Algorithm with elitist preserved
%Max f(x1,x2)=100*(x1*x1-x2).^2+(1-x1).^2; -2.0480<=x1,x2<=2.0480
%下面为代码。函数最大值为3904.9262,此时两个参数均为-2.0480,有时会出现局部极值,此时一个参数为-2.0480,一个为2.0480。变
%异概率pm=0.05,交叉概率pc=0.8。
clc;
clear all;
format long;%设定数据显示格式
%初始化参数
T=500;%仿真代数
N=80;% 群体规模
pm=0.05;pc=0.8;%交叉变异概率
umax=30;umin=-30;%参数取值范围
L=10;%单个参数字串长度,总编码长度Dim*L
Dim=5;%Dim维空间搜索
bval=round(rand(N,Dim*L));%初始种群,round函数为四舍五入
bestv=-inf;%最优适应度初值
funlabel=2; %选择待优化的函数,1为Rastrigin,2为Schaffer,3为Griewank
Drawfunc(funlabel);%画出待优化的函数,只画出二维情况作为可视化输出
%迭代开始
for ii=1:T
%解码,计算适应度
for i=1:N %对每一代的第i个粒子
for k=1:Dim
y(k)=0;
for j=1:1:L %从1到L,每次加以1
y(k)=y(k)+bval(i,k*L-j+1)*2^(j-1);%把第i个粒子转化为十进制的值,例如y1是第一维
end
x(k)=(umax-umin)*y(k)/(2^L-1)+umin;%转化为实际的x1
end
% obj(i)=100*(x1*x1-x2).^2+(1-x1).^2; %目标函数
obj(i)=fun(x,funlabel);
xx(i,:)=x;
end
func=obj;%目标函数转换为适应度函数
p=func./sum(func);
q=cumsum(p);%累加
[fmax,indmax]=max(func);%求当代最佳个体
if fmax>=bestv
bestv=fmax;%到目前为止最优适应度值
bvalxx=bval(indmax,:);%到目前为止最佳位串
optxx=xx(indmax,:);%到目前为止最优参数
end
Bfit1(ii)=bestv; % 存储每代的最优适应度
%%%%遗传操作开始
%轮盘赌选择
for i=1:(N-1)
r=rand;
tmp=find(r<=q);
newbval(i,:)=bval(tmp(1),:);
end
newbval(N,:)=bvalxx;%最优保留
bval=newbval;
%单点交叉
for i=1:2:(N-1)
cc=rand;
if cc<pc
point=ceil(rand*(2*L-1));%取得一个1到2L-1的整数
ch=bval(i,:);
bval(i,point+1:2*L)=bval(i+1,point+1:2*L);
bval(i+1,point+1:2*L)=ch(1,point+1:2*L);
end
end
bval(N,:)=bvalxx;%最优保留
%位点变异
mm=rand(N,Dim*L)<pm;%N行
mm(N,:)=zeros(1,Dim*L);%最后一行是精英不变异,强制赋0
bval(mm)=1-bval(mm);
end
%输出
figure;
plot(-Bfit1);% 绘制最优适应度进化曲线
bestv %输出最优适应度值
optxx %输出最优参数
五、结果分析
5.1目标函数为Schaffer()函数
种群数量N=10, 解空间维度Dim=2
种群数量N=10, 解空间维度Dim=5
种群数量N=10, 解空间维度Dim=10
种群数量N=40, 解空间维度Dim=2
种群数量N=40, 解空间维度Dim=5
种群数量N=40, 解空间维度Dim=10
种群数量N=80, 解空间维度Dim=2
种群数量N=80, 解空间维度Dim=5
种群数量N=80, 解空间维度Dim=10
对选择不同的种群数量和解空间维度的时间统计如下表:
维度\种群数量 | 10 | 40 | 80 |
---|---|---|---|
2 | 1.698s | 2.344s | 3.217s |
5 | 2.062s | 2.860s | 5.090s |
10 | 2.720s | 3.989s | 5.726s |
分析:对目标函数为Schaffer()函数,分别选择种群数量为10、40、80,解空间维度数为2、5、10,种群数量为40和80时,最优适应度bestv =0.998279300372192,种群数量为10时,最优适应度bestv =0.990283826870370,差别并不明显,从运行速度上看,随着维度和种群数量的增加呈递增趋势。
5.2目标函数为Griewank()函数
种群数量N=10, 解空间维度Dim=2
种群数量N=10, 解空间维度Dim=5
种群数量N=10, 解空间维度Dim=10
种群数量N=40, 解空间维度Dim=2
种群数量N=40, 解空间维度Dim=5
种群数量N=40, 解空间维度Dim=10
种群数量N=80, 解空间维度Dim=2
种群数量N=80, 解空间维度Dim=5
种群数量N=80, 解空间维度Dim=10
对选择不同的种群数量和解空间维度的时间统计如下表:
维度\种群数量 | 10 | 40 | 80 |
---|---|---|---|
2 | 1.923s | 3.113s | 4.215s |
5 | 1.959s | 3.523s | 4.664s |
10 | 2.636s | 3.564s | 4.919s |
分析:对目标函数为Griewank()函数,分别选择种群数量为10、40、80,解空间维度数为2、5、10,适应度函数的最优解随着种群数量和维度变化有着较明显差别,随着维度增多,最优解值越小,从运行速度上看,随着维度和种群数量的增加呈递增趋势。
5.3目标函数为Rastrigin()函数
种群数量N=10, 解空间维度Dim=2
种群数量N=10, 解空间维度Dim=5
种群数量N=10, 解空间维度Dim=10
种群数量N=40, 解空间维度Dim=2
种群数量N=40, 解空间维度Dim=5
种群数量N=40, 解空间维度Dim=10
种群数量N=80, 解空间维度Dim=2
种群数量N=80, 解空间维度Dim=5
种群数量N=80, 解空间维度Dim=10
对选择不同的种群数量和解空间维度的时间统计如下表:
维度\种群数量 | 10 | 40 | 80 |
---|---|---|---|
2 | 1.643s | 2.283s | 3.011s |
5 | 1.845s | 3.528s | 3.988s |
10 | 1.982s | 4.025s | 4.780s |
分析:对目标函数为Rastrigin()函数,分别选择种群数量为10、40、80,解空间维度数为2、5、10,适应度函数的最优解随着种群数量和维度变化有着较明显差别,随着维度增多,最优解值越小,最优适应度进化曲线比较曲折,即随着迭代次数的增加,对最优解的影响较大,从运行速度上看,随着维度和种群数量的增加呈递增趋势。
六、小结
- 从运行时间上分析:观察最优适应度进化曲线及运行时间统计表格,可以看出当种群规模相同,若选取的维度越多,则最优适应度进化曲线迭代次数越多,运行时间越长;当维度相同,若种群规模越大,则最优适应度进化曲线迭代次数越多,运行时间越长。
- 从精度上分析:相对来说,Schaffer()函数最优解的结果没有随种群规模或维度的变化有明显波动,较为稳定;对Griewank()函数和Rastrigin()函数,维度越大,结果越精确。
- 遗传算法对径向基函数参数的初始化是随机的,然后不断迭代优化,基本上每次运行后,得到的参数是不同的,这样能保证遗传算法优化的多样性,避免陷入定制。
- 遗传算法的编码使用二进制编码,随机产生一个初始种群。L表示编码长度,通常由对问题的求解精度决定,编码长度L越长,可期望的最优解的精度也就越高,过大的L会增大运算量。