当前位置:   article > 正文

matlab新手快速上手4(人工蜂群算法)

matlab新手快速上手4(人工蜂群算法)

        本文用经典人工蜂群算法框架模板,对matlab新手友好,快速上手看懂matlab代码,快速应用实践,源代码在文末给出。

基本原理:

        人工蜂群算法(Artificial Bee Colony Algorithm,ABC)是一种启发式算法,受到蜜蜂觅食行为的启发而提出的一种优化算法。它模拟了蜜蜂在寻找花朵采集花粉的过程中的行为,通过不断地调整蜜蜂的搜索策略来寻找最优解。

        人工蜂群算法的基本思想是将候选解空间中的点看作花朵,并将搜索过程看作蜜蜂在不同花朵之间搜索的过程。在算法的执行过程中,蜜蜂分为三类:雇佣蜜蜂、观察蜜蜂和侦查蜜蜂。

  1. 雇佣蜜蜂:雇佣蜜蜂负责在当前位置附近的解空间中搜索,并评估候选解的质量。它们根据花粉量的多少(即解的适应度)来选择候选解,并将信息传递给其他蜜蜂。

  2. 观察蜜蜂:观察蜜蜂根据雇佣蜜蜂的信息进行选择,并尝试在当前位置附近进行搜索。它们通过观察雇佣蜜蜂找到的解来确定自己的搜索方向。

  3. 侦查蜜蜂:侦查蜜蜂负责在整个解空间中进行全局搜索,以寻找可能的新解。它们以一定的概率选择随机位置进行探索,并在搜索过程中更新最优解。

        通过不断地雇佣、观察和侦查过程,人工蜂群算法能够在解空间中搜索到较优解。该算法具有较好的全局搜索能力和较快的收敛速度,适用于解决各种复杂的优化问题,如函数优化、参数优化等。

本文编程思想:

本编程将观察蜂于侦察蜂统一,称为侦察蜂,将雇佣蜜蜂称为采蜜蜂

编程思想为:采蜜蜂进行随机采蜜,侦察蜂根据采蜜蜂的适应度大小进行跟随,适应度越高证明蜜源越好,越接近正确解,侦察蜂在采蜜蜂周围进行随机侦察,侦察到更好的蜜源后(也就是适应度越好的个体),那么将采蜜蜂更新到此位置,进而吸引更多的侦察蜂侦察,实现快速收敛。

开始编程:

参数与子函数定义:

  1. %---------------------------------- 程序正文 -------------------------------
  2. function ABC
  3. %---------------------------------- 参数设置 -------------------------------
  4. NP1=20; %种群规模
  5. NP2=20; %种群规模
  6. D=10; %变量个数
  7. MinX=-D^2; %范围下限
  8. MaxX=D^2; %范围上限
  9. Limit=50; %次数阈值
  10. Search=zeros(1,NP1); %采蜜搜次
  11. Error=1.0; %限定精度
  12. Max_N=1000; %限定代数
  13. flagc=[0,Max_N]; %收敛标志
  14. %---------------------- 粒子位置初始化 ----------------------
  15. for i=1:1:D
  16. X(:,i)=MinX+(MaxX-MinX)*rand(NP1+NP2,1);
  17. end
  18. %----------------------- 计算函数值 -------------------------
  19. F=fun(X);
  20. %---------------------------- 子函数1:目标函数 ----------------------------
  21. function F=fun(X)
  22. [M,N]=size(X);
  23. for i=1:1:M
  24. for j=1:1:N
  25. x(j)=X(i,j);
  26. end
  27. F(i)=N*(N+4)*(N-1)/6+sum((x-1).^2)-sum(x(2:N).*x(1:N-1));
  28. end
  29. %----------------------- 建采蜜蜂群 -------------------------
  30. [Bestf,Indexf]=sort(F,2);
  31. for i=1:1:NP1
  32. X1(i,:)=X(Indexf(i),:);
  33. F1(i)=F(Indexf(i));
  34. end
  35. CX1=X1;CF1=F1;

 参数定义:

NP1和NP2分别为采蜜蜂和侦察蜂。D为变量个数

X矩阵为D列,NP1+NP2行的矩阵,也就是40行,10列的矩阵。每一行代表一个蜜蜂个体,元素范围为(-100,100)

子函数定义

fun(x)为子函数,子函数中,M,N分别代表为X的行数和列数,这里的子函数也是目标函数,具体的数学函数如下,最终算法目标也就是求这个数学函数值小于1的解。N \left( N + 4 \right) \left( \frac{N - 1}{6} \right) + \sum_{i=1}^{N} \left( x_i - 1 \right)^2-\sum_{i=1}^{N-1} x_i x_{i+1}

建立采蜜蜂群:

        如上述代码所示,sort(F,2)表示按F的第二维度进行排序,也就是按列排序,也就是对F的每一行进行排序,由于F只有1行,那么也可以去掉这个参数,F一行的第i个参数也就是第i个蜜蜂的适应度,这里的排序就相当于按照每个蜜蜂的适应度进行排序,然后根据for循环挑选出NP1个蜜蜂作为采蜜蜂,CX1,CF1表示复制一份值。

开始主循环:

  1. %--------------------- 程序主循环开始 ----------------------
  2. for gen=1:1:Max_N
  3. time(gen)=gen;
  4. %----------------- 作采蜜蜂群搜索 ----------------------
  5. for i=1:1:NP1
  6. flag1=ceil(rand*NP1);
  7. while(flag1==i)
  8. flag1=ceil(rand*NP1);
  9. end
  10. flag2=ceil(rand*D);
  11. X1(i,flag2)=X1(i,flag2)+rands(1)*(X1(i,flag2)-X1(flag1,flag2));
  12. end
  13. %----------------- 计算采蜜函数值 ----------------------
  14. F1=fun(X1);
  15. %----------------- 采蜜蜂贪婪搜索 ----------------------
  16. for i=1:1:NP1
  17. if F1(i)>=CF1(i)
  18. Search(i)=Search(i)+1;
  19. X1(i,:)=CX1(i,:);
  20. F1(i)=CF1(i);
  21. else
  22. Search(i)=0;
  23. end
  24. end
  25. %----------------- 跟踪蜂选择概率 ----------------------
  26. temp=(1./(1+F1))/sum(1./(1+F1));
  27. %P=cumsum((1./(1+F1))/sum(1./(1+F1)));
  28. for i=1:1:NP1
  29. P(i)=sum(temp(1:i));
  30. end
  31. %----------------- 跟踪蜂蜜源搜索 ----------------------
  32. for i=1:1:NP2
  33. %------------- 跟踪蜂选择蜜源 ----------------------
  34. rnd=rand;
  35. for flag=1:1:NP1
  36. if rnd<P(flag)
  37. Genzong(i)=flag;
  38. break;
  39. end
  40. end
  41. X2(i,:)=X1(flag,:);
  42. %------------- 跟踪蜂搜索蜜源 ----------------------
  43. flag1=ceil(rand*NP1);
  44. while(flag1==flag)
  45. flag1=ceil(rand*NP1);
  46. end
  47. flag2=ceil(rand*D);
  48. X2(i,flag2)=X1(flag,flag2)+rands(1)*(X1(flag,flag2)-X1(flag1,flag2));
  49. end
  50. %----------------- 计算跟踪函数值 ----------------------
  51. F2=fun(X2);
  52. %----------------- 跟踪蜂蜜源计数 ----------------------
  53. for i=1:1:NP2
  54. if F2(i)>=F1(Genzong(i))
  55. Search(Genzong(i))=Search(Genzong(i))+1;
  56. else
  57. Search(Genzong(i))=0;
  58. X1(Genzong(i),:)=X2(i,:);
  59. F1(Genzong(i))=F2(i);
  60. end
  61. end
  62. %----------------- 检验采蜜蜂蜜源 ----------------------
  63. for i=1:1:NP1
  64. if Search(i)>Limit
  65. Search(i)=0;
  66. if i~=Indexf(1)
  67. X1(i,:)=MinX+(MaxX-MinX)*rand(1,D);
  68. F1=fun(X1);
  69. end
  70. end
  71. end
  72. %----------------- 迭代更新 ---------------------------
  73. CF1=F1;CX1=X1;
  74. %----------------- 求最优解 ---------------------------
  75. [Bestf,Indexf]=sort(F1,2); %对NP1个函数值排序
  76. gBestf=Bestf(1);
  77. gX=X1(Indexf(1),:);
  78. %----------------------------- 记录结果 --------------------------------
  79. result(gen)=gBestf;
  80. if mod(gen,10)==0
  81. disp(sprintf('代数:%d -------- 结果:%f',gen,gBestf));
  82. plot(time,result,'r');axis([1,Max_N,0,10000]);
  83. xlabel('迭代步数');ylabel('优化结果');drawnow;pause(0.1);
  84. end
  85. if gBestf<Error break;end
  86. end
  87. %disp(' ');
  88. disp(sprintf('迭代步数:%d -------- 优化结果:%f',gen,gBestf));

外层循环:

最外层循环表示迭代次数,表示进行Max_N次迭代,time记录迭代到第几次,做采蜜蜂群搜索代码中,ceil表示向上取整,表示[1,NP1]范围的随机整数。while循环内表示此整数不能等于当前迭代次数,也就是防止下一段代码中X1的参数未被修改。

F1 = fun(X1)表示计算采蜜蜂群的适应度并存储在F1矩阵中。

采蜜蜂贪婪搜索:

当更新后F1的适应度比之前差,那么把对应的个体记录到search中,并把没更新之前的值赋值给X1和F1。

跟踪蜂选择概率:

这个选择方法是轮盘赌选择,具体原理和流程见主页遗传算法中。这里Genzong数组里记录了每个跟踪蜂跟踪第几个采蜜蜂,X2矩阵中存储跟踪蜂选择的采蜜蜂个体。蜜源越大也就是适应度越好,跟踪蜂越多。

跟踪蜂搜索蜜源:

flag1表示[1,NP1]的随机值,与上面的采蜜蜂搜索蜜源相似,做随机搜索,随机改变10个变量中的一个,循环结束使用F2进行跟踪蜂适应度计算。

跟踪蜜源计数:

这个for循环中,遍历每个跟踪蜂的适应度,如果跟踪蜂的适应度比它跟踪的采蜜蜂的适应度差,那么将对应采蜜蜂的search中的值+1,也就是search越大,这个采蜜蜂的适应度越好,如果跟踪蜂的适应度好,将跟踪蜂的值赋值给它跟踪的采蜜蜂,并更新采蜜蜂的对应适应度的值。

检验采蜜蜂蜜源:

这个代码是防止陷入局部最优解的过程,当search超过limit时,表示此采蜜蜂周围没有比他更好的蜜源了,将search设置为0,如果这个采蜜蜂还不是全局最优解,那么将这个采蜜蜂重新分配一个随机蜜源,这就是避免陷入局部最优的过程,如果这个蜜蜂是全局最优解,那么不分配随机蜜源,继续让跟踪蜂寻找。

迭代更新:

迭代更新的CF1记录上一次的采蜜蜂的适应度,CX1记录上一次采蜜蜂的值,计算最优解将适应度排序,寻找最佳的采蜜蜂。

源代码:

  1. %---------------------------------- 程序说明 -------------------------------
  2. % 该程序实现了基本蜂群算法
  3. %---------------------------------- 程序正文 -------------------------------
  4. function ABC
  5. %---------------------------------- 参数设置 -------------------------------
  6. NP1=20; %种群规模
  7. NP2=20; %种群规模
  8. D=10; %变量个数
  9. MinX=-D^2; %范围下限
  10. MaxX=D^2; %范围上限
  11. Limit=50; %次数阈值
  12. Search=zeros(1,NP1); %采蜜搜次
  13. Error=1.0; %限定精度
  14. Max_N=1000; %限定代数
  15. flagc=[0,Max_N]; %收敛标志
  16. %---------------------- 粒子位置初始化 ----------------------
  17. for i=1:1:D
  18. X(:,i)=MinX+(MaxX-MinX)*rand(NP1+NP2,1);
  19. end
  20. %X=MinX+(MaxX-MinX)*rand(NP1+NP2,D);
  21. disp(X);
  22. %----------------------- 计算函数值 -------------------------
  23. F=fun(X);
  24. %----------------------- 建采蜜蜂群 -------------------------
  25. [Bestf,Indexf]=sort(F,2);
  26. for i=1:1:NP1
  27. X1(i,:)=X(Indexf(i),:);
  28. F1(i)=F(Indexf(i));
  29. end
  30. CX1=X1;CF1=F1;
  31. %--------------------- 程序主循环开始 ----------------------
  32. for gen=1:1:Max_N
  33. time(gen)=gen;
  34. %----------------- 作采蜜蜂群搜索 ----------------------
  35. for i=1:1:NP1
  36. flag1=ceil(rand*NP1);
  37. while(flag1==i)
  38. flag1=ceil(rand*NP1);
  39. end
  40. flag2=ceil(rand*D);
  41. X1(i,flag2)=X1(i,flag2)+rands(1)*(X1(i,flag2)-X1(flag1,flag2));
  42. end
  43. %----------------- 计算采蜜函数值 ----------------------
  44. F1=fun(X1);
  45. %----------------- 采蜜蜂贪婪搜索 ----------------------
  46. for i=1:1:NP1
  47. if F1(i)>=CF1(i)
  48. Search(i)=Search(i)+1;
  49. X1(i,:)=CX1(i,:);
  50. F1(i)=CF1(i);
  51. else
  52. Search(i)=0;
  53. end
  54. end
  55. %----------------- 跟踪蜂选择概率 ----------------------
  56. temp=(1./(2+F1))/sum(1./(2+F1));
  57. %P=cumsum((1./(1+F1))/sum(1./(1+F1)));
  58. for i=1:1:NP1
  59. P(i)=sum(temp(1:i));
  60. end
  61. %----------------- 跟踪蜂蜜源搜索 ----------------------
  62. for i=1:1:NP2
  63. %------------- 跟踪蜂选择蜜源 ----------------------
  64. rnd=rand;
  65. for flag=1:1:NP1
  66. if rnd<P(flag)
  67. Genzong(i)=flag;
  68. break;
  69. end
  70. end
  71. X2(i,:)=X1(flag,:);
  72. %------------- 跟踪蜂搜索蜜源 ----------------------
  73. flag1=ceil(rand*NP1);
  74. while(flag1==flag)
  75. flag1=ceil(rand*NP1);
  76. end
  77. flag2=ceil(rand*D);
  78. X2(i,flag2)=X1(flag,flag2)+rands(1)*(X1(flag,flag2)-X1(flag1,flag2));
  79. end
  80. %----------------- 计算跟踪函数值 ----------------------
  81. F2=fun(X2);
  82. %----------------- 跟踪蜂蜜源计数 ----------------------
  83. for i=1:1:NP2
  84. if F2(i)>=F1(Genzong(i))
  85. Search(Genzong(i))=Search(Genzong(i))+1;
  86. else
  87. Search(Genzong(i))=0;
  88. X1(Genzong(i),:)=X2(i,:);
  89. F1(Genzong(i))=F2(i);
  90. end
  91. end
  92. %----------------- 检验采蜜蜂蜜源 ----------------------
  93. for i=1:1:NP1
  94. if Search(i)>Limit
  95. Search(i)=0;
  96. if i~=Indexf(1)
  97. X1(i,:)=MinX+(MaxX-MinX)*rand(1,D);
  98. disp("reSearch");
  99. F1=fun(X1);
  100. end
  101. end
  102. end
  103. %----------------- 迭代更新 ---------------------------
  104. CF1=F1;CX1=X1;
  105. %----------------- 求最优解 ---------------------------
  106. [Bestf,Indexf]=sort(F1,2); %对NP1个函数值排序
  107. gBestf=Bestf(1);
  108. gX=X1(Indexf(1),:);
  109. %----------------------------- 记录结果 --------------------------------
  110. result(gen)=gBestf;
  111. if mod(gen,10)==0
  112. disp(sprintf('代数:%d -------- 结果:%f',gen,gBestf));
  113. plot(time,result,'r');axis([1,Max_N,0,10000]);
  114. xlabel('迭代步数');ylabel('优化结果');drawnow;pause(0.1);
  115. end
  116. if gBestf<Error break;end
  117. end
  118. %disp(' ');
  119. disp(sprintf('迭代步数:%d -------- 优化结果:%f',gen,gBestf));
  120. disp(X1(Indexf(1),:));
  121. %---------------------------- 子函数1:目标函数 ----------------------------
  122. function F=fun(X)
  123. [M,N]=size(X);
  124. for i=1:1:M
  125. for j=1:1:N
  126. x(j)=X(i,j);
  127. end
  128. F(i)=N*(N+4)*(N-1)/6+sum((x-1).^2)-sum(x(2:N).*x(1:N-1));
  129. end

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

闽ICP备14008679号