Word害我重写=_=顺便重新整理下思路
背景:写论文时用到遗传算法,花了近一周时间,还算理解了算法以及能够进行基础的编程实现(保持谦虚)。
说明:具体的实现没敢细讲,主要是原理的方法上的介绍(讲解都算不上)。
先说说算法学习,个人觉得首先需要了解这个算法是拿来干嘛的,然后学习它的理论原理,多看懂几遍总是好的;结合实际例子,接着把算法的每一块儿研究清楚,通篇理解后,自己试着编程实现,这样学起来感觉也还不错。
关于遗传算法原理:模拟自然界优胜劣汰的进化现象,把搜索空间(问题解的组成空间)映射为遗传空间,把可能的解编码成一个向量——染色体,向量的每个元素称为基因。通过不断计算各染色体的适应值,选择最好的染色体,获得最优解。
简单说,就是给你一堆人儿(解和种群),让你选择一部分基因优良(解的适应度更高,比如值更大)的人出来,让他们生小孩组成后代(选择交叉和变异),把这些后代和之前选出来的父代,再比较基因优良,再选择,再遗传,这样循环,最后找出一个超级英雄(最优解)就达到目的了。
这样类似于一种无目的的搜索式寻找最优,不过遗传算法的效率更高。
关于原理,知乎上有些通俗好玩的文章可以看下:https://www.zhihu.com/question/23293449
关于算法步骤:从原理也可以总结出,主要步骤包括,适应度函数的设计,编码,选择,交叉,变异。
即是说,我们主要能用代码实现这些操作,一个算法就能基本实现了。这也算是面向对象编程了。给一张流程图:
图有点大
这流程图在整篇文字看完后在回来看一遍。(坚持,看完d===( ̄▽ ̄*)b)
关于算法术语(偷懒截图):
来源某不知源课件,大学资源多
先从个体开始,我总是乐意把个体和染色体一起理解,因为染色体就是编码过后的个体,两者本质一样,只是表现方式不一样。个体就是算法的一个解,比如一个函数在某个区间内,有无数个解。而染色体,是为了让算法能更好的理解和操作我们的个体,进行的编码结果。这里的编码,就是一个转换操作。
举个栗子,求一个函数区间内最大值,我将一个值为13的解,按照6位长的二进制编码,转换为:001101,这里的13就是个体,001101就是染色体,里面的0和1就是基因。这样来,算法操作这些二值集比实数容易得多。
然后,一大堆个体组成种群,我们需要做的,就是从种群中,挑选出优良的个体(染色体),进行交叉变异,生成下一代,组成新的种群。
评价个体是否优良的标准就是适应度函数,比如求极值函数的值哪些更大或更小。适应度函数给每个个体一个评价值,然后依据评价值,我们选出一部分——如种群数量的20%——作为优良的父代,通过交叉变异,让他们产生子代,组成新的种群,再计算适应度和循环。
交叉和变异就是遗传操作。交叉,就是把染色体里的基因交换,比如吧父亲的优良基因与母亲的优良基因组合在一起,生成下一代,如图:
我们将左边两个染色体交叉,产生了右边新的两个染色体。这个时候用了编码就十分好理解了,每个染色体就是一个二进制串,如图:
这样进行交叉比用实数表示容易实现多了去了。
然后是变异,就是染色体内部的基因变异,比如改变二进制串中的某个基因值,就能产生变异。
001101?011101,对第二个基因变异,产生新的染色体(解),也就是13产生了29。
理解了术语和步骤,接下来就是具体实现。具体的实现,我结合网上找的很实用的例子,来源应该是《遗传算法工具箱》这类书。
环境:matlab和遗传算法工具箱。
首先说下工具箱,这是由外国的大神们编制的一个工具箱,里面有对应的遗传算法各个操作会用到的函数。这些函数也是重点,因为遗传算法(或者大部分算法)都是分块儿的,每一个块儿就是一个操作,每一个操作都以函数形式来表达和进行。
因此具体的实现,就是对每个操作的函数实现。代码来自《工具箱》群书,只是主要部分:
?
前4行为算法约定或约束。表明,我们每一个种群中有40个个体(染色体)。最多会遗传25代,及循环25次或者说会生成25个种群。然后编码的长度—即染色体的长度为20位(使用的二进制编码)。代沟是选择的比例,即每个种群,我们选出40*0.1=4个优良个体。
接下来就是循环的设计,在循环里边,有函数:“计算目标函数值”,在这里即是适应度函数。大多时候,适应度函数都是用原函数。
二十进制转换函数bs2rv是为了让编码后的个体能恢复实数形式并用以计算适应度。
里边的选择、重组和变异,都是通过一个函数完成:select,recombin,mut。这里的选择,就是选出优良染色体用来产生下一代。重组就是交叉;变异就是…变异。
所以你看到,每一个操作用函数就可以完成,但是要知道,这里的一个函数只是对应了一种操作模式,二每个操作都有很多模式,比如编码有二进制编码、实数编码等。选择操作有赌轮选择、锦标赛选择。交叉有单点交叉、多点交叉等。变异有基本位变异、均匀变异等。
当然每一个模式,或者方法都有对应的原理和函数,这个就自行查找学习。
所以看来遗传算法也没那么难,搞清楚每一个操作,寻找或编写对应的函数,再调用即可。
不过这只是基本遗传操作,现在更在意的是遗传算法的改进和优化,而这些改进和优化,又都是针对以上操作的模式的不足进行的优化,也是好玩。
大概就到这里,最后推荐一本书,雷英杰,老师和张善文老师主编《MATLAB遗传算法工具箱及应用》,着实实用,实际操作也有,优化也有。