当前位置:   article > 正文

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

遗传算法matlab程序代码

初始化种群

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

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

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

  1. %初始化种群
  2. pop=m_InitPop(NUMPOP,irange_l,irange_r);
  3. pop_save=pop;
  4. %绘制初始种群分布
  5. x=linspace(-1,2,1000);
  6. y=m_Fx(x);
  7. plot(x,y);
  8. hold on
  9. for i=1:size(pop,2)
  10. plot(pop(i),m_Fx(pop(i)),'ro');
  11. end
  12. hold off
  13. title('初始种群');

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

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

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

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

初始种群的图像为:

开始迭代

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

  1. %开始迭代
  2. for time=1:ITERATION
  3. %计算初始种群的适应度
  4. fitness=m_Fitness(pop);
  5. %选择
  6. pop=m_Select(fitness,pop,SELECTRATE);
  7. %编码
  8. binpop=m_Coding(pop,LENGTH,irange_l);
  9. %交叉
  10. kidsPop = crossover(binpop,NUMPOP,CROSSOVERRATE);
  11. %变异
  12. kidsPop = Variation(kidsPop,VARIATIONRATE);
  13. %解码
  14. kidsPop=m_Incoding(kidsPop,irange_l);
  15. %更新种群
  16. pop=[pop kidsPop];
  17. end

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

 适应度

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

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

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

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

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

选择

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

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

  1. function parentPop=m_Select(matrixFitness,pop,SELECTRATE)
  2. %% 选择
  3. % 输入:matrixFitness--适应度矩阵
  4. % pop--初始种群
  5. % SELECTRATE--选择率
  6. sumFitness=sum(matrixFitness(:));%计算所有种群的适应度
  7. accP=cumsum(matrixFitness/sumFitness);%累积概率
  8. %轮盘赌选择算法
  9. for n=1:round(SELECTRATE*size(pop,2))
  10. matrix=find(accP>rand); %找到比随机数大的累积概率
  11. if isempty(matrix)
  12. continue
  13. end
  14. parentPop(:,n)=pop(:,matrix(1));%将首个比随机数大的累积概率的位置的个体遗传下去
  15. end
  16. end

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

编码

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

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

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

交叉

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

  1. %交叉
  2. kidsPop = crossover(binpop,NUMPOP,CROSSOVERRATE);
  1. %% 子函数
  2. %
  3. %题 目:Crossover
  4. %
  5. %%
  6. %输 入:
  7. % parentsPop 上一代种群
  8. % NUMPOP 种群大小
  9. % CROSSOVERRATE 交叉率
  10. %输 出:
  11. % kidsPop 下一代种群
  12. %
  13. %%
  14. function kidsPop = Crossover(parentsPop,NUMPOP,CROSSOVERRATE)
  15. kidsPop = {[]};n = 1;
  16. while size(kidsPop,2)<NUMPOP-size(parentsPop,2)
  17. %选择出交叉的父代和母代
  18. father = parentsPop{1,ceil((size(parentsPop,2)-1)*rand)+1};
  19. mother = parentsPop{1,ceil((size(parentsPop,2)-1)*rand)+1};
  20. %随机产生交叉位置
  21. crossLocation = ceil((length(father)-1)*rand)+1;
  22. %如果随即数比交叉率低,就杂交
  23. if rand<CROSSOVERRATE
  24. father(1,crossLocation:end) = mother(1,crossLocation:end);
  25. kidsPop{n} = father;
  26. n = n+1;
  27. end
  28. end

变异

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

  1. %变异
  2. kidsPop = Variation(kidsPop,VARIATIONRATE);
  1. %% 子函数
  2. %
  3. %题 目:Variation
  4. %
  5. %
  6. %输 入:
  7. % pop 种群
  8. % VARIATIONRATE 变异率
  9. %输 出:
  10. % pop 变异后的种群
  11. %%
  12. function kidsPop = Variation(kidsPop,VARIATIONRATE)
  13. for n=1:size(kidsPop,2)
  14. if rand<VARIATIONRATE
  15. temp = kidsPop{n};
  16. %找到变异位置
  17. location = ceil(length(temp)*rand);
  18. temp = [temp(1:location-1) num2str(~temp(location))...
  19. temp(location+1:end)];
  20. kidsPop{n} = temp;
  21. end
  22. end

解码

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

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

更新种群

然后更新种群,

  1. %更新种群
  2. pop=[pop kidsPop];

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

  1. figure
  2. x=linspace(-1,2,1000);
  3. y=m_Fx(x);
  4. plot(x,y);
  5. hold on
  6. for i=1:size(pop,2)
  7. plot(pop(i),m_Fx(pop(i)),'ro');
  8. end
  9. hold off
  10. title('终止种群');

终止种群

可以看到图像的最优解:

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

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

输出:

  1. 最优解:1.491
  2. 最大适应度:1.9645

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/53245
推荐阅读
相关标签
  

闽ICP备14008679号