本文最初由SpriteLW发表于http://blog.csdn.net/SpriteLW,可以随意转载,但未经同意不得增删修改,转载应保留本声明,否则追究责任。
读万卷书不如行万里路,今天下决心写一个SGA(Simple Genetic Alogrithms)程序,是求解非约束优化问题。
max f(x1,x2) = 21.5 + x1*sin(4 * PI *x1) + x2*sin(20 * PI * x2)
-3.0 <= x1 <= 12.1
4.1 <= x2 <= 5.8
这可是遗传算法中最容易的,可是结果却令人失望,在整个求解过程中都收敛在局部最优,只有通过加大变异率才能求得全局最优,但问题可想而知:全局最优解不稳定,就好像是昙花一现。
查了一下资料才发现是编码设计的问题。我用的是二进制编码。
编码是应用遗传算法时要解决的首要问题,也是设计遗传算法时的一个关键步骤。编码方法影响到交叉算子、变异算子等遗传算子的运算方法,大很大程度上决定了遗传进化的效率。
迄今为止人们已经提出了许多种不同的编码方法。总的来说,这些编码方法可以分为三大类:二进制编码法、浮点编码法、符号编码法。下面我们从具体实现角度出发介绍其中的几种主要编码方法。
1.二进制编码方法:
它由二进制符号0和1所组成的二值符号集。它有以下一些优点:
1) 编码、解码操作简单易行
2) 交叉、变异等遗传操作便于实现
3) 符合最小字符集编码原则
4) 利用模式定理对算法进行理论分析。
二进制编码的缺点是:对于一些连续函数的优化问题,由于其随机性使得其局部搜索能力较差,如对于一些高精度的问题(如上题),当解迫近于最优解后,由于其变异后表现型变化很大,不连续,所以会远离最优解,达不到稳定。而格雷码能有效地防止这类现象
2.格雷码方法:
格雷码方法是这样的一种编码方法,其连续两个整数所对应的编码值之间仅仅只有一个码位是不同的。如下表
十进制 |
二进制 |
格雷码 |
0 |
0000 |
0000 |
1 |
0001 |
0001 |
2 |
0010 |
0011 |
3 |
0011 |
0010 |
4 |
0100 |
0110 |
5 |
0101 |
0111 |
6 |
0110 |
0101 |
7 |
0111 |
0100 |
8 |
1000 |
1100 |
9 |
1001 |
1101 |
10 |
1010 |
1111 |
11 |
1011 |
1110 |
12 |
1100 |
1010 |
13 |
1101 |
1011 |
14 |
1110 |
1001 |
15 |
1111 |
1000 |
假设有一个二进制编码B=bmbm-1…b2b1,其对应的格雷码为G=gmgm-1…g2g1
由二进制编码转格雷码的转换公式为:
gm = bm
gi = bi+1⊕bi ,i=m-1,m-2,…2,1
由格雷码转二进制的转换公式为:
bm = gm
bi = bi+1⊕gi, i=m-1,m-2,…2,1
从以上表格可以看出,当一个染色体变异后,它原来的表现现和现在的表现型是连续的。
格雷码编码的主要优点是:
1) 便于提高遗传算法的局部搜索能力
2) 交叉、变异等遗传操作便于实现
3) 符合最小字符集编码原则
4) 便于利用模式定理对算法进行理论分析
3.浮点编码法
对于一些多维、高精度要求的连续函数优化问题,使用二进制编码来表示个体时将会有一些不利之处。
二进制编码存在着连续函数离散化时的映射误差。个体长度较知时,可能达不到精度要求,而个体编码长度较长时,虽然能提高精度,但却使遗传算法的搜索空间急剧扩大。
所谓浮点法,是指个体的每个基因值用某一范围内的一个浮点数来表示。在浮点数编码方法中,必须保证基因值在给定的区间限制范围内,遗传算法中所使用的交叉、变异等遗传算子也必须保证其运算结果所产生的新个体的基因值也在这个区间限制范围内。
浮点数编码方法有下面几个优点:
1) 适用于在遗传算法中表示范围较大的数
2) 适用于精度要求较高的遗传算法
3) 便于较大空间的遗传搜索
4) 改善了遗传算法的计算复杂性,提高了运算交率
5) 便于遗传算法与经典优化方法的混合使用
6) 便于设计针对问题的专门知识的知识型遗传算子
7) 便于处理复杂的决策变量约束条件
4.符号编码法
符号编码法是指个体染色体编码串中的基因值取自一个无数值含义、而只有代码含义的符号集如{A,B,C…}。
符号编码的主要优点是:
1) 符合有意义积术块编码原则
2) 便于在遗传算法中利用所求解问题的专门知识
3) 便于遗传算法与相关近似算法之间的混合使用。
但对于使用符号编码方法的遗传算法,一般需要认真设计交叉、变异等遗传运算的操作方法,以满足问题的各种约束村求,这样才能提高算法的搜索性能。