遗传算法(genetic algorithm,GA)是计算数学中用于解决最优化问题的搜索算法,是进化算法的一种。进化算法最初是借鉴了达尔文进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择以及杂交等。
预备知识:达尔文进化论,遗传学三大基本定律
查尔斯·达尔文 (1809 - 1882)
格雷戈尔·孟德尔(1822 - 1884)
托马斯·亨特·摩尔根 (1866 - 1945)
遗传算法通常实现方式为一种计算机模拟。对于一个最优化问题,一定数量的候选解(称为个体)可抽象表示为染色体,使种群向更好的解进化。传统上,解用二进制表示(即0和1的串),但也可以用其他表示方法。进化从完全随机个体的种群开始,之后一代一代发生。在每一代中评价整个种群的适应度,从当前种群中随机地选择多个个体(基于它们的适应度),通过自然选择和突变产生新的生命种群,该种群在算法的下一次迭代中成为当前种群。
基本的遗传算法以初始种群为起点,经过自然选择、交叉和突变操作生成新的种群,经过反复更新种群直到寻找到最优解。其计算步骤如下:
- 编码:将问题空间转换为遗传空间;
- 生成初始种群:随机生成P个染色体;
- 种群适应度计算:按照确定的适应度函数,计算各个染色体的适应度;
- 选择:根据染色体适应度,按照选择算子进行染色体的选择;
- 交叉:按照交叉概率对被选择的染色体进行交叉操作,形成下一代种群;
- 突变:按照突变概率对下一代种群中的个体进行突变操作;
- 返回第3步继续迭代,直到满足终止条件。
例题1:试计算此二元函数的最大值:
- 编码:因
x1,x2
为 0 ~ 7之间的整数,所以分别用3位无符号二进制整数来表示,将它们连接在一起所组成的6位无符号二进制数就形成了个体的基因型,表示一个可行解。例如:基因型 X=101110 所对应的表现型是:
[x1,x2]=[5,6] - 生成初始种群:本例中,群体规模的大小取为4,即群体由4个个体组成,每个个体可通过随机的方法产生。例如:
a1=101000=[5,0],a2=101100=[5,4],a3=001100=[1,4],a4=101111=[5,7] - 种群适应度计算:本例中,目标函数总取非负值,并且是以求函数最大值为优化目标,故可直接利用目标函数值作为个体的适应度:
f(a1)=25,f(a2)=41,f(a3)=17,f(a4)=74 - 选择:我们采用与适应度成正比的概率来确定各个个体复制到下一代群体中的数量。其具体操作过程如下:
- 先计算出群体中所有个体的适应度的总和 Σf(ai) , i=1,2,3,4 ;
- 其次计算出每个个体的相对适应度的大小 p(ai)=f(ai)/Σf(ai) , i=1,2,3,4 。它即为每个个体被遗传到下一代群体中的概率;
- 每个概率值组成一个区间,全部概率值之和为1;
- 最后再产生一个0到1之间的随机数,依据该随机数出现在上述哪一个概率区域内来确定各个个体被选中的次数。
在本例中,
Σf(ai)=157
p(a1)=15.92%,p(a2)=26.11%,p(a3)=10.82%,p(a4)=47.13%
因此 a1区间=[0,0.1592] , a2区间=[0.1592,0.4203] , a3区间=[0.4203,0.5285] , a4区间=[0.5285,1] 。
经过4次选择, a4 被选3次, a2 被选1次, a1 与 a3 落选:
b1=101111=[5,7],b2=101111=[5,7],b3=101100=[5,4],b4=101111=[5,7]
- 交叉:本例采用单点交叉的方法,其具体操作过程是:
- 先对群体进行随机配对;
- 其次随机设置交叉点位置;
- 最后再相互交换配对染色体之间的部分基因。
在本例中,
b1 与 b2 在第3位后交叉,生成:
101∥111×101∥111:c1=101111=[5,7],c2=101111=[5,7]
b3 与 b4 在第5位后交叉,生成:
10110∥0×10111∥1:c3=101101=[5,5],c4=101110=[5,6]
- 突变:我们采用基本位变异的方法来进行变异运算,其具体操作过程是:
- 首先确定出各个个体的基因变异位置;
- 然后依照某一概率将变异点的原有基因值取反。
本例中, c2 的第2位发生突变:
c′2=10⎯⎯1111=111111=[7,7]
至此,我们已经找到了一个最优解 c′2 。
例题2:八皇后问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
https://en.wikipedia.org/wiki/Eight_queens_puzzle
- 编码:染色体的长度取决于皇后的个数,本例中染色体长度即为8。染色体中每个基因所处的位置表示其在棋盘上的行号,基因值表示其所在的列号。例如,染色体4075623,表示第0行皇后放在第4列,第1行皇后放在第0列,第2行皇后放在第7列,等等。八皇后问题中的任意两个皇后不能出现在同列,因此染色体中的基因取值(0~7)不可重复;
- 生成初始种群:随机生成8个初始染色体,他们的染色体中的基因取值各不相同,也就是满足所有皇后都不处于同行同列,但是可能并不满足对角线上是否出现互攻。
- 种群适应度计算:在对某一染色体上某两个皇后的位置进行比较的时候,可以求其行号之差的绝对值与列号之差的绝对值, 若相等则说明互攻成立。
设某一染色体的互攻次数用Value表示,其初始值等于0;将第0行皇后与第1~7行皇后进行比较,每出现一次互攻则Value的值加1;将第1行皇后与第2~7行皇后进行比较,每出现一次互攻则Value的值加1;以此类推。
如果染色体的Value值为0则表示未发生互攻,表示已找到一个可行解。如果Value不为0,一般说来适应度越大则Value的值越小,也就是说适应度与Value成反比。在这里对染色体的Value求倒数就得到其适应度。 - 选择:根据染色体适应度,按照与例题1中相似的赌轮选择法进行染色体的选择;
- 交叉:本例采用单点交叉的方法,先对群体进行随机配对,对于每一对染色体,首先随机选取两点截取一段基因,例如:
01∥24∥3675
12∥30∥4576
然后将这段基因进行交换:
01∥30∥3675
12∥24∥4576
这样生成的两条染色体并不合法,因此要对中间段外的基因进行交换,从而生成合法的染色体:
41∥30∥2675
13∥24∥0576
交叉完成。 - 突变:按照突变概率对下一代种群中的个体进行突变操作,这里对突变个体的染色体随机选择两个基因进行互换,例如对第1和6进行互换:
突变之前:72061453
突变之后:42061753(这其实就是一个最优解) - 返回第3步继续迭代,直到取得Value为0的解。
遗传算法在解决优化问题过程中有如下特点:
- 遗传算法在适应度函数选择不当的情况下有可能收敛于局部最优,而不能达到全局最优。
- 初始种群的数量很重要,如果初始种群数量过多,算法会占用大量系统资源;如果初始种群数量过少,算法很可能忽略掉最优解。
- 对于每个解,一般根据实际情况进行编码,这样有利于编写变异函数和适应度函数(Fitness Function)。
- 在编码过的遗传算法中,每次变异的编码长度以及变异率也影响到遗传算法的效率。如果变异代码长度过长,变异的多样性会受到限制;如果变异代码过短,变异的效率会非常低下,选择适当的变异长度是提高效率的关键。
- 对于动态数据,用遗传算法求最优解比较困难,因为染色体种群很可能过早地收敛,而对以后变化了的数据不再产生变化。对于这个问题,研究者提出了一些方法增加基因的多样性,从而防止过早的收敛。其中一种是所谓触发式超级变异,就是当染色体群体的质量下降(彼此的区别减少)时增加变异概率;另一种叫随机外来染色体,是偶尔加入一些全新的随机生成的染色体个体,从而增加染色体多样性。
- 选择过程很重要,但交叉和变异的重要性存在争议。一种观点认为交叉比变异更重要,因为变异仅仅是保证不丢失某些可能的解;而另一种观点则认为交叉过程的作用只不过是在种群中推广变异过程所造成的更新,对于初期的种群来说,交叉几乎等效于一个非常大的变异率,而这么大的变异很可能影响进化过程。
- 遗传算法很快就能找到良好的解,即使是在很复杂的解空间中。然而遗传算法并不一定总是最好的优化策略,优化问题要具体情况具体分析。所以在使用遗传算法的同时,也可以尝试其他算法,互相补充,甚至根本不用遗传算法。
- 遗传算法不能解决那些“大海捞针”的问题,所谓“大海捞针”问题就是没有一个确切的适应度函数表征个体好坏的问题,使得算法的进化失去导向。
- 对于任何一个具体的优化问题,调节遗传算法的参数可能会有利于更好更快收敛,这些参数包括个体数目、交叉率、变异率以及适应度函数。例如太大的变异率会导致丢失最优解,而过小的变异率会导致算法过早的收敛于局部最优点。对于这些参数的选择,现在还没有实用的上下限。