GA遗传算法解析
LinJM @HQU
谈及遗传算法,我首先想到的就是孟德尔的豌豆实验。当然,遗传算法实质上并不能用豌豆实验说明,豌豆实验探讨了分离定律和自由组合定律,而遗传算法所借鉴的并不是这两个定律。遗传算法,简单的讲,就是达尔文的适者生存的原理,当新结果的适应度比原来的适应度高,那么这个结果就保存下来,并遗传给下一代,就是把好的留下来(这个“好的”,“怎么好”,就是我们根据具体情况具体定义的)当然,这里面不仅仅是把好的结果留下来,同时还借鉴了遗传进化里面的染色体交叉和变异的想法。闲话说完,那么咱们就来看看遗传算法比较正式的说法是什么:
遗传算法是计算机科学人工智能领域中用于解决最优化的一种搜索启发式算法,是进化算法的一种。这种启发式通常用来生成有用的解决方案来优化和搜索问题。进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择以及杂交等。[1]
Genetic algorithms are a part of evolutionary computing, which is a rapidly growing area of artificial intelligence.As you can guess, genetic algorithms are inspired by Darwin's theory about evolution. Simply said, solution to a problem solved by genetic algorithms is evolved.
——————————————————————————————————————————————
对遗传算法的定义有了初步的了解后,咱们再看一下遗传算法的基本算法
begin initialize theta, P_co, P_mut, L, N-位染色体
do 确定每个染色体的适应度f_i, i=1,…,L
染色体排序
do 选择得分最高的两个染色体
if Rand[0,1) < P_co then 交叉一对随机选择的位
else 以概率P_mut改变每一位;删除父染色体
until N个子代被创建
until 任何染色体的得分都超过theta
return 最高适应度的染色体
end
其中,P_co是染色体的交叉率,P_mut是染色体的变异率,theta是适应度的阈值。
总结来说:遗传算法的基本步骤如下:
1) 在一定编码方案下,随机产生一个初始种群;
2) 用相应的解码方法,将编码后的个体转换成问题空间的决策变量,并求得个体的适应值;
3) 按照个体适应值的大小,从种群中选出适应值较大的一些个体构成交配池;
4) 由交叉和变异这两个遗传算子对交配池中的个体进行操作,并形成新一代的种群;
5) 反复执行步骤2~4 ,直至满足收敛判据为止。
使用遗传算法需要决定的运行参数有:编码串长度、种群大小、交叉和变异概率。编码串长度由优化问题所要求的求解精度决定。种群大小表示种群中所含个体的数量,种群较小时,可提高遗传算法的运算速度,但却降低了群体的多样性,可能找不出最优解;种群较大时,又会增加计算量,使遗传算法的运行效率降低。一般取种群数目为20~100。交叉概率控制着交叉操作的频率,由于交叉操作是遗传算法中产生新个体的主要方法,所以交叉概率通常应取较大值;但若过大的话,又可能破坏群体的优良模式。一般取0.4~0.99。变异概率也是影响新个体产生的一个因素,变异概率小,产生新个体少;变异概率太大,又会使遗传算法变成随机搜索。一般取变异概率为0.0001~0.1。遗传算法常采用的收敛判据有:规定遗传代数;连续几次得到的最优个体的适应值没有变化或变化很小等。
编码:
遗传算法不对优化问题的实际决策变量进行操作,所以应用遗传算法首要的问题是通过编码将决策变量表示成串结构数据。这里我们采用最常用的二进制编码方案,即用二进制数构成的符号串来表示一个个体,用下面的encoding 函数来实现编码并产生初始种群:
function [bin2gen ,bits] =encoding(min2var ,max2var ,scale2var ,popsize)
bits = ceil (log2((max2var2min2var)./scale2var) ) ;
bin2gen = randint (popsize ,sum(bits) ) ;
在上面的代码中, 首先根据各决策变量的下界(min2var)、上界(max2var)及其搜索精度scale2var来确定表示各决策变量的二进制串的长度bits,然后随机产生一个种群大小为popsize的初始种群bin2gen。编码后的实际搜索精度为scale2dec = (max2var2min2var) / (2^bits-1) ,该精度会在解码时用到。
解码
编码后的个体构成的种群bin2gen 必须经过解码,以转换成原问题空间的决策变量构成的种群var2gen ,方能计算相应的适应值。我们用下面的代码实现。
function [ var2gen ,fitness ] = decoding (funname ,bin2gen ,bits ,min2var ,max2var)
num2var = length(bits);
popsize = size (bin2gen ,1);
scale2dec = (max2var2min2var)./(2.^bits-1);
bits = cumsum(bits);
bits = [0 bits] ;
for i = 1 :num2var
bin2var{i} = bin2gen( : ,bits(i) + 1 :bits(i + 1) ) ;
var{i} = sum(ones (popsize ,1)*2.^(size(bin2var{i},2)-1:-1:0).*bin2var{i} ,2).*scale2dec (i) + min2var (i) ;
end
var2gen = [var{1 , :} ] ;
for i = 1 :popsize
fitness (i) = eval ( [funname ,’(var2gen(i , :) ) ’]) ;
end
解码函数的关键在于先由二进制数求得对应的十进制数D ,并根据下式求得实际决策变量值X:
X= D ×scale2dec + min2var
选择
选择过程是利用解码后求得的各个体适应值大小,淘汰一些较差的个体而选出一些比较优良的个体,以进行下一步的交叉和变异操作。选择算子的程序如下:
function [ evo2gen ,best2indiv ,max2fitness ] = selection ( old2gen ,fit2
ness)
popsize = length(fitness) ;
[max2fitness ,index1 ] = max (fitness) ;
[min2fitness , index2 ] =min(fitness) ;
best2indiv = old2gen(index1 , :) ;
index = [1 :popsize ] ; index(index1) = 0 ; index(index2) = 0 ;
index = nonzeros(index) ;
evo2gen = old2gen(index , :) ;
evo2fitness = fitness(index , :) ;
evo2popsize = popsize22 ;
ps = evo2fitness/ sum(evo2fitness) ;
pscum= cumsum(ps) ;
r = rand(1 ,evo2popsize) ;
selected = sum( pscum*ones (1 ,evo2popsize) < ones (evo2pop-size ,1)*r) + 1 ;
evo2gen = evo2gen(selected , :) ;
在该算子中,采用了最优保存策略和比例选择法相结合的思路,即首先找出当前群体中适应值最高和最低的个体,将最佳个体best2indiv 保留并用其替换掉最差个体。为保证当前最佳个体不被交叉、变异操作所被坏,允许其不参与交叉和变异而直接进入下一代。然后将剩下的个体evo2gen 按比例选择法进行操作。所谓比例选择法,也叫赌轮算法,是指个体被选中的概率与该个体的适应值大小成正比。将这两种方法相结合的目的是:在遗传操作中,不仅能不断提高群体的平均适应值,而且能保证最佳个体的适应值不减小。
交叉
下面采用单点交叉的方法来实现交叉算子,即按选择概率PC 在两两配对的个体编码串cpairs 中随机设置一个交叉点cpoints ,然后在该点相互交换两个配对个体的部分基因,从而形成两个新的个体。交叉算子的程序如下:
function new_gen = crossover (old_gen ,pc)
[ nouse ,mating] = sort (rand(size (old_gen ,1) ,1) ) ;
mat_gen = old_gen(mating,:) ;
pairs = size (mat_gen ,1) / 2 ;
bits = size (mat_gen ,2) ;
cpairs = rand(pairs ,1) < pc ;
cpoints = randint (pairs ,1 ,[1 ,bits]) ;
cpoints = cpairs.*cpoints ;
for i = 1 :pairs
new_gen( [2*i-1 2*i],:) = [mat_gen([2*i-1 2*i] ,1 :cpoints(i)) mat2gen([2*i 2*i-1 ] ,cpoints (i) + 1 :bits) ] ;
end
变异
对于二进制的基因串而言,变异操作就是按照变
异概率pm随机选择变异点mpoints ,在变异点处将其位
取反即可。变异算子的实现过程如下:
function new2gen = mutation (old2gen ,pm)
mpoints = find(rand(size (old2gen) ) < pm) ;
new2gen = old2gen ;
new2gen(mpoints) = 12old2gen(mpoints) ;
从上面的代码可以发现,其实遗传算法并不复杂,总共也就那么几步,因此,关键的是我们如何理解GA并应用于实际问题中。
以下是遗传算法的一些要点:
——————————————————————————————————————
- 遗传算法研究的问题是搜索候选假设空间并确定最佳假设(简单说就是找到最优结果)
- 最佳假设被定义为使适应度最优的假设:
——适应度是为当前问题预先定义的数字度量,比如:
- 如果学习任务是在给定一个未知函数的输入输出训练样例后逼近这个函数,适应度可被定义为假设在训练数据上的精度
- 如果是学习下国际象棋的策略,适应度可被定义为该个体在当前群体中与其他个体对弈的获胜率
——————————————————————————————————————
- 遗传算法具有以下的共同结构:
——算法迭代更新一个假设池,这个假设池称为群体
——在每一次迭代中,根据适应度评估群体中的所有成员,然后用概率方法选取适应度最高的个体产生新一代群体
——在被选中的个体中,一部分保持原样地进入下一代群体,其他被用作产生后代个体的基础,其中应用交叉和变异这样的遗传方法
——————————————————————————————————————
- 算法的每一次迭代以3种方式产生新一代群体
复制(replication):直接从当前群体中选择
交叉(crossover):在选中的个体中进行交叉操作
变异(mutation):在新群体上进行变异操作
- 遗传算法执行一种随机的、并行柱状的搜索,根据适应度函数发现好的假设
——————————————————————————————————————
- 遗传算法中的假设常常被表示成二进制位串,这便于用变异和交叉遗传算子来操作
- 把if-then规则编码成位串
- 首先使用位串描述单个属性的值约束
- 比如考虑属性Outlook,它的值可以取以下3个中的任一个:Sunny、Overcast、Rain,因此一个明显的方法是使用一个长度为3的位串,每位对应一个可能值,若某位为1,表示这个属性可以取对应的值
- 多个属性约束的合取可以很容易地表示为对应位串的连接
- 整个规则表示可以通过把描述规则前件和后件的位串连接起来
- 首先使用位串描述单个属性的值约束
——————————————————————————————————————
- 适应度函数定义了候选假设的排序准则
- 如果学习任务是分类的规则,那么适应度函数中会有一项用来评价每个规则对训练样例集合的分类精度,也可包含其他的准则,比如规则的复杂度和一般性
- 选择假设的概率计算方法
- 适应度比例选择(或称轮盘赌选择),选择某假设的概率是通过这个假设的适应度与当前群体中其他成员的适应度的比值得到的
- 锦标赛选择,先从当前群体中随机选取两个假设,再按照事先定义的概率p选择适应度较高的假设,按照概率1-p选择适应度较低的假设
- 排序选择,当前群体中的假设按适应度排序,某假设的概率与它在排序列表中的位置成比例,而不是与适应度成比例
GA遗传算法解析的更多相关文章
- 基于GA遗传算法的TSP旅行商问题求解
import random import math import matplotlib.pyplot as plt import city class no: #该类表示每个点的坐标 def __in ...
- Android入门(二十二)解析JSON
原文链接:http://www.orlion.ga/687/ 解析JSON的方式有很多,主要有官方提供的 JSONObject,谷歌的开源库 GSON.另外,一些第三方的开源库如 Jackson.Fa ...
- Android入门(二十一)解析XML
原文链接:http://www.orlion.ga/685/ 解析XML常用的方式有两种,一种是PULL解析一种是SAX解析. 假设解析数据为: <apps> <app> ...
- 进化计算简介和遗传算法的实现--AForge.NET框架的使用(六)
原文:进化计算简介和遗传算法的实现--AForge.NET框架的使用(六) 开学了,各种忙起来了… 上一篇介绍了AForge.NET在人工神经网络上的一点点使用,但是老觉不过瘾.matlab用着实在不 ...
- TSP 遗传算法
GA——遗传算法 同模拟退火算法一样,都是现代优化算法之一.模拟退火是在一定接受程度的情况下仍然接受一个比较差的解. 遗传算法,是真真正正的和大自然的遗传进化有着非常紧密的联系的,当然遗传进化的只是在 ...
- AI人工智能专业词汇集
作为最早关注人工智能技术的媒体,机器之心在编译国外技术博客.论文.专家观点等内容上已经积累了超过两年多的经验.期间,从无到有,机器之心的编译团队一直在积累专业词汇.虽然有很多的文章因为专业性我们没能尽 ...
- XTU | 人工智能入门复习总结
写在前面 本文严禁转载,只限于学习交流. 课件分享在这里了. 还有人工智能标准化白皮书(2018版)也一并分享了. 绪论 人工智能的定义与发展 定义 一般解释:人工智能就是用 人工的方法在 **机器( ...
- 曼孚科技:AI算法领域常用的39个术语(上)
算法是人工智能(AI)核心领域之一. 本文整理了算法领域常用的39个术语,希望可以帮助大家更好地理解这门学科. 1. Attention 机制 Attention的本质是从关注全部到关注重点.将有限 ...
- 【算法】经典的ML算法(后续结合工作实践完善心得)
18大数据挖掘的经典算法以及代码实现,涉及到了决策分类,聚类,链接挖掘,关联挖掘,模式挖掘等等方面,后面都是相应算法的博文链接,希望能够帮助大家学.目前追加了其他的一些经典的DM算法,在others的 ...
随机推荐
- linux下测试磁盘的读写IO速度【转】
Reference1:http://server.chinabyte.com/495/12361995.shtmlReference2:https://www.deleak.com/blog/2011 ...
- java MYSQL做分页
MySql中查询语句实现分页功能 语句: select * from 表名 where 条件 limit 要找第几页,每页多少行; import java.util.*; import java.sq ...
- 【技术贴】解决vss中提交pdf下载打开空白乱码
vss客户端需要安装一个Vss2005的补丁程序,而且之前上传的pdf文件重新删掉,再次上传进Vss中,再下载打卡就ok了. 补丁名称vs80-kb943847-x86-intl.exe 别人的csd ...
- 用 NSURProtocol 注入测试数据
在之前的几篇博文中,笔者介绍过访问异步网络的单元测试方法及如何使用模拟对象来进一步控制单元测试的范围.在今天的教程中,笔者将展示另一种方法,即:通过自定义 NSURProtocol 类来获取静态测试数 ...
- Highcharts Pie 饼图提示标签IE下重叠解决方法,及json数据绑定方法
一.提示标签重叠解决方法: series: [{ startAngle:90,//添加这个属性,就可以解决 type: 'pie', name: '充值方式' }] 不知道为什么,上述方法不行了.第一 ...
- [转贴]关于C++的抽象的一点新认识
http://my.oschina.net/fzyz999/blog/138491 关于本文 本文是笔者在阅读<C++沉思录>第0章——序幕后的一点想法,可以算作是笔记也可以算作是读后感. ...
- Android ListView内容变化后的动态刷新
ListView内容变化后的动态刷新 基本知识点: 1.更新适配器Adapter数据源 2.调用适配器Adapter的刷新方法notifyDataSetChanged() 首先需要定义ListView ...
- async await 异步编程杂记
1. async 仅仅是用了标记 方法中有异步调用(就是有await...) 2 await 用来把「当前线程」中的代码“分成片”,通过一定条件和事件回调的形式 “依次执行”. 3. await ...
- Spring-boot 配置Aop获取controller里的request中的参数以及其返回值
首先在你的Maven的pom文件里加入aop的依赖: <dependency> <groupId>org.springframework.boot</groupId> ...
- 基础算法(搜索):NOIP 2015 斗地主
Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3& ...