最近在自然计算当中学到了遗传算法,学完之后自己用matlab写了相应的程序,有一些感悟吧,写下了方便忘了后看看。遗传算法就是模拟人类种群繁衍的过程,来寻找最优解的过程,下面介绍一下利用遗传算法解决一个具体例子的整个过程。
题目:
有人可能会说,这个题目还不简单,穷举就可以了。但是我想说的是穷举的话,假设把最优解保留到小数点5位,不算多吧,x1迭代需要1510000次,x2迭代需要170000次,穷举的时间复杂度是这两个数的乘积,就一句话算死你,电脑都能跑出血。所以我们需要的是利用较少的时间复杂度获得比较好的最优解,遗传算法就是做这件事。下面我介绍一下遗传算法的具体过程。
1.编码
首先我们需要对自变量x1,x2进行编码,编码是为了将自变量变成和人类基因类似的序列,自变量的改变看做是人类基因序列发生改变。下面来看看编码的具体过程:
这里我选择将自变量以二进制的形式进行编码,首先我们需要确定表示x1和x2需要多少位二进制??这里我们还是选择让自变量保留到小数点后5位。那么有
bj和aj表示自变量的范围,mj表示自变量需要用多少位进行表示。其原理就是将自变量x1从小数点后面向左移5位,然后估计可以用多少位可以表示该整数。通过这个公式可以知道,x1需要用18位,x2需要用15位,把两个序列合并,就是说要表示自变量需要用33位。如果这样的话,怎么将x1变成二进制的序列呢??
然后用x1'用二进制来表示,就可以得到x1的二进制编码,同理得到x2的二进制序列。当x1=-2.687069,x2=5.361653时,可得如下二进制编码:
同理我们怎么通过二进制序列得到x1呢??公式如下:
具体到本题目,xj=x1,aj=-3.0,bj=12.1,mj=18,decimal是二进制序列转化为十进制的值。
2.随机初始化
由生物知识可以知道,所有的遗传变异都是以种群为单位的,种群中有好多个体,yi就相当于每个个体的表现型,所有我们需要随机化生成多个x1和x2,当然这些x1和x2都在区间内。这个过程就相当于一定数量的人到达一片新的领域生活,最后在这群人以及后代里面找到最适合在这片土地生活的人(最优解)。这里随机初始化的数目是你自己取的,这里我取的是10。
3.计算出函数值
初始化x1和x2后,将x1和x2带入到函数中,就可以得到函数值,即个体的表现型。
4.找到函数值的最大值
我们得到函数值后就可以找到这群个体中的最大值,将最大值保存下来。
5.构造适应性函数
换句话解释标题的意思,我们要繁衍下一代,不可能这个种群中所有的个体都能繁衍下来吧,正所谓优胜劣汰,适应性函数就是用来淘汰个体的,只有表现型较好的个体才能繁衍。那么适应性函数具体形式怎样??
1:
公式中vk表示每个个体的函数值,popsize表示种群中个体的数目。
2:
获得每个个体函数值占总值的比例pk。
3:
qk表示前k个个体比例值pk的总和,这样q(k-1)到q(k)就形成了一个区间,然后我们产生一个随机值,观察随机值在哪个区间内,该个体的下一代就是第k个个体的序列。可能你看到这个适应性函数有点乱,但是通过本质来考虑,如果函数值越大,产生的区间范围就大,当然作为下一代保存下来的概率就大,函数值越小产生的区间小,保存下来的概率小,自然慢慢就淘汰了。
假设初始化个体如下:
则适应性函数产生的过程如下:
如果单纯的这样繁衍的话,种群的基因不会发生变化,后面也不用计算了,之所以后代表现型不同主要是基因会发生染色体的交叉变异和基因突变,使得基因发生改变,从而改变个体的表现型。
5.交叉变异
染色体交叉变异,就是将两条染色体的部分基因片段互换,形式如下:
这里需要注意的是交叉互换发生也有一定的概率,这是一件概率事件,这里我取概率为0.30。染色体交叉互换的位置是不确定的,我们这里可以采用一个随机数。
6.基因突变
基因突变是指序列中某位1突变成0,0突变成1,序列中某位突变也是概率事件,这里我们取0.01。形式如下:
当然这里突变的位置是一个随机值。
由此我们得到下一代个体的基因如下:
这里重复步骤3,得到相应个体的函数值,从而得到种群中的最优解。这里迭代的次数是我们自己选的,迭代次数越高,结果越好,但是时间复杂度越高。
得到该函数的最优解为38.740781。
下面我将程序上传到我的资源里面,可以通过以下链接进行下载:
http://download.youkuaiyun.com/download/hxlove123456/10126363