1.遗传算法的简单介绍

基本思想:适者生存,基因交流

遗传算法是智能优化算法的一种,通过不断缩小解集的搜索域来寻找最优解。

先来以一个简单直观的的自然现象来掀开遗传算法的面纱。

一个叫张三的大学生回乡创业,开了个养鸡场,初期购入1000只小鸡仔(公母各半)。每只小鸡仔的状况都是未知的(把这些小鸡仔称为初始解集),长大后可能有的生蛋多,有的长得肥,有的肉质好......市场上好的肉鸡能买个好价钱(把市场需求叫目标函数),所以张三倾向于多一点肉鸡,春天到了,小鸡仔长成了大公鸡和大母鸡,张三为了能让自己的养鸡场里多获得一些好的肉鸡鸡仔,他开始想办法了。他把不同的鸡按照肉质进行分级(假设不用杀鸡就能看出肉质)。级数越高(肉质越好,即在目标函数的评价标准之下越接近最优解,适应度越高)的有更多的交配机会(优质肉的基因就有更大概率能遗传下去)。这样,下一代的鸡中的肉鸡大大增加,且肉质更好的鸡可能产生(优质肉的基因可能突变为更优质的,或者优质肉基因组合在一起变得更优质)。张三赚到了钱,就继续这样的操作,最后,肉鸡在鸡群中的比例越来越大,并且肉质逐代提高(即较优解占比提高,并向最优解靠拢)。

这个故事虽然简单,但是,我们能够看到张三清晰的解题思路即:
获取初始解集→根据目标确定适应度函数→按适应度大小给予基因遗传概率→交配带来基因的组合和突变基因的遗传→获得更好的下一代

话不多说,接下来我们就开始实践吧:

2.实战搭建遗传算法

我们会用到:python 、numpy 、matplotlib(用来画图,可以不用)

我们以鸡为出发点,来尝试培养一群有趣的飞鸡

假设我们的飞鸡能够瞬间长大,也就是根据基因直接获得适应度

我们给予飞鸡两个不同的运动方向,每个运动方向有着不同的运动速度

让他们从同一起点出发,飞向目标点,假设他们不会在途中有速度的改变

示意图如下:

我们的目标是飞鸡飞的准。

我们设置的起点坐标为(0,50),目标点坐标为(100,30)。

下面开始编程实战:

第一步编码

我们把飞鸡的两个不同的速度方向用简单的二进制编码来表示,假设单向最大速度为15,且我们只取整数,则每个速度方向我们用4位来编码,因为2的四次方减一是15。

由于比较简单,我们初始种群为10只飞鸡。注意:一般来说种群太小是极其不利的,只有10往往会过早收敛,即得出的解只是较优解。

import numpy as np
import matplotlib.pyplot as plt
start=(0,0)
end=(100,30)
def encode():raw=np.random.randint(0,2,(20,4))#生成一个20*4的矩阵,每两行确定一只飞鸡,先X后Yreturn raw

第二步计算适应度

我们的适应度很容易计算,用飞鸡在x轴运动到100时所对应的y轴量与目标点的差值来代表,当然此时要求距离越小越好,对于极端情况,比如x轴速度为零的直接淘汰。注意:一定要用到归一化,使适应度加起来是1。下一步要用。

def adapt(n):n1=np.array(range(4))n1=2**n1#n1[1 2 4 8],n1.T表示n1的转置n=n.dot(n1.T)#获取一个40*1的矩阵,每一行有一个速度分量vx=np.zeros((10,1))vy = np.zeros((10, 1))for i in range(10):vx[i]=n[2*i-1]#获取x速度vy[i]=n[2*i]#获取y速度adp=np.zeros((10,1))#生成一个新的矩阵来保存适应度for i in range(10):if vx[i]!=0:t=(end[0]-start[0])/vx[i]#飞行时间dety=abs(start[1]+t*vy[i]-(end[1]-start[1]))#距离差adp[i]=1/(dety+1)#交配概率,加一是为了避免除0else:adp[i] = 0adp=adp/sum(adp)#归一化return adp

第三步.生成下一代

生物学的研究表明,遗传与染色体的行为有着密不可分的关系。

把我们获取的初始解集中不同的编码当作染色体上不同的基因,为了操作简单,我们在这个例子中只考虑自由组合与变异,不考虑交叉,因为编码比较短,交叉意义不大。

组合方式就按随机组合,在这里我们通过不同的适应度给出不同的遗传概率,使得优秀的基因有更大的概率传给下一代

这里我们采用保留上一代中最优个体的进化方法(这样会在理论上收敛到最优解,已经被论证过了,有兴趣的读者可以去找一找证明过程。)。

def new(n,adp):byl=0.1#0.1的变异率new=np.zeros((20,4))x = np.zeros((10,4))y = np.zeros((10, 4))for i in range(10):x[i,:] = n[2 * i ,:]  # 获取xy[i,:] = n[2 * i+1,:]  # 获取ynew[0, :] = x[np.where(adp==max(adp))[0][0]]#找到上一代最优的那一个的xnew[1, :] = y[np.where(adp==max(adp))[0][0]]#找到上一代最优的那一个的yfor j in range(1,10):p1=np.random.choice(list(range(10)),1,p=adp[:,0])#x速度p2 = np.random.choice(list(range(10)),1,p=adp[:,0])#y速度new[2*j+1,:]=y[p1]new[2 * j, :] = x[p2]if np.random.randint(0,20,1)<10*byl:#变异操作k=np.random.randint(0,20,1)#20个速度(包括两个方向)中选一个进行变异new[k,0]=abs(new[k,0]-1)#将0变1,1变0,选择0号位置是为了减小误差,使变化小一些return new

第四步.重复操作,进化多代

用一个while循环,或者for循环就好

x=encode()#获取初代,不要写到循环里
for ii in range(20):#20代pp=adapt(x)#适应度x=new(x,pp)#产生新一代huitu(x)#绘图

 最后,上效果图:

可以看到,在3到4代进化后就已经趋于最优解了。而且从第二代开始有愈来愈收敛的趋势。

看起来还不错 ,但其实会出现算法早熟的情况,过早收敛,还没到最优解就进化不动了。这个图是运行了几次后才出来的。如果要避免早熟,可以把种群弄大一些。但是这个问题一共就16*16=256种可能,种群弄大了难免有随机搜索之嫌。

遗传算法要真正的使用其实还有许多要考虑的地方,比如编码肯定不是像这么简单,产生下一代的方法也不会这么简单,进化的代数一般会超过500代。但是该有的思想都在这里面了,希望能给遗传算法的初学者一点点启发。

最后贴上全部代码:

import numpy as np
import matplotlib.pyplot as plt
import timestart = (0, 0)
end = (100, 30)def encode():raw = np.random.randint(0, 2, (20, 4))  # 生成一个40*4的矩阵,每两行确定一只飞鸡,先X后Yreturn rawdef adapt(n):n1 = np.array(range(4))n1 = 2 ** n1  # n1[1 2 4 8],n1.T表示n1的转置n = n.dot(n1.T)  # 获取一个40*1的矩阵,每一行有一个速度分量vx = np.zeros((10, 1))vy = np.zeros((10, 1))for i in range(10):vx[i] = n[2 * i]  # 获取x速度vy[i] = n[2 * i + 1]  # 获取y速度adp = np.zeros((10, 1))  # 生成一个新的矩阵来保存适应度for i in range(10):if vx[i] != 0:t = (end[0] - start[0]) / vx[i]  # 飞行时间dety = abs(start[1] + t * vy[i] - (end[1] - start[1]))  # 距离差adp[i] = 1 / (dety + 1)  # 交配概率,加一是为了避免除0else:adp[i] = 0adp = adp / sum(adp)  # 归一化return adpdef new(n, adp):byl = 0.1  # 0.1的变异率new = np.zeros((20, 4))x = np.zeros((10, 4))y = np.zeros((10, 4))for i in range(10):x[i, :] = n[2 * i, :]  # 获取xy[i, :] = n[2 * i + 1, :]  # 获取ynew[0, :] = x[np.where(adp == max(adp))[0][0]]  # 找到上一代最优的那一个的xnew[1, :] = y[np.where(adp == max(adp))[0][0]]  # 找到上一代最优的那一个的yfor j in range(1, 10):p1 = np.random.choice(list(range(10)), 1, p=adp[:, 0])  # x速度p2 = np.random.choice(list(range(10)), 1, p=adp[:, 0])  # y速度new[2 * j + 1, :] = y[p1]new[2 * j, :] = x[p2]if np.random.randint(0, 20, 1) < 10 * byl:  # 变异操作k = np.random.randint(0, 20, 1)  # 20个速度(包括两个方向)中选一个进行变异new[k, 0] = abs(new[k, 0] - 1)  # 将0变1,1变0,选择0号位置是为了减小误差,使变化小一些return newdef huitu(n):n1 = np.array(range(4))n1 = 2 ** n1  # n1[1 2 4 8],n1.T表示n1的转置n = n.dot(n1.T)  # 获取一个40*1的矩阵,每一行有一个速度分量vx = np.zeros((10, 1))vy = np.zeros((10, 1))mo = np.zeros((10, 1))  # 末位置for i in range(10):vx[i] = n[2 * i]  # 获取x速度vy[i] = n[2 * i + 1]  # 获取y速度for i in range(10):if vx[i] != 0:t = (end[0] - start[0]) / vx[i]  # 飞行时间mo[i] = abs(start[1] + t * vy[i])print(mo.T)plt.scatter(start[0], start[1])plt.scatter(end[0], end[1])plt.grid()plt.ion()for i in range(10):plt.plot((0, 100), (0, mo[i, :]))plt.show()plt.pause(0.1)f = plt.gcf()  # 获取当前图像f.savefig(f'0\{str(time.time())}.png')  # 保存图像plt.clf()passx = encode()
for ii in range(20):  # 20代pp = adapt(x)x = new(x, pp)huitu(x)
n1 = np.array(range(4))
n1 = 2 ** n1  # n1[1 2 4 8],n1.T表示n1的转置
x = x.dot(n1.T)  # 获取一个40*1的矩阵,每一行有一个速度分量
print(x)

从小鸡仔开始的遗传算法相关推荐

  1. 纯CSS 写动画背景,高仿蚂蚁庄园小鸡仔

    主要使用的css3属性如下: :before :after :nth-child() animation transform: rotate(angle) transform: skew(x,y) t ...

  2. 利用双向循环链表实现长整数的存储_链表看这一篇真的就够了!

    前言 有的小伙伴说没有学过数据结构,对链表不是特别了解,所以今天我们就来对链表进行一个系统的总结,另外大家如果想提高算法思想的话,我建议还是要系统的学一下数据结构的.阅读完本文你会有以下收获1.知道什 ...

  3. python电脑安装-如何安装python

    原标题:如何安装python 地摊归来,虽然成绩不是很理想,但相信,坚持下去,不断修正过程,终会有所突破! 晚饭后,简单收拾一下,打开电脑,照例学习一会!不用学习麻醉一下,总觉的活的很心虚! 自学py ...

  4. 【Python】青少年蓝桥杯_每日一题_9.11_买鸡

    用心写好每一篇文章 一.题目背景 我国古代数学家张丘建(公元五世纪,南北朝时期)在<算经>一书中最早提出了不定方程组的数学问题,原文为∶鸡翁一值钱五,鸡母一值钱三﹐鸡雏三值钱一.百钱买百鸡 ...

  5. 十年北漂,一个软件“攻城狮”到职业养鸡人的心路历程

    本人(武建亮)IT屌丝出生, 2005年到北京,2006年开始正式成为程序员,曾任某公司的技术总监. 2011年开始创业,曾做过电子商务网站.礼品网.智慧旅游相关的创业项目. 2014年底,再一次创业 ...

  6. 电脑安装python-如何安装python

    原标题:如何安装python 地摊归来,虽然成绩不是很理想,但相信,坚持下去,不断修正过程,终会有所突破! 晚饭后,简单收拾一下,打开电脑,照例学习一会!不用学习麻醉一下,总觉的活的很心虚! 自学py ...

  7. 这只“鸭子不一般”科大讯飞申请“躺倒鸭”商标

    近日,天眼查App显示,科大讯飞股份有限公司新增申请多条"躺倒鸭"的商标信息,目前商标状态为"商标申请中". 那么"躺倒鸭"是什么呢?与科大 ...

  8. OSChina 周三乱弹 —— 程序员的专属小习惯

    2019独角兽企业重金招聘Python工程师标准>>> Osc乱弹歌单(2018)请戳(这里) [今日歌曲] @亚麻仔 :分享 JZlee;阿克江LilAkin 的歌曲<I W ...

  9. 幽默故事:1、有实力的女人;2、小小挖蕨鸡(木子家原创)

    1.我一个二货朋友跟我诉苦说:上个星期天下午陪女朋友逛街,走着走着,迎面走来一位年轻的胖女人,看上去只有一米五左右高,估计有一百五十万斤左右重,面容还算姣好,走路还很快呢,与我们擦肩而过后,我女朋友悄 ...

  10. Java最基础的算法逻辑题,新手一定要看看呀。

    1.水仙花* 需求:在控制台输出1000以内的所有""水仙花数"" 什么是水仙花数?水仙花数是个位.十位.百位的立方和等于原数的数.比如:333+777+111 ...

最新文章

  1. 读秦小波《设计模式之禅》 -- 单例模式
  2. Zabbix安装(十):监控windows进程
  3. PAT_B_1012_Java(20分)
  4. ArcGIS Server安装的几个问题
  5. delphi tclientsocket接收不到返回数据_RS—485中教你主站发送报文结构、从站返回报文结构?系列11...
  6. MySQL relay log 详细参数解释
  7. java 获取所有带指定注解的类名_SXT DAY023 反射和注解
  8. 箭头函数:this的指向问题
  9. python中的jieba分词使用手册_Python jieba结巴分词原理及用法解析
  10. visio素材:安防监控visio素材图库
  11. 中科易安:公安对接流动人口管理智能锁需要联网吗?
  12. 清爽通用工作总结汇报ppt模板免费下载_PPTX图片设计素材_包图网888pic.com
  13. matlab小波变换,图像处理
  14. 刘宇凡:海子,一个孤独的灵魂诗人
  15. nginx 代理ip 和域名
  16. 三年前,故事这样开始 三年后,故事这样延续---2015年终总结
  17. 如何在 Mac 上更改鼠标光标颜色?
  18. 【JAVA|Swing】简单表格的制作
  19. AliCoCo:阿里电商知识图谱核心技术揭秘 Alibaba E-commerce Cognitive Concept Net
  20. csdn首篇笔记——关于笔记本身

热门文章

  1. 条形码生成软件如何制作A级条码
  2. 广工Libero SoC安装教程
  3. 形象理解计算机网络里的各种抽象概念
  4. 互联网短信网关接口协议
  5. Frequent Pattern
  6. POJ-3368 Frequent values
  7. golang学习(二)—— 变量
  8. java getsystemtime,草泥马之家-使用javaAgent解除Burp的时间限制
  9. JVM之Parallel Scavenge回收器
  10. html5 input valid,javascript – 如果inputElement.validity.valid == false,如何显示HTML5验证?...