遗传算法及其MATLAB实现

概述

    遗传算法是一种仿生算法,即通过优胜劣汰的方式逐步淘汰种群中较差的个体,留下较优的个体,并一代代传递下去,最终选出最优个体。遗传算法基本步骤如下:

  1. 编码。编码即给每个样本生成一个二进制码;
  2. 生成种群。种群生成可以通过随机数生成的二进制码来生成,也可以通过迭代过程中步骤7给出的编码来生成;
  3. 计算适应度和概率。通过适应度函数计算种群中每个样本的适应度,并计算下一步交叉过程中被选择概率;
  4. 交叉。从种群中按概率挑选两个样本,并从样本中各取一半编码,生成子代的编码;
  5. 变异。编码中任意一个位置数值按一定概率突变,从0变为1或者从1变为0;
  6. 回到步骤2,直到满足退出条件为止。

通常情况下,计算结束后还需要后处理,比如绘图和数据输出或者保存。

流程图

开始
编码
生成种群
计算适应度和概率
选择供体1和供体2
两个供体各拿出一半编码生成新编码
新编码数达到原始种群数
对每个新编码每个位置按一定概率突变
新编码替代原有编码
达到迭代次数
输出结果并绘图
结束

示例和代码

用遗传算法求以下函数极大值:

f(x)=sin(10πx)/x , x∈[1,2]
代码如下:
Npopulation=40;%%种群数
UpperLimit=2.0;%%区间上限
LowerLimit=1.0;%%区间下限
NInterval=1024;%%区间数
MaxTimes=100;%%迭代次数
PMutates=0.001;%%突变概率
Mxavalue=zeros(MaxTimes,1);%%极大值矩阵
Meanvalue=zeros(MaxTimes,1);%%平均值矩阵

%% 初始数据编码
Rands=(UpperLimit-LowerLimit)*rand(Npopulation,1);%%随机数组
MatrixTen=round(Rands/((UpperLimit-LowerLimit)/NInterval));%%十进制数组
MatrixTwo=zeros(Npopulation,10);%%二进制序列,十位二进制数来表示
Populations=zeros(Npopulation,1);%%种群
for i=1:Npopulation 
    k=0;
    Quotient=MatrixTen(i);%%商
    Remainder=0;%%余数
    while(Quotient>0)
        Remainder=mod( Quotient,2);
        Quotient=floor(Quotient/2);
        MatrixTwo(i,10-k)=Remainder;
        k=k+1;
    end      
end

%% 遗传迭代
Times=1;
while(Times<=MaxTimes)
    %% 生成种群
    for i=1:Npopulation
        Quotient=0;
        for j=1:10
            Quotient=2*Quotient+MatrixTwo(i,j);
        end
        MatrixTen(i)=Quotient;
        Populations(i)=MatrixTen(i)*((UpperLimit-LowerLimit)/NInterval)+LowerLimit;%%种群
    end
    
    %% 计算适应度
    Probability=sin(10*pi*Populations)./Populations;%%适应度矩阵
    Mxavalue(Times)=max(Probability);
    Meanvalue(Times)=sum(Probability)/Npopulation;
    Probability=Probability+ones(Npopulation,1);
    Probability=Probability/sum(Probability);%%筛选概率矩阵
    %%  交叉
    NewMatrixTwo=zeros(Npopulation,10);
    for i=1:Npopulation
        rand1=rand(1,1);
        rand2=rand(1,1);
        Index1=0;%%交叉供体1
        Index2=0;%%交叉供体2
        for j=Npopulation:-1:1
            if(rand1<sum(Probability(1:j)))
                Index1=j;
            end
            if(rand2<sum(Probability(1:j)))
                Index2=j;
            end
        end
        NewMatrixTwo(i,:)=[MatrixTwo(Index1,1:5) MatrixTwo(Index2,6:10)];%%供体1的前半序列+供体2后半序列,生成新样本
    end
    %%  变异
    for i=1:Npopulation
        for j=1:10
            rand1=rand(1,1);
            if(rand1<PMutates)
                NewMatrixTwo(i,j)=1-NewMatrixTwo(i,j);%%序列中每个位置的编码,按一定概率突变。
            end
        end
    end

    %% 迭代
    MatrixTwo=NewMatrixTwo;%%子代种群替代父代种群
    Times=Times+1;
end

%% 绘图
subplot(1,2,2)
plot(Mxavalue);
hold on;
plot(Meanvalue);
title('迭代情况')     %标题
subplot(1,2,1);
x=1:0.001:2;
y=sin(10*pi*x)./x;
plot(x,y);
title('函数值')     %标题

运行结果

    上述示例的运行结果如下图示(蓝色为种群内适应度最大值,橙色为平均值):
在这里插入图片描述

从图上可知,函数极大值为0.76,迭代40次后,种群内每个样本得到的适应度最大值和平均值都趋于稳定,但明显不是最优解。
    示例代码中,突变概率PMutates=0.001时,收敛比较快,但有时会陷入局部最优。当PMutates=0.04时,收敛慢一点,平均值偏离最大值多一点,但不会再陷入局部最优解。
在这里插入图片描述
从图上可知,函数极大值为0.9528,迭代60次后,种群内每个样本得到的适应度最大值和平均值都趋于稳定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饮血太岁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值