GA遗传算法Matlab版本实例注释

关于我对GA遗传算法的理解:

刚开始只听说过遗传算法的时候,听到这个名字就感觉好牛掰的样子。然后看了一本叫做《MATLAB智能算法30个案例分析》的书,学习了GA遗传算法,然而学完了之后知道我的第一感觉是什么?那就是真特么扯淡,哈哈哈!这特么不就是瞎碰,瞎猫碰上死耗子,碰上了最优解就碰上了,碰不上不就得到个不知道差多少的解吗?不过存在即合理仔细想想能发明这个算法的人还是很值得尊敬的。好了来说说我的理解,首先遗传算法当然是模拟生物进化优胜劣汰的法则了,它最大的优点就是不要你去寻找解,而只需要你作为上帝去否决那些你认为不好的解,最终留下来的就是最优解(或者次优解)了

首先来解释一下几个名词:

1. 染色体,一条染色体对应的就是你需要求的一个解,例如你需要求一个三元四次的复杂方程的极小值,那么你的一个结当然包含三个数(因为是三元嘛,当然是三个未知 数啦),假设是x,y,z。那么你的一条染色体就包含三个数,类似于一个向量[x  y  z]。类似的如果你的一个解只有一个数,那么一条染色体就只包含一个数。

2. 基因,咱们都是理科生,当然知道染色体是由基因组成的,上面说到了[x  y  z]对应的是一条染色体,那么自然组成x  , y , z的就是基因喽,这里我们就要说到编码了,一般 我们会将染色体进行编码,假设使用的是二进制编码,那么我们用二进制0和1将[x  y  z]横着写成一排,那么是不是就是遗传0和1。那么这些0和1就是基因了。

3. 交叉,交叉也是跟生物里面学的一样,就是两条染色体并排的时候相对应的那一段交叉接起来

4. 变异,变异就是基因中某个bit的0变成了1,或者1变成了0,几率很小。当然在算法中是我们让它变异的。

5. 压差,在下面的例子中,有个词语叫“压差”,之前网上都没找到明白的解释,其实说的那么高端,压差就是指你把本来0~255之间的数按照某种算法映射到1~10的话,那么 压差就是指这个1~10了,其实就是归一化之后的范围。

6. 适应度,上面说到优胜劣汰,我们作为上帝需要指定一个规则,怎么样的算是优秀,什么样的算是劣质,说让谁淘汰就让谁淘汰,比如说我们求一个方程的极小值,那么 我们当然是将每条染色体的值带入到方程中,求得的值越小就越优秀,越大就越劣质喽。那么我们就要淘汰那些使得方程值大的染色体,通过交叉编译来补充那些被淘汰 染色体的位置。

7. 适应度函数,适应度函数顾名思义就是用来计算适应度的函数,这个函数的定义很重要,但是总得来说只要保证越符合我们要求的,得出来的值(适应度)越大理论上就 可以接受,至于好不好另说。

8. 种群,就是若干个染色体组成种群。

接下来就说说GA遗传算法的步骤:

下面这个用matlab写的例子就是一个求极值问题,求方程y = sin(10*pi*x)/x , x属于[1,2] , 的极值

clc;

clear all;

close all;

figure(1);

hold on;

lb = 1; ub = 2; %这个值是自变量的范围,在这个范围内求解

ezplot(‘sin(10*pi*X)/X’,[lb,ub]); %第一个参数表示的是方程,y的计算公式,画出图像

xlabel(‘自变量/X’);

ylabel(‘函数值/Y’);

NIND = 40;  %初始化40个解,每一个解代表的是一条染色体,这条染色体就代表的是一个x的值

MAXGEN = 20; %最大遗传代数

PRECT = 20; %染色体精度,也就是一个个体的基因数(2进制数长度),也就是用多少个bit表示一个x的值

GGAP = 0.95; %代沟,表示每一代从种群中选择多少个体到下一代

px = 0.7;   %染色体交叉几率,具体自己写的话不知道这个概率怎么用的,不过matlab中作为参数直接带入就好了

pm = 0.01;  %染色体变异几率,具体自己写的话不知道这个概率怎么用的,不过matlab中作为参数直接带入就好了

trace = zeros(2,MAXGEN);%初始化为0

FieldD = [PRECT;lb;ub;1;0;1;1]; % PRECT:2进制位数 lb:范围下限 ub:表示范围上限 

                                % 1:二进制编码 0:表示用算术刻度 1:表示包含左边界 1:表示包含右边界

Chrom = crtbp(NIND,PRECT); %随机产生初始解

gen = 0;%遗传代数

X = bs2rv(Chrom , FieldD); %根据区域描述器,自动将2进制编码转化成指定范围内的实数值

                        %得出的X是一个长度为40的列向量

ObjV = sin(10*pi*X)./X ;%“./”表示为阵列操作,非矩阵运算,得出的也是一个长度为40的列向量,适应度值

                       
%经过上一步,X已经为列向量,所以ObjV也是列向量了

while gen<MAXGEN

    

    %ranking : 根据适应度值,使用ranking()得出各自的入选率(适应度)

    %第一个参数:注意ObjV必须是列向量(这是ranking函数要求的),表示需要计算适应度的种群,

    %第二个参数:一个有两个标量的向量,第一个标量可以认为总为2,同时代表压差的上限

    %           第二个标量有两重意义,如果为0表示线性排序,如果为1表示非线性排序,

    %           同时它代表压差的下限。返回得到的FitnV会是一个长度跟ObjV相同的列向量

    %           ,他们之间的值是一一对应的,FitnV中较大的表示适应度的值对应ObjV中较

    %           较小的值。但是FitnV中的顺序并非是有序的,顺序跟ObjV中的每个值得顺序

    %           是一样的。

    %第三个参数:表示种群中子种群的数量

    FitnV = ranking(ObjV,[2,0],1);

    

    %select : 通过计算得到的适应度值,从原始种群Chrom中筛选一些不符合要求的个体得到

    %           新的种群返回个SelCh

    %第一个参数:表示选择筛选的策略,sus表示随机平均选择 ,还可以是rws表示轮盘赌选择

    %第二个参数:表示原始的需要被筛选的种群

    %第三个参数:表示这个种群对应的适应度

    %第四个参数:表示代沟,也就是说从Chrom中选择多少百分比的个体到下一代,这里为0.95

    %           也就是说从Chrom中选择Chrom*0.95个个体进入下一代,有0.05的染色体被淘汰

    SelCh = select(‘sus’,Chrom,FitnV,GGAP); %这就是优胜劣汰的过程

                                            

    SelCh = recombin(‘xovsp’,SelCh,px); %交叉基因函数 ,xovsp或者recdis表示交叉策略 , px表示染色体交叉几率

    SelCh = mut(SelCh,pm);              %变异函数 ,pm表示编译几率

    X = bs2rv(SelCh , FieldD);

    ObjVSel = sin(10*pi*X)./X;

    

    %reins : 将子代个体插入到父代种群中,代替那些不合适的父代个体

    %第一个参数:表示父代种群

    %第二个参数:子代种群

    %第三个参数:指明Chrom,SelCh中子种群个数,每个子种群必须有相同的大小

    %第四个参数:其实是一个有两个元素的向量,在这里相当于[1,1] ,第一个标量表示用什么策略将子代

    %           将子代插入父代种群,如果为0表示用随机均匀选择,如果为1表示根据适应度进行选择;

    %           第二个标量表示子代种群插入父代,占百分比,可以是[0,1]之间的标量,如果缺省表示

    %           默认值为1

    %第五个参数:基于适应度重插入(也就是第四个参数为1)的时候这个参数是必须的,Objv包含Chrom中

    %           个体的目标值(也就是根据公式计算得到的值比如上面的sin(10*pi*X)./X得到的值)。

    %           这是因为基于适应度的方法,得到适应度必须是根据目标值来确定适应度,所以这里必须

    %           要带入目标值。

    %第六个参数:如果子代的个体数量大于将要插入父代的个体数量,那么这个参数是必须的,因为待插入

    %           的个数多余需要插入的个数,那么必然存在有一部分不能插入,那么淘汰那一部分个体,是

    %           根据子代种群的个体适应度来决定的,淘汰掉适应度底的个体,那么得到个体的适应度就需

    %           要子种群的各个个体的目标值来计算。

    [Chrom,ObjV] = reins(Chrom , SelCh , 1 , 1 , ObjV , ObjVSel)

                              

    X = bs2rv(Chrom , FieldD);

    gen = gen + 1;

    

    %min : 返回向量ObjV的最小值,Y记录ObjV中每一列的最小值,I记录每一列的最小值的行号

    [Y,I] = min(ObjV)

    trace(1,gen) = X(I);

    trace(2,gen) = Y;

end

plot(trace(1,:),trace(2,:),’bo’);

grid on;

plot(X,ObjV,’b*’);

hold off;

figure(2);

plot(1:MAXGEN,trace(2,:));

grid on;

xlabel(‘遗传代数’);

ylabel(‘解的变化’);

title(‘进化过程’);

bestY = trace(2,end);

bestX = trace(1,end);

fprintf([‘最优解:\nX = ‘, num2str(bestX), ‘\nY = ‘ , num2str(bestY) , ‘\n’]);

    原文作者:遗传算法
    原文地址: https://blog.csdn.net/d_a_r_k/article/details/51648046
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞