遗传算法matlab_遗传算法和MATLAB (更新中)

b43cc78c25a544a9b76f97891845a4d1.png

0. 文章目的

本人写这样一篇文章的目的在于提供一张学习遗传算法的地图。实现的主要工具是MATLAB和其自带的全局优化工具箱 Global Optimization Toolbox。无论读者是来自工程、科学或者其他任何领域,希望看完文章之后都能实现自己的遗传算法!欢迎留言交流。

如何通俗易懂地解释遗传算法?有什么例子?​www.zhihu.com

知乎上也有相关的问题,可以看下前两个高赞回答对于养成直觉上的理解很有帮助。


1. 遗传算法简介

遗传算法 (Genetic Algorithm) 是一种基于自然选择启发式的随机并行搜索优化方法。该算法特殊之处在于其借鉴了进化生物学中的很多概念,其中包括遗传、突变、自然选择和杂交等。抽象的来说,我们将会学到怎么模拟一个人工种群的进化过程。相比基于梯度的传统优化方法,遗传算法可以解决不连续、不可微的目标函数的优化问题。尤其擅长解决时间表安排 (例如为一个大学安排不冲突的课表), 在下一篇文章中我们将会看到一个具体的例子和代码。

1.1 遗传算法流水线 (pipeline)

0)预处理:编码优化问题。

1)随机初始化一定数量的初始种群,种群中每一个个体(提前编码成二进制形式)代表优化问题的一个候选解。从生物学意义上来说,我们可以认为个体代表染色体或者基因片段。

2)通过遗传算子(genetic operator)进化至下一代种群。算子的主要构成:

  • 通过适应度函数 (fitness),给当前种群中的每一个个体评分。该评分被称为原始适应成绩 (raw fitness score),用来表征个体对环境的适应度。同时也代表了候选解的优劣程度。
  • 针对具体问题,缩放原始适应成绩到一个更合理的区间。缩放后的成绩称为期望值(expectation)。
  • 基于期望值,通过选择函数(selection function)挑选具有优秀基因的父母 (parents)。对于某些适应度很高的个体,我们称之为精英 (elite)。他们将被直接保留到下一代种群。
  • 父母产生后代 (children)。生产方式主要有以下两种:父母中一方的染色体产生突变(mutation)、父母双方按照一定概率交换部分基因 (crossover)。
  • 完成后取代当前种群的所有个体。

3)满足终止条件(stopping criteria)后,选出迭代进化的种群中最优个体。

以上部分参考了MATLAB的GA官方文档:

How the Genetic Algorithm Works​ww2.mathworks.cn

1.2 可调节参数

  • 种群规模(population size):即种群中染色体个体的数目。
  • 字符串长度(string length):个体中染色体的长度。
  • 交配概率(probability of performing crossover):控制着交配算子的使用频率。交配操作可以加快收敛,使解达到最有希望的最佳解区域,因此一般取较大的交配概率,但交配概率太高也可能导致过早收敛,则称为早熟。
  • 突变概率(probability of mutation):控制着突变算子的使用频率。
  • 中止条件(termination criteria)

关于调参的细节请参见官方文档:

Genetic Algorithm​ww2.mathworks.cn

1483ba7d0a73d2a5ab42cfab75f6ec5f.png

2. 例子与概念详解

接下来我们通过一个具体的优化例子,来进一步认识以上提及的概念:

求解函数

在区间
的最大值和最小值。

画出函数图像和:

78cef7f0f5bf0e408a14a5abe045bbd8.png

*注释:在遗传算法优化中,我们默认求的是最大值问题

。而最小值问题则可以转化为
,其中
。这是因为我们一般规定
在定义域内恒正
。如不满足,也可以转化成
。常数
在我们的例子里可以取

*注释:我们这个例子中

虽然是一个单变量,但对多变量优化问题来说就需要改成向量
其中每个元素可以有自己的定义域

2.1 编码和解码 (code and decode)

遗传算法的第一步是对优化问题进行编码,映射到一个方便基因进化的码空间。主要存在实数编码和二进制编码两种方式。在这个例子中,我们采用传统上偏向的二进制编码。其具有稳定性高、种群多样性(diversity)等优点,但需要的存储空间较大而且解码过程不易理解。

假设我们求解的精度为小数点后四位,即

。我们需要将
的解空间划分成
等分。使
满足以下不等式
,其中
是使上式成立的最小整数,也表示
的基因串的长度。因为
,这里取
例如
就表示一个码空间中的基因串。对于多变量优化问题,编码后
的二进制串的总长度称为一个染色体(chromosome)或者个体(individual)的长度。

类似的,解码过程就是一个逆向的从码空间映射到解空间的过程。对于二进制编码,每个二进制基因串都可以翻译成一个十进制的实数值。这个我们都很熟悉,

请注意这里是从左至右进行转码的。然后再把这个十进制实数映射到相应的区间,我们知道

对应区间下限的转码
对应区间上限的转码。

通过对区间编码过程的观察,我们构造以下映射并验证其合理性:

接着完成我们前面选定个体的解码过程,

2.2 初始化种群

接着我们随机生成一定数量的个体。如果知道种群的实际分布,当然可以按照此分布提高初始种群的质量。初始种群的数量很重要,如果初始种群数量过多,算法会占用大量系统资源;如果初始种群数量过少,算法很可能忽略掉最优解。

function

假设初始种群大小 n = 5,染色体长度 m = 16。得到以下码空间内部的初始种群矩阵:

2.3 适应度函数

接下来我们解码到解空间中,并评分得到每个个体的原始适应成绩 (raw fitness score)。

function

如果我们给前面初始的种群

打分,会得到

其中第4个染色体的表现似乎最好,不如直接选为精英个体(elite)保留到下一代,就不给他脱单的机会了:)。。。接着我们可视化一下这些初始个体:

422999ef66bd4be5f9aee6c6eec87ffc.png

*注释:遗传算法在适应度函数选择不当的情况下有可能收敛于局部最优,而不能达到全局最优。如果一个优化问题没有确切的适应度函数表征个体好坏的问题,算法会失去进化导向。

2.4 (可选) 原始适应成绩的缩放(scaling)和排序(rank)

缩放的目的在于让选择机制更好的运行。如果缩放后的期望值范围太大,表现最好的个体可能繁衍过快,与很多其他个体交换基因从而导致种群的基因库里充斥着这个单一个体的基因,损失多样性。这种现象被称之为早熟,算法会快速收敛到局部最优解而非全局最优解。在相反的情况下,如果缩放后的期望值变化范围很小,每个个体能繁衍后代的几率都差不多。这会导致算法收敛的很慢。。。排序是将种群中的个体按照适应度从小到大进行排列。

[

2.5 选择机制

接着我们来看一下常用的轮盘赌博(Roulette Wheel Selection)选择法。根据上面5个染色体的例子,他们作为一个种群的原始总评分为:

每个染色体被选择的概率是:

比方说个体一被选中的概率就是

那么算法上,具体要怎么做才能让第一个个体被选中的概率正好等于

呢?考虑一下操作,在每次转动转盘时,生成一个随机数
然后把区间划分成种群大小=5份。即
占比分别对应选取概率
。这样的话,只要判断转盘落在哪个区间内,我们随即选择相应区间对应的个体即可!
function

*注释:这里只选了一个精英个体,读者不妨试试选择多个精英个体会产生怎么样的影响

在上面这个轮盘赌博算法中,我默认了精英选择机制。也就是说,把这一代的最优解自动保留到下一代。然后在剩下的基因库里选择父代和母代,接着我们前面的例子:

细心的读者会发现,我们没有让每代的精英在他所在的时代繁衍的机会。但这不意味着在下一代,他没机会脱单。也就是说只要你足够优秀老牛吃嫩草是完全可能的。。。我们接着来看看这一个初始种群是怎么通过遗传算子进化到下一代的。

2.6 变异(mutation)和交叉操作(crossover)

选定好父代和母代之后,进入交配过程。一般的遗传算法都有一个交配概率

(又称为交叉概率),范围一般是0.6~1,这个交配概率反映两个被选中的个体进行交配的概率。例如,交配概率为0.8,则80%的“夫妻”会生育后代。
这里考虑到算法的收敛速度,我们考虑“优生优育”政策。限制每两个个体通过交配只能产生一个新个体,而不交配的个体则保持不变。交配父母的染色体相互交换,从而产生两个新的染色体, 新个体前半段是父亲的染色体,后半段是母亲的。不过这里的半段并不是真正的一半,这个位置叫做交配点
,也是随机产生的,可以是染色体的任意位置。直观上你可以这么理解:

然后交配点在4个基因位,产生的孩子便会是

function

还是回到我们前面的例子,设定

,我们得到繁衍后的种群

再下一步是突变,通过突变产生新的“子”个体。一般遗传算法都有一个固定的突变常数

(又称为变异概率),通常是0.1或者更小,这代表变异发生的概率。根据这个概率,新个体的染色体随机的突变,通常就是改变染色体的一个字节(0变到1,或者1变到0)。在编码过的遗传算法中,每次变异的编码长度也影响到遗传算法的效率。如果变异代码长度过短,变异的多样性会受到限制;如果变异代码过长,变异的效率会非常低下,选择适当的变异长度是提高效率的关键。此外,存在着一些方法增加基因的多样性从而防止过早的收敛。其中一种是所谓
触发式超级变异,就是当染色体群体的质量下降(彼此的区别减少)时增加变异概率;另一种叫 随机外来染色体,是偶尔加入一些全新的随机生成的染色体个体,从而增加染色体多样性。
function

*注释:这里我们每次只允许一个基因点变异其实是限制了遗传多样性的。

设定突变概率

,我们得到突变后的种群

接着我们可视化一下第二代种群的适应程度:

6026c4f3f4dbbb2ecea1f34d65350d84.png

可以看出,种群的累计适应度是按照我们给出的进化方向上升了的。但是由于我们初始种群数量太小,基因库同化趋势比较明显(3个个体都集中在同一处)。我们可以大胆预测,就算进化迭代20次以后依然很难达到全局最大值。不妨验证一下:

c935bdbfb8a1eb0cb105d6f8a78dd848.png

不出所料。这是个典型的例子:由于种群多样性的不足,使得我们无法跳出局部最大值。可以尝试的解决方案就是增大初始种群数量。

2.7 遗传算法主体程序

在搭建完以上的所有轮子之后,我们来看看算法的主体部分

function

调参过后,运行多次遗传算法取结果最大值如下:


3. 例子:使用MATLAB全局优化工具箱寻找全局最小值

那么在搭建完我们自己的遗传算法(破铜烂铁轮子)之后,我们来看看官方的工具箱(军火库)该怎么使用。先从同样的例子开始讲解:

3.1 工具箱入门

求解函数

在区间
的最大值和最小值。
optimtool

我们先打开优化工具箱,来到以下界面。选项是真的多。。不愧是MATLAB军火库。

5f5b2933aaf664f6bb03a6462a89a18a.png

*注释:默认GA工具箱找的全局最小值,所以我们最大值问题得通过取负号变换取得。

填写适应度函数 (Fitness function)以及上下限

后点击开始。在经过65次迭代后,得到全局最大值为
以及
。不得不说,官方优化过的运行速度是真的快。。。

3.2 可视化选项

7d2dda87f9565c03b20df82856599ad9.png

我们选择可视化最优适应度

1ae76ae58bd69160446b0f22a4175d0e.png

3.3 算子选项


4. 拓展:约束条件问题

往往现实当中遇到的实际问题不会像我们的例子这么简单,经常是带有约束条件的。那我们接下来具体看看第二个例子:


5. 编程挑战

读者若有多余的时间不妨尝试挑战以下问题:

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值