用MATLAB彻底搞懂遗传算法原理+代码讲解+具体例子

初始化种群

跟着例子来学习遗传算法,比如计算   y=xsin(3\pix)  的最优值,先看代码

​
clear;clc;close all;

%%遗传参数设置
NUMPOP=100;%初始种群大小
irange_l=-1; %问题解区间
irange_r=2;
LENGTH=22; %二进制编码长度
ITERATION = 10000;%迭代次数
CROSSOVERRATE = 0.7;%杂交率
SELECTRATE = 0.5;%选择率
VARIATIONRATE = 0.001;%变异率

​

在这里我们要对遗传参数的参数进行设置,初始种群的的大小可以改变,100、1000、2000等,问题的解区间就是函数对应的自变量的取值范围,二进制编码的长度也可以变换,迭代次数、杂交率、选择率、变异率都给定数值。

%初始化种群
pop=m_InitPop(NUMPOP,irange_l,irange_r);
pop_save=pop;
%绘制初始种群分布
x=linspace(-1,2,1000);
y=m_Fx(x);
plot(x,y);
hold on
for i=1:size(pop,2)
    plot(pop(i),m_Fx(pop(i)),'ro');
end
hold off
title('初始种群');

接下来就是初始化种群,对于m_InitPop和m_Fx我们来看看具体的函数形式:

function pop=m_InitPop(numpop,irange_l,irange_r)
%% 初始化种群
%  输入:numpop--种群大小;
%       [irange_l,irange_r]--初始种群所在的区间
pop=[];
for i=1:numpop
    pop(:,i)=irange_l+(irange_r-irange_l)*rand;
end
end
    

 pop(:,i)=irange_l+(irange_r-irange_l)*rand;这个我们在自变量的区间产生初始的种群,这个种群也可以设置自己的数据。

function y=m_Fx(x)
%% 要求解的函数
    y=x.*sin(3*pi.*x);
end

初始种群的图像为:

开始迭代

我们的目的是根据遗传算法求解   y=xsin(3\pix)  的最优值。

%开始迭代
for time=1:ITERATION
    %计算初始种群的适应度
    fitness=m_Fitness(pop);
    %选择
    pop=m_Select(fitness,pop,SELECTRATE);
    %编码
    binpop=m_Coding(pop,LENGTH,irange_l);
    %交叉
    kidsPop = crossover(binpop,NUMPOP,CROSSOVERRATE);
    %变异
    kidsPop = Variation(kidsPop,VARIATIONRATE);
    %解码
    kidsPop=m_Incoding(kidsPop,irange_l);
    %更新种群
    pop=[pop kidsPop];
end

然后开始迭代,看下迭代图

 适应度

我们看怎么计算种群的适应度,选择,交叉,变异,分别以子函数讲解

    %计算初始种群的适应度
    fitness=m_Fitness(pop);

我们根据m_Fitness函数计算种群的适应度:

function fitness=m_Fitness(pop)
%% Fitness Function
%y=xsin(3x)在[-1,2]上,最大值也不会超过2
%所以计算函数值到2的距离,距离最小时,即为最优解
%适应度函数为1/距离
for n=1:size(pop,2)
    fitness(n)=1/(2-m_Fx(pop(:,n)));
end

end

 输入初始种群pop ,输出每个个体对应的适应度,fitness(n)=1/(2-m_Fx(pop(:,n)));这里可以加一个很小的数值比如esp。防止分母出现0。

选择

    %选择
    pop=m_Select(fitness,pop,SELECTRATE);

根据SELECTRATE = 0.5的选择率,生成初始种群解集后,首先根据选择率,比如选出50%个体进行交叉、变异过程。特别需要注意的是不能把选择率(也叫代沟)设为100%,虽然每次循环都有最优值记录,这样也能更快得到最优值,但是违背了算法原理。

function parentPop=m_Select(matrixFitness,pop,SELECTRATE)
%% 选择
% 输入:matrixFitness--适应度矩阵
%      pop--初始种群
%      SELECTRATE--选择率

sumFitness=sum(matrixFitness(:));%计算所有种群的适应度

accP=cumsum(matrixFitness/sumFitness);%累积概率
%轮盘赌选择算法
for n=1:round(SELECTRATE*size(pop,2))
    matrix=find(accP>rand); %找到比随机数大的累积概率
    if isempty(matrix)
        continue
    end
    parentPop(:,n)=pop(:,matrix(1));%将首个比随机数大的累积概率的位置的个体遗传下去
end
end

在对个体的适应度进行评价的基础上,通过选择操作把优化的个体直接遗传到下一代,或通过配对交叉产生新的个体再遗传到下一代。设群体规模为size(pop,2),个体被选中的概率为accP。

编码

    %编码
    binpop=m_Coding(pop,LENGTH,irange_l);

主要作用是把十进制转换成二进制

function binPop=m_Coding(pop,pop_length,irange_l)
%% 二进制编码(生成染色体)
% 输入:pop--种群
%      pop_length--编码长度
pop=round((pop-irange_l)*10^6);
for n=1:size(pop,2) %列循环
    for k=1:size(pop,1) %行循环
        dec2binpop{k,n}=dec2bin(pop(k,n));%dec2bin的输出为字符向量;
                                          %dec2binpop是cell数组
        lengthpop=length(dec2binpop{k,n});
        for s=1:pop_length-lengthpop %补零
            dec2binpop{k,n}=['0' dec2binpop{k,n}];
        end
    end
    binPop{n}=dec2binpop{k,n};   %取dec2binpop的第k行
end

    

交叉

转换成二进制之后进行交叉:

    %交叉
    kidsPop = crossover(binpop,NUMPOP,CROSSOVERRATE);
%% 子函数
%
%题  目:Crossover
%
%%
%输   入:
%           parentsPop       上一代种群
%           NUMPOP           种群大小
%           CROSSOVERRATE    交叉率
%输   出:
%           kidsPop          下一代种群
%
%% 
function kidsPop = Crossover(parentsPop,NUMPOP,CROSSOVERRATE)
kidsPop = {[]};n = 1;
while size(kidsPop,2)<NUMPOP-size(parentsPop,2)
    %选择出交叉的父代和母代
    father = parentsPop{1,ceil((size(parentsPop,2)-1)*rand)+1};
    mother = parentsPop{1,ceil((size(parentsPop,2)-1)*rand)+1};
    %随机产生交叉位置
    crossLocation = ceil((length(father)-1)*rand)+1;
    %如果随即数比交叉率低,就杂交
    if rand<CROSSOVERRATE
        father(1,crossLocation:end) = mother(1,crossLocation:end);
        kidsPop{n} = father;
        n = n+1;
    end
end

变异

这里就不过多讲解,代码可以直接用即可。接下是变异

    %变异
    kidsPop = Variation(kidsPop,VARIATIONRATE);
%% 子函数
%
%题  目:Variation
%
%
%输   入:
%           pop              种群
%           VARIATIONRATE    变异率
%输   出:
%           pop              变异后的种群
%% 
function kidsPop = Variation(kidsPop,VARIATIONRATE)
for n=1:size(kidsPop,2)
    if rand<VARIATIONRATE
        temp = kidsPop{n};
        %找到变异位置
        location = ceil(length(temp)*rand);
        temp = [temp(1:location-1) num2str(~temp(location))...
            temp(location+1:end)];
       kidsPop{n} = temp;
    end
end

解码

变异之后进行解码,也就是二进制转换为十进制。

    %解码
    kidsPop=m_Incoding(kidsPop,irange_l);
function pop=m_Incoding(binPop,irange_l)
%% 解码
popNum=1;
popNum = 1;%染色体包含的参数数量
for n=1:size(binPop,2)
    Matrix = binPop{1,n};
    for num=1:popNum
        pop(num,n) = bin2dec(Matrix);
    end
end
pop = pop./10^6+irange_l;

更新种群

然后更新种群,

    %更新种群
    pop=[pop kidsPop];

最后画出遗传算法迭代后的终止种群:

figure
x=linspace(-1,2,1000);
y=m_Fx(x);
plot(x,y);
hold on
for i=1:size(pop,2)
    plot(pop(i),m_Fx(pop(i)),'ro');
end
hold off
title('终止种群');

终止种群

可以看到图像的最优解:

 我们也可以输出最优解和最大适应度:

disp(['最优解:' num2str(max(m_Fx(pop)))]);
disp(['最大适应度:' num2str(max(m_Fitness(pop)))]);   

输出:

最优解:1.491
最大适应度:1.9645

这个是针对一维的函数进行寻优,二维的函数的寻优以后的文章会继续讲解。

  • 27
    点赞
  • 205
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
下面是一个用MATLAB实现遗传算法的简单示例代码,用于解决共享单车调度问题: ```matlab % 参数设置 populationSize = 50; % 种群大小 numGenes = 100; % 基因长度 maxGenerations = 100; % 最大迭代次数 mutationRate = 0.01; % 变异率 % 初始化种群 population = randi([0, 9], populationSize, numGenes); % 迭代计算 for generation = 1:maxGenerations % 评估适应度 fitness = evaluateFitness(population); % 选择操作 selectedPopulation = selection(population, fitness); % 交叉操作 crossedPopulation = crossover(selectedPopulation); % 变异操作 mutatedPopulation = mutate(crossedPopulation, mutationRate); % 更新种群 population = mutatedPopulation; end % 输出结果 bestIndividual = find(fitness == max(fitness)); bestSolution = population(bestIndividual, :); disp('Best solution:'); disp(bestSolution); % 适应度评估函数 function fitness = evaluateFitness(population) % 根据问题的具体定义,计算每个个体的适应度值 % fitness = ... end % 选择操作函数 function selectedPopulation = selection(population, fitness) % 根据适应度值,利用轮盘赌选择或锦标赛选择等方法选择个体 % selectedPopulation = ... end % 交叉操作函数 function crossedPopulation = crossover(selectedPopulation) % 根据选择的个体,进行交叉操作,生成新的个体 % crossedPopulation = ... end % 变异操作函数 function mutatedPopulation = mutate(crossedPopulation, mutationRate) % 根据变异率,对个体进行变异操作 % mutatedPopulation = ... end ``` 这只是一个简单的示例代码具体的实现需要根据问题的具体定义进行相应的编写。在代码中,需要根据问题定义编写适应度评估函数、选择操作函数、交叉操作函数和变异操作函数,并根据实际情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值