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

最近利用学习遗传算法的使用,对着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

 

进制数可以任意

 

适应度函数

  1. FitnV = ranking(ObjV, RFun, SUBPOP)
  2. FitnV = ranking(ObjV)
  3. 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']);
    


最后的输出结果:






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值