目录
一、遗传算法的生物背景
生物在自然界中生存繁衍,显示出了其对自然环境的优异自适应能力.遗传算法(Genetic Algorithms,简称GA)就是对生物遗传和进化过程的计算机模拟.它是一种自适应全局优化概率搜索算法,于1980年左右正式诞生.
首先我们要知道,遗传算法是基于生物进化理论而产生的,因此作为遗传算法生物背景的介绍,下面的概念有必要了解:
-
种群(Population):生物进化以群体形式进行,这样的一个群体称种群;
-
个体:组成种群的单个生物;
-
基因(Gene):一个遗传因子;
-
染色体(Chromosome):包含一组的基因;
-
遗传与变异:新个体会遗传父母双方各一部分的基因,同时有一定的几率发生基因变异;
-
选择(Selection):按一定概率从种群中选择若干个体,选择过程是基于适应度的优胜劣汰;
-
交叉(Crossover):两个染色体某一相同位置处的DNA被切断,然后两者交叉组合形成两个新的 染色体;
-
编码(Coding):DNA中遗传信息的排列,是从表现型到基因型的映射;
-
解码(Decoding):基因型到表现型的映射;
按照达尔文进化理论,物种生存竞争,适者生存,对环境适应度高的、牛b的个体参与繁殖的机会比较多,后代就会越来越多,适应度低的个体参与繁殖的机会比较少,后代就会越来越少。进一步概括,就是繁殖过程,会发生基因交叉(Crossover),基因突变(Mutation).适应度(Fitness)低的个体会逐步淘汰,而适应度高的个体会越来越多.那么经过N代的自然选择后,保存下来的个体都是适应度高的,其中很可能包含那个史上适应度最高的个体.
说到这里,善于思考的你一定想到如果把适应度比作一个函数的函数值,而将n个个体比作该函数在给定区间上的部分自变量的值,那么遗传算法不就相当于搜索该区间上令函数取的最值(适应度最大)的自变量(个体)的值嘛,没错,这正是遗传算法的一方面应用,我们在后文中会有具体的实例来向你展示算法到底是怎么做到的.
二、遗传算法(GA)思想
2.1遗传算法的组成
1.编码(产生初始种群)
2.适应度函数
3.遗传算子(选择,交叉,变异)
4.运行参数
借鉴生物进化论,遗传算法将要解决的问题模拟成一个生物进化过程,通过复制,交叉,变异等操作产生下一代的解,并逐步淘汰掉适应度函数值低的解,增加适应度函数值高的解,这样进化N代后就会进化出适应度函数值很高的个体.
举个例子,用遗传算法解决"0-1背包问题"的思路:0-1背包的解可以编码成一串0-1字符串(0:不取,1:取);首先,随机产生m个0-1字符串,然后评价这些字符串作为0-1背包问题的价值的大小;再从中随机选择一部分字符串通过交叉、变异操作产生下一代m个字符串,而且价值较高的解被选中的概率比较高,这样经过n代的进化后就会产生出0-1背包的一个"近似最优解".
作为遗传算法(GA)的入门,我们应做到掌握基本遗传算法(SGA),并了解相应拓展.下面我将着重讲解基本遗传算法(SGA),兼并相应拓展
2.2编码
正如研究基因是从染色体入手的,染色体也就是基因的串,编码也就是基因的编码,需要将问题的解编码成字符串的形式才能使用遗传算法.前辈们研究出了很多种编码方法,其中最常用的编码方式是二进制编码(SGA的编码方式),即将问题的解编码成二进制位数组的形式.例如,问题的解是整数,那么可以就将其编码成二进制数组的形式.将0-1字符串作为0-1背包问题的解就属于二进制编码(例如01001就表示了2号和5号装入背包,其他的不装入).基因能够在一定意义上包含它所代表的的问题的解,不同的编码方式往往取决于问题本身.下面再简单介绍几种常用的编码方式:
1.二进制编码:正如上文说到,基本遗传算法采用二进制编码,这是将基因用0和1表示的方式
2.互换编码:(用于解决排序问题,如TSP问题和调度问题),在TSP问题中,一串基因编码用来表示遍历的城市序列,如:651234,表示六个城市,先经过城市6,再经过城市5.以此类推.
3.树形编码:(用于解决遗传规划中的演化编程或者表示),例如问题:给出多个输入和输出,要求写出一个函数使得每个输入尽可能进地映射为输出.则基因就是树形结构中的一些函数.
2.3适应度函数
适应度函数(Fitness Function):用于评价某个染色体或者个体的适应度,用f(x)表示.有时需要区分染色体的适应度函数和问题的目标函数.例如:0-1背包问题的目标函数是所取的物品的价值,但将物品价值作为染色体的适应度函数可能并不一定合适.适应度函数与目标函数是正相关的,可对目标函数做一些变形来得到适应度函数.
2.4遗传算子
遗传算子分为选择算子,交叉算子,变异算子
2.4.1选择算子
遗传算法使用选择运算对个体进行优胜劣汰操作,基本遗传算法(SGA)一种常用的选择策略是"比例选择",也就是个体被选中的概率与其适应度函数值成正比.假设群体的总个数是n,那么一个个体Xi被选中的概率就是f(Xi)/(f(X1)+f(X2)+......+f(Xn)).
比例选择的实现算法就是所谓的'轮盘赌算法'(RWS),可以简单地用以下代码表示轮盘赌算法
/*
* 按设定的概率,随机选中一个个体
* P[i]表示第i个个体被选中的概率
*/
int RWS()
{
m =0;
r =Random(0,1); //r为0至1的随机数
for(i=1;i<=N; i++)
{
/* 产生的随机数在m~m+P[i]间则认为选中了i
* 因此i被选中的概率是P[i]
*/
m=m+P[i];
if(r<=m) return i;
}
2.4.2交叉算子
所谓交叉运算,是指两个相互配对的染色体依据交叉概率Pc按照某种方式相互交换其部分基因,从而形成像个新的个体.交叉运算在GA中起关键作用,是产生新个体的主要方法.交叉的方法也有很多,基本遗传算法(SGA)主要采用单点交叉法,即选择一个交叉点,两条染色体交换部分基因,构造两条新染色体,例如:
交叉前:
染色体1: 00000|011100000000|10000
染色体2: 11100|000001111110|00101
交叉后:
染色体1: 00000|000001111110|10000
染色体2: 11100|011100000000|00101
染色体交叉是以一定概率发生的,这个概率记为Pc
另外,在这里介绍两种其他交叉方法:
1.双点交叉法:选择两个交叉点,子代基因在两个交叉点间部分来自一个父代基因,部分来自另一个父代基因,如:
交叉前:
染色体1: 01 |0010| 11|00
染色体2: 11 |0111| 01|10
交叉后:
染色体1:11 |0010| 01|00
染色体2:01 |0111| 11|10
2.基于"与/或"的交叉法:
对父代按位"与"逻辑运算产生一子代A,按位"或"逻辑运算产生另一子代B.如: