Matlab免疫算法---解决二维规划问题(上)

2021年11月21日 5点热度 0条评论 来源: 还是暴力香

免疫算法:

免疫算法是模仿了人体的免疫系统机制进行的一种算法,同时它也是遗传算法的理论基础,归根结底,免疫算法的主要步骤是(代码及详解在后):
①抗原识别:即寻找要解决的问题。

②初始抗体生成:生成随机解,一部分来自初始化,在这里因为有很多的迭代次数,所以每一次迭代都会出现新的随机解,这也是另一部分初始解的来源,即从上一次迭代的记忆库中提取出。

③亲和力计算:通过构造评价函数来进行亲和力的计算,在之后的克隆、变异与选择中这是非常重要的一个指标,同时构造的选择也是难点,这一步骤也是免疫算法的核心步骤。

④记忆单元的更新:在每次的迭代过程中,将抗体中的最优解(亲和力最高的值)选出来,放入记忆库中,保证了子代的优良解。

⑤解的选择:根据亲和力的高度,选择出亲和度较高的一部分群体进行克隆。同时亲和度较低的将会被舍弃,也就是抑制其克隆。

⑥产生新抗体(较为初级的免疫算法):在这里通过自定义函数,进行优良解的克隆、变异和选择,产生新的一批抗体,如此进行迭代,直到找到最优解。

代码块及详解

在这里介绍的是免疫算法的其中一个——克隆选择算法,这与上述的概览相对应,上面是给读者一个明确的代码思路过程。
题目:用克隆优化算法求解如下模型的最优解
f(x)=x+5sin(8x)+7cos(3x)
0≤x≤8
#

%1.初始化函数
function A=InitializeFun(m,n)
%生成抗体集合A,抗体数目为m,每个抗体基因长度为n
A=2.*rand(m,n)-1;
A=hardlim(A);  %过滤掉小于零的数hardlim的范围为[0,1],大于零的数都约为1
end

详解:在这里定义一个初始化函数,是用来第一次产生初始抗体,抗体的数量为m个,即m行;每个抗体都由n个二进制码组成,构成了n列。A返回的是一个m行n列的矩阵,行代表抗体数目,n代表每个抗体由n位二进制码组成。(采用二进制为了更好地运算,同时尽可能的扩大解的随机性,在n取一定的值时)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%2.解码函数(将二进制转为十进制)
function X=DecodeFun(A,xmin,xmax)
A=fliplr(A);%左右翻转矩阵A
SA=size(A);
AX=0:1:21;%
AX=ones(SA(1),1)*AX;%
SX=sum((A.*2.^AX)');%
X=xmin+(xmax-xmin)*SX./4194303;
end

详解:在这道题目中选择的n为22,所以用AX产生了一个1*22阶的矩阵,为什么要进行翻转矩阵?从刚才的初始化抗体可以得知,每行对应一个抗体且由其二进制码组成,在这翻转是因为需要将二进制转为十进制,第二个AX所对应的就是一个与A同型的矩阵,SX的作用就是进行A矩阵的二进制转化,只不过我们经常笔算的时候是将最后一位定位2^0位,在这里则是反过来,这也就是为什么开头需要进行矩阵的左右翻转,同时在SX中的运算中害看到了转置符号,因为sum函数默认对列求和,而我们每个抗体对应的二进制码是一行,所以就需要进行转置。
最后一句的X=xmin+(xmax-xmin)*SX./4194303;这句代码在遗传算法中也又出现,自己目前的水品因素,这句代码还没有能力进行解释,但是在很多的解码函数中都有出现,还望大佬们对我进行指点。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%3.克隆函数
%克隆算子
function [T,AAS]=ReproduceFun(mn,cfactor,m,Affinity,A,T)
if mn==1
    CS=m;
    T=ones(m,1)*A(Affinity(end),:);
else
    for i =1:mn
        %每个抗体的克隆数与它和抗原的亲和度成正比%
        
        CS(i)=round(cfactor*m);%将每个数字四舍五入到最近的数字
        %计算每个抗体的克隆数目CS(i)
        
        AAS(i)=sum(CS);
        %每个抗体克隆的最终下标位置
        
        ONECS=ones(CS(i),1);
        %生成CS(i)行1列单位矩阵ONES
        
        subscript=Affinity(end-i+1);
        %确定当前要克隆抗体在抗体集A中的下标
        
        AA=A(subscript,:);
        %确定当前要克隆抗体的基因序列集合AA(1xn)
        
        T=[T;ONECS*AA];
        %得到零时存放抗体的集合T
    end
end

详解:到这也就是免疫算法的一个重要的函数了,在函数中的T是临时存储的抗体集合,AAS是对应的克隆抗体的最终下标,为什么说是最终?接着往下看,在这里先说明一下,mn指的是每代抗体的准备进行克隆的数目,cfcator是克隆因子,用来计算每个抗体得到的克隆数目,Affinity是函数值进行从小到大的排列后,所对应的下标,即为一个1行的矩阵;当mn为1的时候,也就是在一个群体中只选择出了一个解进行克隆,那么接下来这一个解需要克隆的数目就是m(这里自己需要慢慢想一下,为什么是克隆m个,因为mn为一个,那么肯定是最优解,所以进行它的克隆得到的下一群体就都是最优解了),若mn不为1,那么就按照else函数的操作,求每个抗体的克隆数目,记录每个抗体克隆的最后一个克隆体的下标(在后面的主函数就能知道为什么要这么进行操作,先不要急,慢慢看),生成的ONES函数也就是为了后续的克隆而用的(矩阵的乘法),subscript是每次克隆的抗体的下标,Affinity存的是从小到大的函数值的抗体所对应的下标,这里也就是从最大的函数值所对应的抗体的下标开始进行克隆,AA用来记录每一次克隆的抗体在A中对应的序列位置,从而进行T中的克隆抗体存放。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%4.变异函数
%变异算子
    function T=Hypermutation(T,n,pMutate,xmax,xmin)
    M=rand(size(T,1),n) <= pMutate;
    M=T-2.*(T.*M)+M;
    k=round(log(10*(xmax-xmin)));
    k=1;
    T(:,k:n)=M(:,k:n);
    end

详解:
第一个M返回的是一个逻辑矩阵,pMutate表达的是高频率变异概率,即只有≤它时,就可进行变异(到这可能有点想不太明白,想想计算机的逻辑运算,就知道了),中间即为变异过程,不做过多赘述,到最后的连个矩阵进行对应赋值时,即将已经变异好的矩阵M的对应列赋给T中,M与T时同型矩阵(若不知道原因,请仔细看中间的过程,以及上一个函数的T是怎么来的,不要心急)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
接下来就是主函数,我会把详解放在主函数内部,因为文字限制,主函数的内容放在第二篇博客中。

    原文作者:还是暴力香
    原文地址: https://blog.csdn.net/weixin_45827640/article/details/104524149
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。