《MATLAB智能算法30个案例分析》笔记一:熟悉常用GA函数和简单一元函数优化

    xiaoxiao2022-06-24  65

    最近利用学习遗传算法的使用,对着MATLAB智能算法 30案例来的,首先是入门的遗传算法对简单一元函数优化:

    最先上代码看不懂,得提前熟悉Sheffield工具箱里面的各种函数:

    采用的是 gatbx 1.3版本

     

    工具箱中主要函数列表:

    创建种群

     

     [Chrom Lind BaseV] = crtbp(Nind, Lind, Base)

     

    Nind---种群个体数

    Lind---个体长度

    Base---进制数

     

    Lind就是Base的列数

     

    Chrom---种群编码

    BaseV---染色体基因位的基本字符向量

     

    [Chrom,Lind,BaseV]=crtbp(5,10)

     

    Chrom =

     

         1    0     0     0    1     1     1    1     0     0

         1    0     1     0    0     1     0    1     0     0

         0    1     1     1    1     0     0    0     1     1

         1    1     0     1    1     1     0    1     1     1

         1    1     1     1    1     0     0    0     0     1

     

     

    Lind =

     

        10

     

     

    BaseV =

     

         2    2     2     2    2     2     2    2     2     2

     

    进制数可以任意

     

    适应度函数

    FitnV = ranking(ObjV, RFun, SUBPOP) FitnV = ranking(ObjV) FitnV = ranking(ObjV, Rfun)

     

    3---按照个体的目标值ObjV(列向量)有小到大的顺序对个体进行排序,返回个体适应度值FitnV(列向量)

    2---Rfun   a:若是在[1,2]中的一个标量(压差),采用线性排序

         b:两个参数的向量: Rfun(1):对线性排序,标量指定的选择压差RFun(1)必须在【1,2】区间;

    对非线性排序,RFun(1)必须在【1,length(ObjV)-2】区间;若为NAN,RFun(1)假设为2

    Rfun(2):制定排序方法,0--线性排序,1--非线性

     

    【a(压差) ,b(0 线性| 1非线性)  】

     

         c:RFun长度为length(ObjV)  则它包含对每一行的适应度计算值

    1---SUBPOP 指明ObjV中子种群的数量,省略或NAN则为1

     

    ObjV=[1;2;3;4;5;10;9;8;7;6];

    RFun=[3;53;71;101;14;18;25;30;40;50];

    F=ranking(ObjV,RFun)

     

    F =

     

        50

        40

        30

        25

        18

         3

        53

        71

       101

        14

     

     

     

    选择函数

    SelCh= select(Self_F,Chrom,FitnV)

    SelCh= select(Self_F,Chrom,FitnV,GGAP)

    SelCh= select(Self_F,Chrom,FitnV,GGAP,SUBPOP)

     

    Sel_F 是一个字符串,包含一个低级选择函数名,入rws或sus

    GGAP是可选参数,指出了代沟部分种群被复制。省略或者为NAN,则GGAP假设为1.0

    SUBPOP决定Chrom中子种群的数量。省略或者为NAN,则SUBPOP假设为1.0

     

     

    ********************************************************************************

    Chrom=[1 11 21;2 12 22;3 13 23;4 14 24;5 15 25;6 16 26;7 17 27;8 18 28];

    FitnV=[1.50;1.35;1.21;1.07;0.92;0.78;0.64;0.5];

    SelCh=select('sus',Chrom,FitnV)

    %'sus' 轮盘赌选择函数

    SelCh =

     

         4    14   24

         2    12    22

         5   15    25

         6   16    26

         3   13    23

         1   11    21

         2   12    22

         8   18    28

    ********************************************************************************

    假设Chrom由两个子种群组成,通过轮盘赌选择函数 sus 对每个子种群选择 150% 的个体

    Fitnv=[1.50;1.16;0.83;0.50;1.50;1.16;0.83;0.5];

    SelCh=select('sus',Chrom,1.5,2)

    错误使用 select (line 35)

    Chromand FitnV disagree

     

    SelCh=select('sus',Chrom,Fitnv,1.5,2)

     

    SelCh =

     

         4   14    24

         1   11    21

         2   12    22

         3   13    23

         2   12    22

         1   11    21

         7   17    27

         6   16    26

         5   15    25

         8   18    28

         5   15    25

         6   16    26

     

     

    交叉算子函数recombin

     

    NewChrom = recombin(REC_F, OldChrom,RecOpt, SUBPOP)

     

    完成种群Chrom中个体重组,在新种群NewChrom中返回重组后的个体,一行对应一个个体

     

    REC_F是包含低级重组函数名的字符串,如 recdisxovsp

    RecOpt是一个指明交叉概率的任选参数,如省略或为NAN,将设为缺省值

    SUBPOP是一个决定Chrom中子群个数的可选参数,如果为NAN,则为1.

     

    ********************************************************************************

    对5个个体的种群进行重组

     

    Chrom=crtbp(5,10)

     

    Chrom =

     

         1     1    0     1     1     1    0     1     1    0

         1     0    0     0     0     1     0     0    1     0

         1     1     1    0     0     0     0     1    1     1

         1     0    1     0     0     1     1     0    1     0

         0     0     0    1     1     1     0     1    0     1

     

    NewChrom=recombin('xovsp',Chrom)

     

    NewChrom =

     

         1     1    0     1     0     1     0    0     1     0

         1     0    0     0     1     1    0     1     1    0

         1     1     1    0     0     0     0    1     1     1

         1     0    1     0     0    1    1     0     1    0

         0     0     0    1     1     1     0    1     0     1

     

    ********************************************************************************

    变异算子函数mut

     

    NewChrom = mut(OldChrom,Pm,BaseV)

    OldChrom---当前种群

    Pm---为变异概率(省略时为 0.7/Lind)

    BaseV指明染色体个体元素的变异的基本字符(省略是种群编码为二进制)

     

    ********************************************************************************

     

    >>%种群为2进制编码

    >>OldChrom=crtbp(5,10);

    >>NewChrom=mut(OldChrom)

    NewChrom =

     

         0    1     1     1    0     0     1    0     1     0

         1    1     0     1    0     1     1    1     0     0

         0    1     1     1    0     0     1    0     1     0

         0    0     0     0    0     1     0    1     0     1

         1    1     0     1    0     0     0    1     1     0

     

    >>  OldChrom

     

    OldChrom =

     

         0    1     1     1    0     0     1    0     1     0

         1    1     0     1    0     1     1    1     0     1

         0    1     1     1    0     0     1    0     0     1

         0    0     0     0    0     1     0    1     0     1

         1    1     0     1    1     0     0    1     1     0

     

     

    ********************************************************************************

    种群为非二进制编码,创建一个长度为8、有6个个体的随机种群

    BaseV=[8 8 8 4 4 4 44];

    [Chrom,Lind,BaseV]=crtbp(6,BaseV);

    Chrom

     

    Chrom =

     

         0    5     4    2     2     1    3     2

         2    1     0     1    2     1     0    0

         3    0     2     2    0     3     1    2

         4    2     6     0    1     0     1    1

         2    2     0     1    2     3     2    3

         4    3     7     3    2     3     0    2

     

     

    注意到加粗的为8进制,但是发现了没,这个顺序是和BaseV不一样的!

    NewChrom=mut(Chrom,0.7,BaseV)

     

    NewChrom =

     

         0    5     4     1     1    3     0     2

         2    4    0     2     0     1    0     2

         6     4    4     1     3     3    3     1

         0     2    2    0     2     0    1     2

         5     1    3     1     1     0    1     2

         1     5     7    1    0     2     1     2

     

    红色的变异的

     

     

     

    重插入函数,重新插入子代到种群

     

    [Chrom, ObjVCh] = reins(Chrom, SelCh, SUBPOP,InsOpt, ObjVCh, ObjVSel)

     

    用子代代替附带并返回结果种群

     

    SelCh---子代

    InsOpt---

    [1]:标量,指明替代方法,0位均匀选择,1为适应度选择,代替父类中适应度最小的,默认为0

     

    [2]:[0,1]之间的标量,表示每个子种群中重插入的子代个体在整个子种群中个体的比率,默认为1

     

    ObjVCh---可选的列向量,包括Chrom中个体的目标值。对于基于适应度的重插入,ObjVCh是必须的

     

    ObjVSel--- 包含SelCh中个体的目标值。如果子代的数量大于重插入种群中的子代数量,则是必须的,

    此时按照适应度大小插入

     

     

    >>Chrom=crtbp(5,10)

     

    Chrom =

     

         0    1     0     1    1     0     0    1     1     1

         0    0     1     0    1     0     1    0     0     0

         0    0     0     1    0     0     0    0     1     0

         0    1     1     0    1     0     1    0     1     1

         0    0     1     1    0     0     1    1     1     1

     

    >>SelCh=crtbp(2,10)

     

    SelCh =

     

         0    0     0     1    1     1     1    1     1     0

         0    0     0     0    1     1     0    0     1     0

     

    >>Chrom=reins(Chrom,SelCh)

     

    Chrom =

     

         0    0     0     1    1     1     1    1     1     0

         0    0     1     0    1     0     1    0     0     0

         0    0     0     1    0     0     0    0     1     0

         0    0     0     0    1     1     0    0     1     0

         0    0     1     1    0     0     1    1     1     1

     

     

     

     

     

    实用函数

    bs2rv

    二进制到十进制的转换

    Phen =bs2rv(Chrom,FieldD)

    将二进制的Chrom转换为实值

     

    Field----  len

      lb

         ub

        code

      scale

      lbin

      ubin

     

    len 子串长度    sum(len)=size(Chrom,2)

    lb  ub  每个变量的上下界

    code 指明子串怎样编码,1为标准的二进制编码,0为格雷编码

    scale  指明每个子串所使用的刻度,0表示算术刻度,1表示对数刻度

    lbin ubin表示指示范围是否包含边界,0不包含 1包含

     

    FieldD=[size(Chrom,2);-1;10;1;0;1;1;]

     

    FieldD=

     

         8

        -1

        10

         1

         0

         1

         1

     

     

    Phen=bs2rv(Chrom,FieldD)

     

    Phen =

     

        4.5216

        1.5020

        9.9569

        0.7686

     

     

    ********************************************************************************

    rep  复制矩阵

    MatOut =rep(MatIn,REPN);

     

    REPN指明复制次数  REPN:【1,2】表示 纵向复制1次,横向复制2次

    熟悉完了函数,就可以利用这些函数来进行一些简单的求解:

    附上代码:

    %简单一元函数优化 % f(x)=(sin(10*pi*x)/x),x belongs to [1,2] clc clear close all %%画出函数图 figure(1); hold on; lb=1;ub=2;   %函数自变量范围 [1,2],初始种群是随机的,但是将初始种群利用 bs2rv 映射到实数时,这两个值限制了实数的范围 ezplot('sin(10*pi*X)/X',[lb,ub]); xlabel('自变量'); ylabel('函数值'); %%定义遗传算法参数 NIND=40;  %种群大小 MAXGEN=20000;  %最大遗传代数,书中用的是20,我用20000写的玩的 PRECI=20; %个体长度 GGAP=0.95; %代沟 px=0.7;     %交叉概率 pm=0.01;   %变异概率 trace=zeros(2,MAXGEN);  %寻优结果初始值 FieldD=[PRECI;lb;ub;1;0;1;1];   %FieldD=[20 20;-2,-2;-2,-2; 1 1;0 0;1 1; 1 1],利用bs2rv计算出来的会有两列值 Chrom=crtbp(NIND,PRECI); %%优化 gen=0;   %代计数器 X=bs2rv(Chrom,FieldD);  %初始种群二进制到十进制 ObjV=sin(10*pi*X)./X;   %计算目标函数值,NIND个目标 while gen<MAXGEN     FitnV=ranking(ObjV);   %分配适应度     SelCh=select('sus',Chrom,FitnV,GGAP);  %根据适应度,代数,用sus选择子种群     SelCh=recombin('xovsp',SelCh,px);  %重组,将样本截断,随机重组成新的值     SelCh=mut(SelCh,pm);   %另重组后的种群进行变异,pm为概率     X=bs2rv(SelCh,FieldD); %变异后形成新的种群,转化为实值     ObjVSel=sin(10*pi*X)./X; %计算实值对应的目标函数值     [Chrom,ObjV]=reins(Chrom,SelCh,1,1,ObjV,ObjVSel);  %将子种群,看做一个子种群,用适应度选择,ObjV是初始种群的目标值,ObjVSel是选择后的目标值     X=bs2rv(Chrom,FieldD);     gen=gen+1;          %获取每一代的最优解及其序号,Y为最优解,I为个体的序号     [Y,I]=min(ObjV);     %Y是最小值,I是其索引     trace(1,gen)=X(I);   %记录每代的最优值,目标函数的x值     trace(2,gen)=Y;      %记录每代的最优值,目标函数的y值 end plot(trace(1,:),trace(2,:),'b*'); grid on; plot(X,ObjV,'b*'); hold off; %%画进化图 figure(20); plot(1:MAXGEN,trace(2,:)); grid on; xlabel('遗传代数'); ylabel('解得变化'); title('进化过程'); bestY=trace(2,end); %end表示最后的索引 bestX=trace(1,end); fprintf(['最优解:\nX=',num2str(bestX),'\nY=',num2str(bestY),'\n']);     

    最后的输出结果:

    转载请注明原文地址: https://ju.6miu.com/read-1123975.html

    最新回复(0)