在基因交叉之后产生的子代个体,其变量可能以很小的概率或者步长发生转变,这个过程称为变异(Mutation)。
如果进化的目标函数极值是单峰值的,那么,将变异概率p设置为种群数量n的倒数是一个比较好的选择。
如果变异概率很大,那么整个搜索过程就退化为一个随机搜索过程。所以,比较稳妥的做法是,进化过程刚刚开始的时候,取p为一个比较大的概率,随着搜索过程的进行,p逐渐缩小到0附近。
与交叉过程一样,变异的算法也可以大致分为实数编码和二进制编码两种。
(1) 实数变异
<1>步长变异
即给数值加上或者减去一个值,这个数值称为步长。大致如下:
X' = X + 0.5 Ld 或者
X' = X - 0.5 Ld
这里
L为变量的取值范围 L = Upper - Lower
d= a(0)/2^0 + a(1)/2^1 + ... + a(m)/s^m
其中a(i)以1/m的概率取1,以 1-1/m的概率取0,一般m=20
C++ 代码
<2>高斯变异
这种变异的方法就是,产生一个服从高斯分布的随机数,取代原先基因中的实数数值。这个算法产生的随机数,数学期望当为当前基因的实数数值。
一个模拟产生的算法是,产生6个服从U(0,1)的随机数,以他们的数学期望作为高斯分布随机数的近似。
(2)二进制变异
对二进制编码来讲,变异就是变量的翻转,如
100001 1 1100001
100001 0 1100001
c++代码
(3)一些相关算法或者函数
如果进化的目标函数极值是单峰值的,那么,将变异概率p设置为种群数量n的倒数是一个比较好的选择。
如果变异概率很大,那么整个搜索过程就退化为一个随机搜索过程。所以,比较稳妥的做法是,进化过程刚刚开始的时候,取p为一个比较大的概率,随着搜索过程的进行,p逐渐缩小到0附近。
与交叉过程一样,变异的算法也可以大致分为实数编码和二进制编码两种。
(1) 实数变异
<1>步长变异
即给数值加上或者减去一个值,这个数值称为步长。大致如下:
X' = X + 0.5 Ld 或者
X' = X - 0.5 Ld
这里
L为变量的取值范围 L = Upper - Lower
d= a(0)/2^0 + a(1)/2^1 + ... + a(m)/s^m
其中a(i)以1/m的概率取1,以 1-1/m的概率取0,一般m=20
C++ 代码
1
template
<
class
GENE
>
2 class Real_Gene_Mutate_Algorithm
3 {
4 public :
5 void operator ()( GENE & gene ) const
6 {
7 const unsigned int M = 20 ;
8
9 // claculate Delta
10 long double Delta = 0 . 0L ;
11 for ( unsigned int i = 0 ; i < M; ++ i )
12 {
13 const long double Boundary =
14 1 . 0L / static_cast < long double > (M);
15 const long double Ran = ran();
16 if ( Ran < Boundary )
17 {
18 const unsigned int Base = 1 << i;
19 Delta += 1 . 0L / static_cast < long double > ( Base );
20 }
21 }
22
23 // claculate Sig and L
24 const long double Ran = ran();
25 long double Sig = 0 ;
26 long double L = 0 ;
27 if ( Ran > 0 . 5L )
28 {
29 Sig = 1 . 0L ;
30 L = gene.Upper - gene.Value;
31 }
32 else
33 {
34 Sig = - 1 . 0L ;
35 L = gene.Value - gene.Lower;
36 }
37
38 gene.Value += Sig * L * Delta * 0 . 5L ;
39 }
40
41 };
42
2 class Real_Gene_Mutate_Algorithm
3 {
4 public :
5 void operator ()( GENE & gene ) const
6 {
7 const unsigned int M = 20 ;
8
9 // claculate Delta
10 long double Delta = 0 . 0L ;
11 for ( unsigned int i = 0 ; i < M; ++ i )
12 {
13 const long double Boundary =
14 1 . 0L / static_cast < long double > (M);
15 const long double Ran = ran();
16 if ( Ran < Boundary )
17 {
18 const unsigned int Base = 1 << i;
19 Delta += 1 . 0L / static_cast < long double > ( Base );
20 }
21 }
22
23 // claculate Sig and L
24 const long double Ran = ran();
25 long double Sig = 0 ;
26 long double L = 0 ;
27 if ( Ran > 0 . 5L )
28 {
29 Sig = 1 . 0L ;
30 L = gene.Upper - gene.Value;
31 }
32 else
33 {
34 Sig = - 1 . 0L ;
35 L = gene.Value - gene.Lower;
36 }
37
38 gene.Value += Sig * L * Delta * 0 . 5L ;
39 }
40
41 };
42
<2>高斯变异
这种变异的方法就是,产生一个服从高斯分布的随机数,取代原先基因中的实数数值。这个算法产生的随机数,数学期望当为当前基因的实数数值。
一个模拟产生的算法是,产生6个服从U(0,1)的随机数,以他们的数学期望作为高斯分布随机数的近似。
1
template
<
class
GENE
>
2 class Gauss_Mutate_Algorithm
3 {
4 public :
5 void operator ()( GENE & gene ) const
6 {
7 long double gauss = 0 . 0L ;
8 for ( unsigned int i = 0 ; i < 6 ; ++ i )
9 gauss += ran();
10 gauss /= 6 . 0L ;
11
12 long double upper;
13 long double lower;
14 const long double Upper = gene.Upper;
15 const long double Lower = gene.Lower;
16 const long double Value = gene.Value;
17
18 ( ( Value - Lower ) > ( Upper - Value ) ) ?
19 ( upper = Upper, lower = Value * 2 . 0L - Upper ) :
20 ( lower = Lower, upper = Value * 2 . 0L - Lower );
21
22 gauss *= ( upper - lower );
23 guass += lower;
24
25 gene.Value = gauss;
26 }
27 };
28
2 class Gauss_Mutate_Algorithm
3 {
4 public :
5 void operator ()( GENE & gene ) const
6 {
7 long double gauss = 0 . 0L ;
8 for ( unsigned int i = 0 ; i < 6 ; ++ i )
9 gauss += ran();
10 gauss /= 6 . 0L ;
11
12 long double upper;
13 long double lower;
14 const long double Upper = gene.Upper;
15 const long double Lower = gene.Lower;
16 const long double Value = gene.Value;
17
18 ( ( Value - Lower ) > ( Upper - Value ) ) ?
19 ( upper = Upper, lower = Value * 2 . 0L - Upper ) :
20 ( lower = Lower, upper = Value * 2 . 0L - Lower );
21
22 gauss *= ( upper - lower );
23 guass += lower;
24
25 gene.Value = gauss;
26 }
27 };
28
(2)二进制变异
对二进制编码来讲,变异就是变量的翻转,如
100001 1 1100001
100001 0 1100001
c++代码
1
template
<
class
GENE
>
2 class Binary_Gene_Mutate_Algorithm
3 {
4 public :
5 void operator ()( GENE & gene ) const
6 {
7 encoding( gene );
8
9 const unsigned int Size = gene.Binary_Array.size();
10 const long double Ran = ran();
11 const unsigned int Pos = static_cast < unsigned int >
12 ( static_cast < long double > ( Size ) * Ran );
13
14 if ( gene.Binary_Array[Pos] )
15 gene.Binary_Array[Pos] = 0 ;
16 else
17 gene.Binary_Array[Pos] = 1 ;
18
19 decoding( gene );
20 }
21 };
2 class Binary_Gene_Mutate_Algorithm
3 {
4 public :
5 void operator ()( GENE & gene ) const
6 {
7 encoding( gene );
8
9 const unsigned int Size = gene.Binary_Array.size();
10 const long double Ran = ran();
11 const unsigned int Pos = static_cast < unsigned int >
12 ( static_cast < long double > ( Size ) * Ran );
13
14 if ( gene.Binary_Array[Pos] )
15 gene.Binary_Array[Pos] = 0 ;
16 else
17 gene.Binary_Array[Pos] = 1 ;
18
19 decoding( gene );
20 }
21 };
(3)一些相关算法或者函数
1
template
<
class
DATA,
class
ALGORITHM
>
2 void mutate( DATA & d, const ALGORITHM & a )
3 {
4 a( d );
5 }
6
7 template < class POPULATION, class GENE_MUTATE_ALGORITHM >
8 class Population_Mutate_Algorithm
9 {
10 public :
11 void operator ()( POPULATION & p ) const
12 {
13 // chromosome numbers in the population
14 const unsigned int C_Size = p.Chromosome_Array.size();
15 // gene numbers in a chromosome
16 const unsigned int G_Size = p.Chromosome_Array[ 0 ].Gene_Array.size();
17
18 for ( unsigned int i = 0 ; i < C_Size; ++ i )
19 {
20 for ( unsigned int j = 0 ; j < G_Size; ++ j )
21 {
22 const long double Ran = ran();
23
24 if ( Ran > p.Mutation_Probability )
25 return ;
26
27 mutate( p.Chromosome_Array[i].Gene_Array[j],
28 GENE_MUTATE_ALGORITHM() );
29 }
30 }
31 }
32 };
33
2 void mutate( DATA & d, const ALGORITHM & a )
3 {
4 a( d );
5 }
6
7 template < class POPULATION, class GENE_MUTATE_ALGORITHM >
8 class Population_Mutate_Algorithm
9 {
10 public :
11 void operator ()( POPULATION & p ) const
12 {
13 // chromosome numbers in the population
14 const unsigned int C_Size = p.Chromosome_Array.size();
15 // gene numbers in a chromosome
16 const unsigned int G_Size = p.Chromosome_Array[ 0 ].Gene_Array.size();
17
18 for ( unsigned int i = 0 ; i < C_Size; ++ i )
19 {
20 for ( unsigned int j = 0 ; j < G_Size; ++ j )
21 {
22 const long double Ran = ran();
23
24 if ( Ran > p.Mutation_Probability )
25 return ;
26
27 mutate( p.Chromosome_Array[i].Gene_Array[j],
28 GENE_MUTATE_ALGORITHM() );
29 }
30 }
31 }
32 };
33