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遗传算法解析的更多相关文章

  1. 基于GA遗传算法的TSP旅行商问题求解

    import random import math import matplotlib.pyplot as plt import city class no: #该类表示每个点的坐标 def __in ...

  2. Android入门(二十二)解析JSON

    原文链接:http://www.orlion.ga/687/ 解析JSON的方式有很多,主要有官方提供的 JSONObject,谷歌的开源库 GSON.另外,一些第三方的开源库如 Jackson.Fa ...

  3. Android入门(二十一)解析XML

    原文链接:http://www.orlion.ga/685/ 解析XML常用的方式有两种,一种是PULL解析一种是SAX解析. 假设解析数据为: <apps>     <app> ...

  4. 进化计算简介和遗传算法的实现--AForge.NET框架的使用(六)

    原文:进化计算简介和遗传算法的实现--AForge.NET框架的使用(六) 开学了,各种忙起来了… 上一篇介绍了AForge.NET在人工神经网络上的一点点使用,但是老觉不过瘾.matlab用着实在不 ...

  5. TSP 遗传算法

    GA——遗传算法 同模拟退火算法一样,都是现代优化算法之一.模拟退火是在一定接受程度的情况下仍然接受一个比较差的解. 遗传算法,是真真正正的和大自然的遗传进化有着非常紧密的联系的,当然遗传进化的只是在 ...

  6. AI人工智能专业词汇集

    作为最早关注人工智能技术的媒体,机器之心在编译国外技术博客.论文.专家观点等内容上已经积累了超过两年多的经验.期间,从无到有,机器之心的编译团队一直在积累专业词汇.虽然有很多的文章因为专业性我们没能尽 ...

  7. XTU | 人工智能入门复习总结

    写在前面 本文严禁转载,只限于学习交流. 课件分享在这里了. 还有人工智能标准化白皮书(2018版)也一并分享了. 绪论 人工智能的定义与发展 定义 一般解释:人工智能就是用 人工的方法在 **机器( ...

  8. 曼孚科技:AI算法领域常用的39个术语(上)

    ​算法是人工智能(AI)核心领域之一. 本文整理了算法领域常用的39个术语,希望可以帮助大家更好地理解这门学科. 1. Attention 机制 Attention的本质是从关注全部到关注重点.将有限 ...

  9. 【算法】经典的ML算法(后续结合工作实践完善心得)

    18大数据挖掘的经典算法以及代码实现,涉及到了决策分类,聚类,链接挖掘,关联挖掘,模式挖掘等等方面,后面都是相应算法的博文链接,希望能够帮助大家学.目前追加了其他的一些经典的DM算法,在others的 ...

随机推荐

  1. Mvc 分页栏扩展方法

    using System; using System.Collections.Generic; using System.Reflection; using System.Text; using Sy ...

  2. CommonsChunkPlugin的一些总结

    CommonsChunkPlugin 官方文档地址 https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin new ...

  3. CSS中IE8和chrom像素百分比计算差异

    IE8中和chrome在计算像素百分比上,IE8舍一位取元素像素大小,chrome则使用四舍五入取元素像素大小: 比如:<body><div stype=“width:30%”> ...

  4. [JavaScript] js 迅雷评分效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"         "http://www ...

  5. Kaggle Competition Past Solutions

    Kaggle Competition Past Solutions We learn more from code, and from great code. Not necessarily alwa ...

  6. win7 安装SQL Server 2005 开发版 图文教程

    转自win7 安装SQL Server 2005 开发版 图文教程 ----------------------------写在安装前------------------------------ 一. ...

  7. PHP的MVC框架 深入解析

    本篇先介绍一下php的MVC实现原理,我们框架的MVC部分也是基于此原理实现的,但是今天的代码并不是框架内的代码,仅仅为说明原理     一.文件结构 建立3个文件夹 controller文件夹存放控 ...

  8. 《大数据Spark企业级实战 》

    基本信息 作者: Spark亚太研究院   王家林 丛书名:决胜大数据时代Spark全系列书籍 出版社:电子工业出版社 ISBN:9787121247446 上架时间:2015-1-6 出版日期:20 ...

  9. Oracle core06_latch&lock

    lock and latch 在oracle中为了保护共享资源,使用了两种不同的锁机制lock和latch,这两种锁有明显不同点: 1,lock和pin,采用的是队列的方式,先来先服务的策略,latc ...

  10. bzoj1927

    看到这道题不难想到费用流吧,但是怎么做呢? 一开始看到“每个点都恰好走一次”,我首先想到的有下界最小费用流, 然后发现这没有满足最大流的条件,然后又连边松弛掉多余的流 为了按照可行流的做法先减减去极大 ...