参考文章

遗传算法(Genetic Algorithm)详解与实现

遗传算法详解 附python代码实现python遗传算法重学CS的博客-CSDN博客

遗传算法

遗传算法 是模仿自然选择和繁殖的过程,为涉及搜索优化和学习的各种问题提供高质量的解决方案,类似于自然进化。

达尔文进化论是遗传算法的基础理论。

达尔文进化论的原理概括总结如下:

变异:种群中单个样本的特征(性状,属性)可能会有所不同,这导致了样本彼此之间有一定程度的差异。

遗传:某些特征可以遗传给其后代。导致后代与双亲样本具有一定程度的相似性。

选择:种群通常在给定的环境中争夺资源。更适应环境的个体在生存方面更具优势,因此会产生更多的后代。

基因型 -> 表现型 -> 基因型

进化使得适应环境的个体更加可能生存,并且繁衍后代,通过交叉、重组实现性状融合,通过变异、突变引入偶然性的变化在进化中发挥重要作用

1 遗传算法基本假设

  1. 不同的因素或者部分称为问题中的 基因

  1. 多个基因组合形成一条 染色体 染色体是问题的一个可能解

  1. 每个个体一般只有一条染色体,所以在一般的讨论中,个体 = 染色体,所以个体也是一个可能解

  1. 染色体携带基因,个体赋予染色体交叉、变异的操作可能

  1. 所有的个体组成一个种群,种群是可能解的集合

2 遗传算法编码

1 二进制编码

在大多数情况下,我们寻找的可能解都在某个区间内部,例如 x ∈[ -2 , 2 ]。在这种情况下,我们不知道要把这个区间分成多少份。

而在计算机内,所有的数字都是通过二进制来表示的。如果我们能够把变量也是用二进制来表示,那么每个浮点数都能使用一串2进制数字来表示。只要能够确定二进制和浮点数的一一对应关系即可实现编码和解码过程。

x ∈[ -2 , 2 ] 假如使用 8 位 2进制 数字串来表示 。

8 位 2进制 最多能够表示 2^8=256 个数字,相当于把区间分割为 256 - 1 =255 份。

二进制编码的显著特征就是交叉和变异的简明性和便捷性。

编码过程

编码指的是给出一个实数,转化为2进制数。

  1. 第一步,这个10进制实数是[ -2 , 2 ] 区间的一个数,为了防止出现负数,使得这个实数 x = x + xmin (xmin 是区间内的最小值),这样就将实数转化为了正数。

  1. 第二步,将这个10进制实数 x = x / L (L为区间长度),这样的目的是为了获得这个实数 x 在区间内所在的位置。或者说其大小在区间内的排名百分比。

  1. 第三步,将10进制实数 x = x * (2^8 - 1) ,来确认其落在所分割的哪个区间之内。

  1. 第四步,将10进制实数 x 转化为2 进制数,并使用字符串或者列表来存储这个数。

程序实现

import random
import numpy
X_RANGE = [-2,2]X = numpy.linspace(*X_RANGE,100)
x0 = random.choice(X)
x = x0 - X_RANGE[0]
x = x / (X_RANGE[1] - X_RANGE[0])
x = x * (2**12-1)
list = []
while x > 0:y = int(x % 2)x = x // 2list.append(y)
list = list[::-1]
x1=numpy.dot(list,2 ** numpy.arange(len(list))[::-1])/ float(2 ** len(list) - 1) * (X_RANGE[1] - X_RANGE[0]) + X_RANGE[0]
print("x0为:",x0)
print("x为",x)
print("x的二进制为",list)
print("二进制串的长度为",len(list))
print("二进制串转回十进制",x1)

这个实现有点小问题,因为在转换过程的代码有问题,在进行除法时,因为取整数的问题,导致有时候会丢失数据。(之后再想想怎么改)

解码过程

解码过程很简单,就做一个逆向的向量内积,对于一个2进制的数组[1,0,0,1,0,1,1],其对应的十进制数应该是:

在python中numpy包中有向量内积的函数 numpy.dot

nmupy.arange(a) 生成一个 [0,a)的整数向量

x1=numpy.dot(list,2 ** numpy.arange(len(list))[::-1])/ float(2 **len(list)        - 1) * (X_RANGE[1] - X_RANGE[0]) + X_RANGE[0]

交叉

每个个体只有一条染色体, 那么染色体一定可以用一串2进制的字符串来表示。

假如现在有两个个体,其二进制编码分别为

indiv1 = [1,0,0,1,1,1,0,1,0,1] # 629 -> 0.459433
indiv2 = [1,1,0,0,1,0,1,1,0,0] # 812 -> 1.174976

则对其进行交叉

randPro = random.uniform(0,1)
if randPro >= crossPro:randPoint = random.randint(0,8)temp = indiv1indiv1 = indiv1[:randPoint] + indiv2[randPoint:ranPoint+2] +               indiv1[randPoint + 2:]indiv2 = indiv2[:randPoint] + temp[randPoint:ranPoint+2] +                   indiv2[randPoint + 2:]

经过以上交叉之后,两个个体就变成了新个体。交叉的方式是但单片段交叉,通过随机数找到交叉点位,然后将紧随其后的两位一起交叉。

假如上述程序中的随机点位 randPoint = 4 ,其交叉过程为:

那么交叉成功的两个个体分别为:

newIndiv1 = [1,0,0,0,1,1,0,1,0,1] # 565 -> 0.209189
newIndiv2 = [1,1,0,1,1,0,1,1,0,0] # 876 -> 1.425220

可以看到,经过一次交叉之后,两个个体所代表的十进制数发生了变化,而且这种变化的范围相对比较随机,因为二进制变动一位可能会导致十进制变动几十甚至几百,最后映射到区间内的数字变化也会比较大。

变异

变异的原理和交叉相似,依然是随机选出一个或者多个点位,进行一个非运算。

个体的基因型

indiv = [1,0,0,1,1,1,0,1,0,1] # 629 -> 0.459433

单点变异的简单程序

randMutationPro = random.uniform(0,1)
if randMutationPro >= mutationPro:randMutationPoint = random.randint(0,11)indiv[randMutationPint] = ~indiv[randMutationPint]#indiv[randMutationPint] = indiv[randMutationPint]^1

假如randMutationPoint = 3,看一下个体的变化、

newindiv = [1,0,0,0,1,1,0,1,0,1] # 565 -> 0.209189

可以看到,一次变异可以使个体的数字变化很大,而且有时候可能和交叉具有相同的作用。

如果变异机率大,那么个体可能会有很大的概率变得和之前差距特别大,假如上述例子randMutationPoint = 0

newindiv = [0,0,0,1,1,1,0,1,0,1] # 117 -> -1.542522

可以看到新个体的表现型发生了很大的变化,这有利于跳出局部最优解,寻找全局最优解。但是变异机率过大,会导致算法收敛速度变慢。在实际问题中,变异机率一般为0.2~0.3

问题

二进制编码利于交叉变异,符合计算机处理数据的思路,但是其缺点和也很明显,缺乏精度,为了将[ -2 , 2 ] 区间映射为2进制,已经需要十位二进制。即使是这样也会产生浮点误差,损失一些精度。

目前二进制编码只能将浮点数的区间进行拆分,对特定的值进行编码。

2 浮点数编码

浮点数编码就是使用的当前的变量进行编码,不需要进行转换。例如x ∈[ -2 , 2 ],x的取值就是区间内的任意随机数。

编码与解码

根据遗传算法的理论,表现型为x ∈[ -2 , 2 ]中的任意一个值,基因型与表现型相同。 每条染色体上只有一个基因,每个个体只包含一条染色体,那么每个个体就只有一个基因。所以其编码和解码过程无需额外操作,

那么种群就可以用一个数组来表示[x1, x2, x3, x4.....,xn],每个数都是一个浮点数。

例如种群

pop = [0.23,1,58,1,93,0.45,-1,72....]

交叉

浮点数编码对于每个个体,都只是一个浮点数

indiv1 = 0.245
indiv2 = -1.289

其交叉不能类似二进制进行,而是使用因子交叉法。

randPro = random.uniform(0,1)
if randPro >= crossPro:randCross = random.uniform(0,1)temp = indiv1indiv1 = randCross * indiv1 + (1 - randCross) * indiv2indiv2 = randCross * indiv2 + (1 - randCross) * temp

假如 randCross = 0.3,交叉后的个体变为

newIndiv1 = -0.8288
newIndiv2 = -0.2152

经过交叉之后个体变化非常大。

变异

浮点数的变异一般采用加上随机数法:

这个变异没什么可说的,只有让个体加上一个随机数就可以了。

问题

浮点数编码胜在数值精确,针对浮点型问题,简单可靠。不足之处在与交叉和变异的方式还需要进一步优化,在收敛速度和寻找最优解的过程中相对较慢。

总结

遗传算法是一个很好的数学工具,通过模拟自然选择的过程,实现约束条件下寻找最优解。其独特的思维可以将表现型映射到基因型,通过交叉、变异,修改基因型,实现最优解的寻找。

二进制编码和浮点数编码各有优劣,在解决实际问题时,根据目标条件来合理选择编码方式,能够让你事半功倍。

遗传算法入门(一)编码相关推荐

  1. 遗传算法入门到掌握(一)

    遗传算法入门到掌握(一) 心得:把解决方案做染色体 遗传算法的有趣应用很多,诸如寻路问题,8数码问题,囚犯困境,动作控制,找圆心问题(这是一个国外网友的建议:在一个不规则的多边形 中,寻找一个包含在该 ...

  2. GA遗传算法入门到掌握

    遗传算法的有趣应用很多,诸如寻路问题,8数码问题,囚犯困境,动作控制,找圆心问题(这是一个国外网友的建议:在一个不规则的多边形 中,寻找一个包含在该多边形内的最大圆圈的圆心.),TSP问题(在以后的章 ...

  3. 遗传算法入门(连载之十) 神经网络入门(连载预告)

    .游戏编程中的人工智能技术 . (连载之10) .. 这是<遗传算法入门>连载的最后一篇,将对连载来源进行一些说明. 0.本连载来自<游戏编程中的人工智能技术>一书,是该书第三 ...

  4. 遗传算法入门(连载1-10)

    注:整合by Leytton     原文:http://blog.csdn.net/zzwu/article/category/243066 . (连载之一) . 扎自<游戏编程中的人工智能技 ...

  5. 大白话解析模拟退火算法、遗传算法入门

    优化算法入门系列文章目录(更新中): 1. 模拟退火算法 2. 遗传算法 一. 爬山算法 ( Hill Climbing ) 介绍模拟退火前,先介绍爬山算法.爬山算法是一种简单的贪心搜索算法,该算法每 ...

  6. 如何理解遗传算法中的编码与解码?以二进制编码为例

    文章目录 前言 编码 解码 补充 前言 遗传算法的编码方法各种各样,但二进制串编码方式是最经典的一种,那么它的编码和解码该如何进行呢?或许本博客能给你一个具有参考价值的答案. 编码 经典遗传算法中使用 ...

  7. eclipse run on server 点不了finish_分享点经验 | springboot入门及编码

    点击蓝字关注我们 AMP 很多新人在刚刚接触后端开发的时候,可能对springboot的概念.如何快速上手一个springboot项目多多少少有些一知半解:此外写出来的代码也因为不够规范而可读性较低, ...

  8. 遗传算法入门到掌握(二)

     遗传算法引擎――GenAlg           [cpp] view plaincopy <span style="font-size:16px;">/遗传算法 c ...

  9. 遗传算法 python 简书_遗传算法入门

    遗传算法简介: 遗传算法(Genetic algorithm)属于演化计算( evolutionary computing),是随着人工智能领域发展而来的一种智能算法.正如它的名字所示,遗传算法是受达 ...

最新文章

  1. InnoDB 存储引擎中的表锁和行锁详解
  2. 2021考研数学一李林4套卷整理
  3. 非常好用的两个PHP函数 serialize()和unserialize()
  4. SQL Server里的 ISNULL 与 Oracle 中的 NULLIF
  5. 合并excel文件 C语言,再见Ctrl + C!合并100个Excel表格,只需30秒!
  6. 你的网页加载太慢了怎么办?
  7. 表面上在帮女朋友拍照,其实镜头瞄准的是......
  8. Centos7.3 格式化和挂载数据盘
  9. KubeSphere配置应用路由
  10. [吴恩达机器学习笔记]14降维3-4PCA算法原理
  11. 【短文本聚类】TextCluster:短文本聚类预处理模块 Short text cluster
  12. 信息论与编码第三章课后题
  13. Xshell6 plus绿色永久版_SSH连接工具_站长必备工具集
  14. Matlab 读取.grd文件
  15. 基于PC的工业控制系统的优缺点分析
  16. 【FFMpeg】源码编译
  17. Office与visio的快速下载与安装
  18. 微信小程序一些常用标签与html的对应关系
  19. DELL笔记本电源检测功率匹配、充不进电
  20. input-file 部分手机不能拍照问题

热门文章

  1. 【Linux学习之驱动:驱动程序编译、执行】
  2. 双休日,只有发呆睡觉!
  3. 2021年最新Spring面试题,常见面试题及答案汇总
  4. 一个面向未来的数据库应使用哪些技术?
  5. 2022-2028中国滚珠轴承杆端市场现状研究分析与发展前景预测报告
  6. tskill杀进程拒绝访问的解决办法
  7. 根据经纬度数组绘制地区范围
  8. 海绵TB 117 美标焖烧阻燃性能测试
  9. textarea取值赋值
  10. python快速注释html5_P29-30《Python爬虫技术5天速成…》学习过程笔记16(超详细记录)...