1.遗传算法介绍
遗传算法的基本思想是从初始种群出发,采用优胜劣汰适者生存的自然法则选择个体,并通过杂交、变异来产生新
一代种群,如此逐代进化,直到满足目标为止。
2.自己解决的问题
自己选取了一个二维函数 “obj(i)=100*(x1*x1-x2).^2+(1-x1).^2; %目标函数 ”来进行函数优化
3.如何开始
种群是指用遗传算法求解问题时,初始给定的多个解的集合。遗传算法的求解过程是从这个子
集开始的。初始化种群大小等于80
4.编码
二进制编码是将原问题的结构变换为染色体的位串结构。在二进制编码中,首先要确定二进制字符串的长度l,该长度与
变量的定义域和所求问题的计算精度有关。例 假设变量x的定义域为[4,10],要求的计算精度为10-5,则需要将[4,10]至少分为600000个等长小区间,每个小区间用一个二进制串表示。于是,串长至少等于20,原因是524288=2^19<600000<2^20=1048576,这样,对应于区间[4,10]内满足精度要求的每个值x,都可用一个20位编码的二进制串<b19,b18,…,b0>来表示。
我用rand随机函数,来生成初始种群 :bval=round(rand(N,Dim*L));%初始种群,round函数为四舍五入
5.解码
解码即将编码空间中的基因串翻译成解空间中的自变量的实际值的过程。对于二进制编码而言,每个二进制基因串都可以这样翻译成一个十进制实数值,。例如基因串0000110110000101,可以翻译为,这里二进制基因串转变成十进制是从左至右进行的。
可以想到以下的映射:
000000000=−1111111111=2
000000000=−1111111111=2
因此可以得到以下的解码公式:
(111111111)into10∗e−1=512∗3512−1=2(000000000)into10∗e−1=0−1=−1
(111111111)into10∗e−1=512∗3512−1=2(000000000)into10∗e−1=0−1=−1
6.适应度
个体的适应值即是它繁殖的能力,它将直接关系到其后代的数量,在遗传算法中,适应函数是用来区分群体中个体好坏的标准,是算法演化过程的驱动力,同时也是进行自然选择的唯一依据。
适应函数: 适应值会出现两种情形,一是极小情形即原始适应值越小个体性能越好;另一种是极大化情形即原始适应值越大个体性能越好 。遗传算法中的某些选择策略则要求适应函数是非负的,而且适应值越大表明个体的性能越好。
7.选择
不同的选择策略将导致不同的选择压力,即下一代中父代个体的复制数目的不同分配关系。
转盘式选择 (轮赌)
转盘式选择是基于适应值比例的选择中比较重要的选择策略。
先计算个体的相对适应值 =
根据选择概率p 把一个圆盘分成N份
生成一个内的随机数 r(0≤r≤1),若 ,则选择个体 i
8.交叉
交叉指的是交换染色体片段产生后代两个新的后代,例如典型的单点交叉方式:随机选择两个个体进行交叉,按照以下的方式产生新的子代。
0 1 1 0 | 1 -> 0 1 1 0 0
1 1 0 0 | 0 -> 1 1 0 0 1
9.变异
变异运算是指将个体染色体编码串中的某些基因座上的基因值用该基因座的其它等为基因来替换,从而形成一个新的个体 。遗传算法中使用变异算子主要有以下两个目的:①改善遗传算法的局部搜索能力。②维持群体的多样性,防止出现早熟现
我采用的是基本位变异方法:①对个体的每一个基因座,依变异概率 p指定其为变异点。②对每一个指定的变异点,对其基因值做取反运算或用其他等位基因值来代替,从而产生出一个新的个体。
10.多次迭代,求出最优值
我选择的迭代次数是500次
下面附上源程序代码及其运行结果
先看主函数
%初始化参数
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
数据太多,这里只截取一点啦
转盘选择
%轮盘赌选择
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;%最优保留
ch:
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 %输出最优参数
function Drawfunc(label)
x=-5:0.05:5;%41列的向量
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
最终结果
11.总结
本文介绍了简单遗传算法的实现过程,并以一个简单的函数优化作为案例说明了其应用。但是在实际的应用过程中,还需要对相关参数进行调整,使其效率得到更大的提高。