文章目录

  • 前言
  • 问题背景
  • 遗传算法
  • Matlab实例代码
  • 附录
    • 君主方案
    • 遗传算法解决旅行商问题

前言

本文旨在使用智能优化算法及其MATLAB实例(第2版) 一书中的例子,来透彻理解遗传算法的本质。

问题背景

目标: 求解最大化函数 f(x)=x+10sin⁡(5x)+7cos⁡(4x)f(x)=x+10 \sin (5 x)+7 \cos (4 x)f(x)=x+10sin(5x)+7cos(4x) 的 xxx, 其中x∈[0,10]x\in[0,10]x∈[0,10]。

这个问题可以直接通过导数为0求解,但我们选择以此作为遗传算法的简单示例。

遗传算法的本质是优化后的穷搜算法事实上几乎所有此类启发式算法,本质都是用不同方式尽可能规避无效搜索后的优化版穷搜算法

对于这个优化问题,变量xxx为连续变量,可行解有无穷个, 这样甚至连穷搜都不可行。 因此,我们首先要将可行域离散化,使其可行解个数为有限个方能进行搜索。 很简单的一种办法就是遗传算法中所谓的染色体编码: 定义一个编码XXX是一个L×1L\times 1L×1的 0−10-10−1向量, 例如:
X=[0,1,1,0,⋯,1]X=[0, 1, 1, 0, \cdots, 1]X=[0,1,1,0,⋯,1]
那么很显然, 共有2L2^L2L个不同的XXX。 我们可以认为每个XXX都代表一个原问题中的可行xxx, 具体而言,我们可以定义函数:
g(X)=0+m×102L,m=∑i=1L2i−1Xig(X) = 0 + \frac{m\times 10} {2^L}, m = \sum_{i=1}^{L}2^{i-1}X_ig(X)=0+2Lm×10​,m=i=1∑L​2i−1Xi​
那么 g(X)g(X)g(X)就代表了[0,10][0, 10][0,10]之间的一个可行的xxx。

通过均匀量化的方式,我们将无限的可行空间缩小成一个有限的可行空间。 当LLL足够大时,解的精度几乎不会受损。 而这一简单的思想在遗传算法中就被称作听起来更高大上一些的染色体编码。

这样一来,使用穷搜算法的话,就是无脑遍历2L2^L2L个解,选择最好的那个。 接下来介绍遗传算法的搜索方式,以期在搜索数远少于2L2^L2L次的情况下,搜到很好的解。

遗传算法

  1. 首先, 获取初始种群, 也就是先随机要搜索的NPN_PNP​个初始可行解XXX。
  2. 对初始种群进行评估: 计算这NPN_PNP​个解对应的目标函数大小。 就本例而言,基于XXX换算为xxx后再计算f(x)f(x)f(x)的值,记录对应最大f(x)f(x)f(x)和最小f(x)f(x)f(x)值的个体, 也即XXX。
  3. 计算适应度: 越优秀的个体,要有越大的概率遗传到下一代。我们以适应度来量化刻画优秀:F=f(x)−fminfmax−fminF=\frac{f(x)-f_{min}}{f_{max}-f_{min}}F=fmax​−fmin​f(x)−fmin​​
    此处fminf_{min}fmin​和fmaxf_{max}fmax​代表了第二步中计算得到的当代种群的最优和最差解。 经这一步操作,我们可以得到一个归一化的适应度结果FFF。 显然,F∈[0,1]F\in[0,1]F∈[0,1], 且是f(x)f(x)f(x)的单调递增函数, 也符合了我们优胜劣汰的遗传思想。
  4. 复制操作: 从这一步开始我们准备基于初始种群生成下一代的种群了。 首先,我们要基于适应度进行优胜劣汰: 更好的个体将有更大的概率进行复制,遗传到下一代种群。 我们采用本例中所使用的所谓轮盘赌的选择准则:
    pi=Fi∑Fip_i=\frac{F_i}{\sum F_i} pi​=∑Fi​Fi​​
    这里pip_ipi​和FiF_iFi​分别代表第iii个个体被选中进行复制的概率和其对应的适应度。 显然,FiF_iFi​越大,被复制的概率越高。基于此,我们复制出下一代的NpN_pNp​个可行解XXX。
    (可以看到,表现最差的那个个体已不可能被复制,因为其FiF_iFi​为0。)
  5. 交叉操作: 这个操作就是完全启发自遗传的思想了——父母结合产生新的下一代。 具体而言, 将我们刚刚复制出来的下一代的NpN_pNp​个个体中,随机选择一对,将它们随机lll位的编码互换, 从而更新这两个个体,创造出新的个体来。 在本例中, 对复制好的NpN_pNp​个个体,我们按序两两成对, 如1和2, 3和4,然后随机交换它们对应位的编码。每个位置交换与否的概率为0.50.50.5。 另外, 对每一对选出的个体,都有20%的概率不进行交叉, 有80%的概率执行刚刚所述的交叉。 而80%则被称为交叉率。
  6. 变异操作: 除了通过交叉操作产生新个体,变异操作也是得到新个体的重要手段。 首先定义变异率pmp_mpm​, 那么我们将随机选取pm×Npp_m\times N_ppm​×Np​个个体进行变异。 变异操作如下: 对一个个体, 随机挑选其L×pmL\times p_mL×pm​个基因(也即编码)进行变异,也即取反,从而得到一个新的个体。 这里如果pm×Lp_m\times Lpm​×L的结果非整则还需取整。
  7. 保留最优: 经过上述操作后,我们实际上已经生成了共有NpN_pNp​个个体的新一代种群。 此时,我们将第一个个体踢掉,用上一代种群中最好的那个个体代替之。 也即: 下一代种群永远保留上一代的最优解。
  8. 判断是否已迭代到指定的遗传代数。如果没有,则跳转到第二步进行迭代。 若已达到, 选择最优的个体作为最终解。 由于在每一代遗传时都保留了上一代的最优解,因此事实上我们的最终解就是所有搜索过的个体中的历史最优解。

以上就是遗传算法的具体流程。 虽然看到许多文章会说他各种优点,但笔者看来,本质上就是如果基于一些启发式的(来自于自然的)思想进行更高效的搜索,虽然欠缺扎实的理论分析,但看上去就是个行之有效的方案。 下面则是Matlab实例运行结果:

Matlab实例代码


作者给出的代码中用到了已被淘汰的randint API, 这里笔者进行了修改使得可以直接在新版matlab上运行了,代码如下:

%%%%%%%%%%%%%%%%%%%%标准遗传算法求函数极值%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all;              %清除所有变量
close all;              %清图
clc;                    %清屏
NP=50;                  %种群数量
L=20;                   %二进制数串长度
Pc=0.8;                 %交叉率
Pm=0.1;                 %变异率
G=100;                  %最大遗传代数
Xs=10;                  %上限
Xx=0;                   %下限
f=randi(2, NP,L) - 1;        %随机获得初始种群
%%%%%%%%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%%%%%
for k=1:G%%%%%%%%%%%%将二进制解码为定义域范围内十进制%%%%%%%%%%%%%%for i=1:NPU=f(i,:);m=0;for j=1:Lm=U(j)*2^(j-1)+m;endx(i)=Xx+m*(Xs-Xx)/(2^L-1);Fit(i)= func1(x(i));endmaxFit=max(Fit);           %最大值minFit=min(Fit);           %最小值rr=find(Fit==maxFit);fBest=f(rr(1,1),:);        %历代最优个体   xBest=x(rr(1,1));Fit=(Fit-minFit)/(maxFit-minFit);  %归一化适应度值%%%%%%%%%%%%%%%%%%基于轮盘赌的复制操作%%%%%%%%%%%%%%%%%%%sum_Fit=sum(Fit);fitvalue=Fit./sum_Fit;fitvalue=cumsum(fitvalue);ms=sort(rand(NP,1));fiti=1;newi=1;while newi<=NPif (ms(newi))<fitvalue(fiti)nf(newi,:)=f(fiti,:);newi=newi+1;elsefiti=fiti+1;endend   %%%%%%%%%%%%%%%%%%%%%%基于概率的交叉操作%%%%%%%%%%%%%%%%%%for i=1:2:NPp=rand;if p<Pcq=randi(2, 1,L) - 1;for j=1:Lif q(j)==1temp=nf(i+1,j);nf(i+1,j)=nf(i,j);nf(i,j)=temp;endendendend%%%%%%%%%%%%%%%%%%%基于概率的变异操作%%%%%%%%%%%%%%%%%%%%%%%i=1;while i<=round(NP*Pm)h=randi(NP);      %随机选取一个需要变异的染色体for j=1:round(L*Pm)         g=randi(L);   %随机需要变异的基因数nf(h,g)=~nf(h,g);endi=i+1;endf=nf;f(1,:)=fBest;                   %保留最优个体在新种群中trace(k)=maxFit;                %历代最优适应度
end
xBest;                              %最优个体
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')

附录

君主方案

不同于轮盘赌方案,君主方案的交叉、变异、选择操作如下:

  1. 降序排列种群的个体适应度,选出适应度最高的个体作为“君主”。
  2. 将君主与其他偶数位的个体进行交叉, 交叉的基因位个数决定于交叉率, 例如交叉率为80%,基因位数10, 则有8个基因将进行交叉置换。
  3. 基于变异率对所有个体进行变异,这一步操作与前例一致。 至此得到NpN_pNp​个新个体。
  4. 将这NpN_pNp​个新个体与上一代的NpN_pNp​个老个体一并进行适应度评价, 留下前NpN_pNp​个高适应度个体作为这一代的种群。、

遗传算法解决旅行商问题

假设有NNN个城市, 旅行商问题就是解决到这NNN个城市的顺序问题, 也即可行解 XXX 为 [1,2,⋯,N][1,2,\cdots, N][1,2,⋯,N]的任意乱序排列。 因此,我们可以将一个个体定义为一种乱序排列 (也即基因位数仍是323232, 但取值不再是0,10,10,1, 而是1,⋯,N1,\cdots, N1,⋯,N), 也即任意个体就是一个可行解。

为此,我们需要重新定义交叉、变异操作, 以使得创造出的新个体是可行解。

非常启发式的, 交叉操作可以定义为:随机交换两个个体成对的城市索引。 变异操作可定义为: 随机交换一个个体的一对城市索引。

由此我们也可以看出, 用遗传算法解决问题的核心,就在于如何定义交叉、变异操作,使得新个体仍是可行解,即实现有效搜索。

从Matlab实例学习遗传算法相关推荐

  1. Matlab实现遗传算法(附上完整仿真源码)

    遗传算法(Genetic Algorithm,GA)是一种基于生物进化理论的优化算法,通过模拟自然界中的遗传过程,来寻找最优解. 在遗传算法中,每个解被称为个体,每个个体由一组基因表示,每个基因是解空 ...

  2. Matlab 基于遗传算法优化的VMD信号去噪算法 创新点:基于样本熵作为适应度函数

    Matlab 基于遗传算法优化的VMD信号去噪算法 创新点:基于样本熵作为适应度函数 创新点2:基于信噪比作为适应度函数 提高信噪比 本人研究方向信号处理特征提取与故障诊断算法 ID:34506686 ...

  3. MATLAB编写遗传算法求解vrp问题

    MATLAB编写遗传算法求解vrp问题 vrp问题是有载重限制的物流配送线路优化问题,详细可表述为:有1个配送中心,向m个客户点送货,从配送中心出发,货物不足时回配送中心装货,配送完成后回到配送中心. ...

  4. 通过matlab的遗传算法工具求解规划问题

    matlab的Optimization工具中有遗传算法工具箱,可利用该界面工具求解规划问题. 界面定义: @fun            目标函数(最后小化问题)    A*x<=b       ...

  5. BP神经网络优化 | MATLAB基于遗传算法优化BP神经网络(GA-BP)的预测模型(含完整代码)

    文章目录 前言 一.遗传算法描述 二.优化思路 三.完整代码 预测结果 前言 首先需要安装一下遗传算法工具箱,可参考这篇博客 MATLAB遗传算法工具箱安装包及安装方法(图解)_周杰伦今天喝奶茶了吗的 ...

  6. 【Matlab】 遗传算法求解TSP问题

    [Matlab] 遗传算法求解TSP问题 文章目录 [Matlab] 遗传算法求解TSP问题 前言 一.问题描述 二.实验设计 1.问题案例 2.读入数据 3.适应度计算 4. 选择子代 5. 结果输 ...

  7. 阵列matlab遗传,基于MATLAB的遗传算法及其在稀布阵列天线中的应用

    文件名大小更新时间 基于MATLAB的遗传算法及其在稀布阵列天线中的应用02019-12-26 基于MATLAB的遗传算法及其在稀布阵列天线中的应用\chapter302019-07-28 基于MAT ...

  8. matlab约束非线性规划,MATLAB中用遗传算法求解约束非线性规划问题

    <MATLAB中用遗传算法求解约束非线性规划问题>由会员分享,可在线阅读,更多相关<MATLAB中用遗传算法求解约束非线性规划问题(3页珍藏版)>请在人人文库网上搜索. 1.维 ...

  9. MATLAB实战系列(二十六)-matlab通过遗传算法求解车间调度问题

    文章目录 文中涉及源代码请参见,感兴趣的小伙伴可自行订阅下载! 数学建模源码集锦-基于多层编码遗传算法的车间调度算法应用实例 1. 关于遗传算法的一个小故事 2. 遗传算法操作流程 3. 车间调度问题 ...

最新文章

  1. asp.net mvc 学习
  2. 30 分钟让你掌握 Git 的黑魔法
  3. 调多大的角度 计算几何
  4. 前端面试题集结号之CSS
  5. Document Builder: 如何分析rule执行逻辑
  6. Javascript面向对象编程:构造函数的继承
  7. Java 判断目录是否为空
  8. 学前端开发是一种什么样的体验?
  9. TiDB 在 Ping++ 金融聚合支付业务中的实践
  10. 小程序获取用户手机号_借助云开发5行代码获取小程序用户的手机号
  11. python tree 库_Python——tree
  12. Google 包庇 Android 之父还给了 9000 万美元,女工程师们怒了!
  13. 菜鸟使用mock.js心得
  14. 解决问题:Parameter 0 of method modifyRequestBodyGatewayFilterFactory inorg.springframework.cloud.gateway
  15. 用java制作扑克牌_JAVA入门第三季-简易扑克牌程序-个人编写-源代码(含截图)...
  16. GitLab搭建局域网改外网
  17. single-shot detection(SSD)目标检测算法详解——(一看就懂系列!!!)
  18. Windows-空硬盘安装系统
  19. 机器学习水果识别——python+opencv实现物体特征提取
  20. 旋转八卦代码 java_Java的BIO和NIO很难懂?用代码实践给你看,再不懂我转行!

热门文章

  1. mybatis plus 事务管理器_最全MyBatis核心配置文件总结,可以作为工具先收藏了
  2. 基础类 - SQL语句
  3. UEFI开发探索100 – 《UEFI编程实践》发布啦
  4. 从小白到起飞的 RT-Thread 开发指南
  5. 吉林大学[离散数学(68集)AVI] 下载地址 百度云盘
  6. Mac系统下获取/创建ssh key
  7. xe5 android 模拟器,Delphi xe5如何使用Bluestacks模拟器。
  8. Android期末大作业、移动应用开发期末大作业(教练预约APP)
  9. PowerBuilder 10 下调用FoxitPDFSDK_AX_Pro.ocx浏览打印PDF文件
  10. 系统集成项目管理工程师+android,系统集成项目管理工程师