当前位置:   article > 正文

填坑:遗传算法代码(MATLAB)_适应度函数在遗传算法中哪一步应用,代码如何编写

适应度函数在遗传算法中哪一步应用,代码如何编写

上一篇博文写了遗传算法的主要思路,然后摸索了一下工具箱什么的,今天就把代码这个坑先填上。

顺序就按照上一篇博文里面写的步骤来:

问题描述:采用遗传算法和非线性规划的方法求解如下函数的极小值:

f(x) = -5sinx_{1}sinx_{2}sinx_{3}sinx_{4}sinx_{5}-sin5x_{1}5x_{2}5x_{3}5x_{4}5x_{5}+8

其中的变量都在0~0.9π之间。

该函数的最小值为-2,最小值位置为(π/2,π/2,π/2,π/2,π/2)。

1. 先是写适应度函数

个体的适应度是适应度函数值的倒数,上一篇博文中已经用红色字标注出来了,函数值越小的个体,适应度值越大,个体越优。

所以,代码如下:

  1. function y = fun(x)
  2. y = -5 * sin(x(1))*sin(x(2))*sin(x(3))*sin(x(4))*sin(x(5))-
  3. sin(5*x(1))*sin(5*x(2))*sin(5*x(3))*sin(5*x(4))*sin(5*x(5))+8;

其实所谓的适应度函数就是题目所要求的函数,适应度的话,就在下面的程序中取1/y。

2. 选择操作

方法选用的是轮盘赌(一个for循环,取随机),然后组成新的种群。

  1. function ret = select(individuals,sizepop)
  2. %individuals input :种群信息
  3. %sizepop input :种群规模
  4. %opts input :选择方法
  5. %ret input :重组的种群
  6. individuals.fitness = 1./(individuals.fitness);
  7. sunmfitness = sum (individuals.fitness); %求适应度的总和
  8. sumf = individuals.fitness./sumfitness; %求每个函数值适应度的占比
  9. index = []; %建立一个序列
  10. for i = 1:sizepop; %开始轮盘赌
  11. pick = rand; %这里把rand(0-1的随机数)理解成百分比比较好,作为一个概率的比较标准
  12. while pick == 0
  13. pick = rand;
  14. end
  15. for j = 1:sizepop
  16. pick = pick - sumf(j);
  17. if pick<0
  18. index = [index j]; %这里其实就是进行pick和sumf的对比,
  19. %如果pick比sumf小,就放入序列
  20. break;
  21. end
  22. end
  23. end
  24. individuals.chrom = individuals.chrom(index,:);
  25. individuals.fitness = individuals.fitness(index);
  26. ret = individuals;

轮盘赌的想法就是模拟自然选择,把值的大小换算成面积,用随机值来模拟指针,值越大,选中的概率也就越大。

这里可能不是很好理解,在知乎上有很多大佬解读过轮盘赌的方法,比我这个更详细,可以去观摩。毕竟我这个算法只针对这道题。

3. 交叉操作

函数就不解释了,贴个链接:https://blog.csdn.net/zhangqimo/article/details/105292845

  1. function ret = Cross(pcross,lenchrom,chrom,sizepop,bound)
  2. %pcross input :交叉概率
  3. %lenchrom input :%染色体长度
  4. %chrom input :%染色体群
  5. %sizepop input :种群规模
  6. %ret output :交叉后的染色体
  7. for i = 1 : sizepop
  8. pick = rand(1,2);
  9. while prod(pick) == 0 %prod函数是求矩阵元素的积
  10. pick = rand(1,2);
  11. end
  12. index = ceil(pick.*sizepop);
  13. pick = rand;
  14. while pick = 0;
  15. pick = rand;
  16. end
  17. if pick > pcross %如果大于交叉互换的概率就继续进行操作
  18. continue;
  19. end
  20. flag = 0;
  21. while flag == 0
  22. pick = rand;
  23. while pick == 0
  24. pick = rand;
  25. end
  26. pos = ceil(pick.*sum(lenchrom)); %随机选择交叉位置(选择第几个变量进行互换)
  27. pick = rand; %交叉开始
  28. v1 = chrom(index(1),pos);
  29. v2 = chrom(index(2),pos);
  30. chrom(index(1),pos) = pick * v2 + (1-pick) *v1;
  31. chrom(index(2),pos) = pick * v2 + (i-pick) *v2; %交叉结束
  32. flag1 = test(lenchrom,bound,chrom(index(1),:),fcode); %bound为自变量取值的约
  33. %束,该函数检验可行性
  34. flag2 = test(lenchrom,bound,chrom(index(2),:),fcode);
  35. if flag1 * flag2 ==0
  36. flag = 0;
  37. else flag = 1;
  38. end %如果都不行,则重新交叉
  39. end
  40. end
  41. ret = chrom;

4. 变异操作

是从种群中随机选择一个个体,按一定概率变异得到新个体。

  1. function ret = Mutation(pmutation,lenchrom,chrom,sizepoppop,bound)
  2. %pcross input :变异概率
  3. %lenchrom input :染色体长度
  4. %chrom input :染色体群
  5. %sizepop input :种群规模
  6. %pop input :当前种群的进化代数和最大的进化代数信息
  7. %ret output :变异后的染色体
  8. for i = 1 : sizepop
  9. pick = rand; %随机选
  10. while pick == 0
  11. pick = rand;
  12. end
  13. index = ceil(pick * sizepop)
  14. pick = rand;
  15. if pick > pmutation
  16. continue;
  17. end
  18. flag = 0;
  19. while flag == 0;
  20. pick = rand;
  21. while pick == 0;
  22. pick == 0;
  23. end
  24. pos = ceil(pick * sum(lenchrom));
  25. v = chrom(i,pos);
  26. v1 = v - bound(pos,1)
  27. v2 = bound(pos,2) - v;
  28. pick = rand;
  29. %从这里开始变异
  30. if pick>0.5
  31. delta = v2*(1-pick^((1-pop(1)/pop(2))^2);
  32. chrom(i,pos) = v + delta;
  33. else
  34. delta = v1*(1 - pick^((1-pop(1)/pop(2))^2));
  35. chrom(i,pos) = v-delta;
  36. end
  37. flag = test(lenchrom,bound,chrom(i,:),fcode);
  38. end
  39. end
  40. end
  41. ret = chrom;

5. 主程序

遗传算法基本上就是:随机初始化——计算种群适应度,找最优——选择——交叉——变异——寻优——判断结束条件。

具体代码为:

心态有点炸,码的代码被猫一脚踹没了。心情好了更。

更新:主程序

  1. clc
  2. clear
  3. maxgen = 100; %迭代次数
  4. sizepop = 10; %种群规模
  5. pcross = [0.5]; %交叉概率
  6. pmutation = [0.05]; %变异概率
  7. lenchrom = [1 1 1 1 1]; %变量长度
  8. bound = [0 0.5*pi;0 0.5*pi;0 0.5*pi;0 0.5*pi;0 0.5*pi];
  9. %初始化(个体)
  10. individuals = struct('fitness',zeros(1,sizepop),'chrom',[]);
  11. avgfitness = []; %平均适应度
  12. bestfitness = []; %最佳适应度
  13. bestchrom = []; %最佳染色体
  14. %初始化(种群)
  15. for i = 1 : sizepop
  16. individuals.chrom(i,:) = Code(lenchrom,bound);
  17. x = individuals.chrom(i,:);
  18. individuals.fitness(i) = fun(x);
  19. end
  20. %找最优
  21. [bestfitness bestindex] = min(individuals.fitness);
  22. bestchrom = individuals.chrom(bestindex,:);
  23. avgfitness = sum(individuals.fitness)/sizepop;
  24. trace=[]; %记录每一代数值
  25. %进化
  26. for i = 1 :maxgen
  27. %选择
  28. individuals = Select(individuals,sizepop);
  29. avgfitness = sum(individuals.fitness)/sizepop;
  30. %交叉
  31. individuals.chrom = Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);
  32. %变异
  33. individuals.chrom = Mutation(pmutation,lenchrom,individuals.chrom,sizepop,[i maxgen],bound);
  34. %以5代为界限,用求得数值作为初始值进行非线性寻优
  35. if mod(i,5) == 0
  36. individuals.chrom = nonlinear(individuals.chrom,sizepop);
  37. end
  38. %计算适应度
  39. for j = 1:sizepop
  40. x = individuals.chrom(j,:)
  41. individuals.fitness(j) = fun(x);
  42. end
  43. %求最优值所在位置
  44. [newbestfitness,newbestindex] = min(individuals.fitness);
  45. %与上一轮进化求得最优值对比,若更优,则替换
  46. if bestfitness > newbestfitness
  47. bestfitness = newbestfitness;
  48. bestchrom = individuals.chrom(newbestindex,:);
  49. end
  50. avgfitness = sum(individuals.fitness)/sizepop;
  51. trace = [trace;avgfitness bestfitness]; %每一代数据记录
  52. end

6. 非线性寻优

这里得调用工具箱里的fmincon

  1. function ret = nonlinear(chrom,sizepop)
  2. for i = 1 : sizepop
  3. x = fmincon(inline('-5 * sin(x(1))*sin(x(2))*sin(x(3))*sin(x(4))*sin(x(5))-
  4. sin(5*x(1))*sin(5*x(2))*sin(5*x(3))*sin(5*x(4))*sin(5*x(5))'),
  5. chrom(i,:)',[],[],[],[],[0 0 0 0 0].[2.874 2.874 2.874 2.874 2.874]);
  6. ret(i,:)=x';
  7. end

以上就是代码的全部了。

鬼知道我保存了几遍,不得不感叹一句,猫主子的脚是厉害,每次刚好踩到Alt+F4.

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

闽ICP备14008679号