您的位置:首页 > 编程语言 > MATLAB

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

2016-09-14 11:14 441 查看
最近利用学习遗传算法的使用,对着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指明染色体个体元素的变异的基本字符(省略是种群编码为二进制)

 

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

 

c039

>>%种群为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']);

    

最后的输出结果:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: