遗传算法

一、介绍

​ 遗传算法是用于解决最优化问题的一种搜索算法。遗传算法借用了生物学里达尔文的进化理论:“适者生存,优胜劣汰”,将该理论以算法的形式表现出来就是遗传算法的过程。

二、基本原理

1)程序流程

​ 遗传算法是通过大量备选解的变换、迭代和变异,在解空间中并行动态地进行全局搜索的最优化方法,是模拟生物基因遗传的做法,算法的基本原理通过编码组成的群体组成初始群体后,遗传操作的任务就算对群体的个体按照他们对环境适应度(适应度)评估,施加了一定的操作之后从而实现优胜劣汰的进化过程,算法的基本程序框图:

2)物竞天择

​ 我们可以假设有一个种群,这个种群存在的目标是帮我寻找一个函数F(x)的极值(可能是max or min),首先我们随机生成一组种群,假设我对变量x的取值范围为【0,8】,这是我们的变量域,因为我们要玩一些不一样的操作,先跟着我,后面你会恍然大悟!我们会有一个二进制域【0,2^8】,我们的二进制域对应的就是我们的变量域,我们将数字8看成8位的二进制数,可以得到2的八次方为:256,但因为我们在二进制当中我们是从0开始的,0-255,有256个数,我们的八位二进制数最多只能取到255,取不到256。

"二进制" 0 0 0 0   0 0 0 0
"二进制数 x-> " 1 1 1 1  1 1 1 1
"x转化为十进制" 1*2^0 + 1*2^1 + 1*2^2 + 1*2^3 + 1*2^4 + 1*2^5 + 1*2^6 + 1*2^7 = 255

​ 因为我们实数x的范围只有【0,8】,我们将二进制转化为十进制之后,还有求解二进制域到变量域值,二进制域变量域之间的映射关系为:

"变量域x_"  x_ = x*8/2^8

​ 如此,我们将我们的8看作是染色体的长度,这样我们就可以做一些基因重组和基因变异的操作了!!!,我们先来一组基因重组图:

​ 是不是很熟悉,这个不就是高中生物的杂交实验吗?如果我们把DDdd看成我们染色体的01呢?我们再形象一点

# 定义我们的染色体
x1 = [0 1 0 0 1 0 0 1]
x2 = [1 1 0 1 0 0 0 1]
#OK 我们现在有两个种群了(抽象一点)
# 第一个种群 x1 的染色体为 0 1 0 0  1 0 0 1
# 第一个种群 x2 的染色体为 1 1 0 1  0 0 0 1#我们尝试做一下杂交实验?学一学孟德尔的八年抗战
"第一代:" 0 1 0 0    1 0 0 1      *      1 1 0 1    0 0 0 1|                              |v                              v"配子:" [0 1 0 0]    [1 0 0 1 ]        [1 1 0 1 ]   [0 0 0 1]  #用x1的第一个配子和x2的第二个配子进行基因重组#用x1的第二个配子和x2的第一个配子进行基因重组"F1代:" [0 1 0 0][0 0 0 1]              [1 1 0 1 ][1 0 0 1] new_x1 = [0 1 0 0 0 0 0 1]
new_x2 = [1 1 0 1 1 0 0 1]# 不知道你有没有恍然大悟

​ 有了二进制的操作,我们做变异的时候也是同样的道理,我们只需要把0变异为1,1变异为0,就能完成我们的变异算法。

3)算法步骤

​ 求解函数:f(x) = 9sin(5x) + 7cos(4*x)的最大值,x的取值范围为【0,8】

3.1初始化种群

​ 我们先初始化我们的种群,先初始化一些随机解,因为我们要在搜索空间内寻找我们的最优解,可参考粒子群算法的思想。

def initpop(popsize, chromlength):"""Parameters----------popsize :  TYPE种群的数目.chromlength : TYPE表示染色体的长度(二值数的长度), 长度的大小取决于变量的二进制编码的长度     Returns -------pop : TYPE随机种群"""pop=np.round(np.random.rand(popsize,chromlength))return pop

3.2二进制编码转化为十进制数

​ 设计我们的算法,将二进制的矩阵转化为十进制数,为了得到我们的二进制域。

def decodebinary(pop):"""二进制数转十进制数函数Parameters----------pop : TYPE初始化种群.Returns-------pop2 种群的染色体二进制数转十进制数"""px,py = pop.shapepop1 = np.zeros((px,py))for i in range(py):pop1[:,i] = (2**(py-i-1))*pop[:,i]pop2=np.sum(pop1, 1)#对pop1向量的每行求和 标识位0代表每列求和,标识位1代表每行求和return pop2

​ 我们的pop2是一个转化为十进制数之后的种群,可以理解为种群的表现型,我们的0和1的操作反应的是种群的基因型,因为我们的变量不可能只有一种,扩展我们的思维,我们先设置的染色体长度,因为我们的变量只有一个,它的值域在【0,8】,如果我们有两个变量,不同变量对应不同值域,我们的染色体的长度是否也要切片计算?仔细思考。

def decodechrom(pop,spoint,length):"""将二进制编码转化为十进制数Parameters----------pop : TYPEDESCRIPTION.spoint : TYPE染色体的起始位.length : TYPEDESCRIPTION.Returns-------pop2 : TYPEDESCRIPTION."""#对于多个变量而言,如有两个变量,采用20为表示,每个变量10位,则第一个变量从1开始,另一个变量从11开始。本例为一个变量#这句话的意思就是加入目标函数需要两个变量,则我可将染色体的数量拆为两个,然后遗传迭代#值得注意的是,我的染色体的长度也要跟着变量的数量改变,呈倍数关系pop1=pop[:,spoint:spoint+length]pop2=decodebinary(pop1)return pop2

​ 这里的spoint代表的是我们的一个终止位,可以对我们的变量进行一个切片,自行理解。

3.3实现目标函数的计算

​ 实现目标函数的计算,就是把x的值带进去,很简单。

def calobjvalue(pop):"""实现目标函数的计算Parameters----------pop : TYPE种群.Returns-------objvalue : TYPE返回目标函数值."""temp = decodechrom(pop, 0, 15)x=temp*15/32767objvalue = 9*np.sin(5*x)+7*np.cos(4*x)objvalue = np.reshape(objvalue,(-1,1))#以行的形式输出return objvalue

3.4剔除0以外的值

​ 计算个体的适应值,在calobjvalue已经计算好,需要将小于0的个体删除,方便后续的概率计算。

def calfitvalue(objvalue):"""计算个体的适应值,在calobjvalue已经计算好,需要将小于0的个体删除,方便后续的概率计算Parameters----------objvalue : TYPE目标函数值.Returns-------fitvalue : TYPE个体适应值."""global CminCmin = 0fitvalue = np.zeros((objvalue.shape[0],objvalue.shape[1]))px, py = objvalue.shapefor i in range(px):if objvalue[i,0] + Cmin > 0:temp = objvalue[i,0] + Cminelse:temp = 0fitvalue[i,0]=tempreturn fitvalue

3.5选择算法

​ 选择算法我们采用轮盘赌,决定哪些个体可以进入下一代,用轮盘赌选择复制

def selection(pop, fitvalue):"""选择函数 选择复制,决定哪些个体可以进入下一代采用轮盘赌选择Parameters----------pop : TYPE种群的个体.fitvalue : TYPE个体适应值.Returns-------newpop : dict新的种群."""totalfit = np.sum(fitvalue)fitvalue_pro = fitvalue / (totalfit + 0.000001)fitvalue_pro_cumnsum = np.cumsum(fitvalue_pro)fitvalue_pro_cumnsum = np.reshape(fitvalue_pro_cumnsum,(-1,1))#以行的形式px, py = pop.shape #轮盘随机概率 从小到大排序ms = np.sort(np.random.rand(px,1),0)fitin = 1 - 1   #pop种群 第几代个体 因为python的下标从0开始。所以是第一代的索引是0 故用1-1newin = 1 - 1  #pop种群 第几代个体newpop_dict = {}#我愿称为[适者生存,优胜劣汰] while循环while newin <= px-1:if ms[newin, 0] < fitvalue_pro_cumnsum[fitin, 0]:newpop_dict[newin] = pop[fitin,:]newin += 1else:fitin += 1newpop = np.zeros((newin,py))for i in range(newin):newpop[i,:] = newpop_dict[i]return newpop

3.6交叉算法(基因重组)

​ 物竞天择是遗传学的核心,相应的,选择和变异也是遗传算法的核心,我们对染色体进行一个基因重组的操作,具体代码如下:

def crossover(pop, pc):"""交叉算法 实现基因重组Parameters----------pop : TYPE种群.pc : TYPE交叉概率.Returns-------newpop : TYPEDESCRIPTION."""px, py = pop.shape newpop = np.zeros((px, py))# seletion_litst = [i for i in range(px)]# sl = seletion_litst[0:px:2]for i in range(px-1):#是否能够进行基因重组if pc > np.random.rand(1)[0]:cpoint = int(np.round(np.random.rand(1)[0] * py) - 1)if cpoint == 0:cpoint = 1newpop[i, :][0:cpoint] = pop[i, 0:cpoint]newpop[i, :][cpoint+1:py] = pop[i+1, cpoint+1:py]newpop[i+1, :][0:cpoint] = pop[i+1, 0:cpoint]newpop[i+1, :][cpoint+1:py] = pop[i, cpoint+1:py]else:newpop[i,:] = pop[i,:]newpop[i+1,:] = pop[i+1,:]return newpop

3.7变异算法(基因突变)

​ 0变1,1变0 你上你也行

def mutation(pop, pm):"""变异算法 实现基因突变Parameters----------pop : TYPE种群.pm : TYPE变异概率.Returns-------newpop : TYPE新的变异种群."""px, py = pop.shape newpop = np.zeros((px, py))for i in range(px):if pm > np.random.rand(1)[0]:mpoint = int(np.round(np.random.rand(1)[0] * py) - 1)if mpoint == 0:mpoint = 1newpop[i,:] = pop[i,:]if newpop[i, mpoint] == 0:newpop[i, mpoint] = 1newpop[i,:] = pop[i,:]return newpop

3.7最优计算(基因突变)

​ 简单的排序取最大(不要忘记我们粒子群算法里面的全局极值和个体极值)

def best(pop, fitvalue):"""最优的个体及其适应值Parameters----------pop : TYPE种群.fitvalue : TYPE适应值.Returns-------bestindividual : 最大适应值DESCRIPTION.bestfit : TYPE最大适应值的个体."""px, py = pop.shape bestindividual = pop[0,:]bestfit = fitvalue[0]for i in range(1,px):if fitvalue[i] > bestfit:bestindividual = pop[i,:]bestfit = fitvalue[i]return bestindividual,bestfit

3.8主函数

​ 不要忘记导入我们的numpy 和matplotlib库,将上面的函数和导入的库,放在主函数的上面,然后运行代码,不过我这里的取值是【0,15】,上面说【0,8】便于读者理解。

import numpy as np
import matplotlib.pyplot as pltif __name__ == "__main__":popsize=30; #群体大小chromlength=15; #字符串长度(染色体的长度)pc=0.7; #交叉概率 pm=0.005 #变异概率#初始化种群pop=initpop(popsize, chromlength)poptest=pop#开始迭代 epoch = 500x_ = []y_ = []for i in range(epoch):objvalue = calobjvalue(pop)     #计算目标函数值fitvalue = calfitvalue(objvalue)    #计算群体中每个个体的适应度newpop = selection(pop, fitvalue)newpop1 = crossover(newpop, pc)newpop2 = mutation(newpop1, pm)objvalue = calobjvalue(newpop2)     #计算目标函数值fitvalue = calfitvalue(objvalue)    #计算群体中每个个体的适应度bestindividual,bestfit = best(newpop2, fitvalue) #求出群体中适应值最大的个体及其适应值x_.append(bestfit)# y_.append(bestfit)pop = newpop2plt.plot(x_, lw=3, label='funcotio_max_value_x')plt.show()reshape_best_infrivedual = np.reshape(bestindividual,(1,-1))#以行的形式best_x_value = encode(reshape_best_infrivedual)plt.plot(x_, lw=3, label='funcotio_max_value_x')plt.legend()plt.show()print("最好的个体是 ",bestindividual)print("函数:f(x) = 9sin(5x)+7cos(4x)的极值为 ",bestfit[0]) #最后拟合之后随便取一个值即可print("x的取值应为: ",best_x_value[0]) #最后拟合之后随便取一个值即可# plt.plot(fv2, lw=3, label='fv2')# plt.legend()# plt.show()

4)运行结果

最好的个体是 [1. 0. 0. 0. 0. 1. 1. 0. 0. 0. 0. 0. 0. 0. 0.]

函数:f(x) = 9sin(5x)+7cos(4x)的极值为 15.999199583116948

x的取值应为: 7.851802117984557

数学建模之【遗传算法】相关推荐

  1. 数学建模之遗传算法(含matlab代码)

    目录 前言 遗传算法 简介 算法主体 概括 编码格式 适应度函数 交叉操作 变异操作 各个变量设置 算法总结 问题和代码 问题 数据 matlab程序 结果展示 结语 前言 本文以面向数学建模的同学为 ...

  2. 数学建模——智能优化之遗传算法详解Python代码

    数学建模--智能优化之遗传算法详解Python代码 import numpy as np import matplotlib.pyplot as plt from matplotlib import ...

  3. 数学建模--遗传算法(从零开始学)

    学习数学建模常见算法–遗传算法. 首先,确定一下学习路线和学习资料(按照这个路线,入门非常容易,主要是人家文章写得好!): 视频:https://www.bilibili.com/video/av11 ...

  4. 【MATLAB数学建模算法代码(六)之遗传算法】

    MATLAB数学建模算法代码(六) 遗传算法: 根据自己需要修改参数即可!!! %遗传算法主程序 %Name:genmain05.m function genmain() tic; clear clf ...

  5. 数学建模:现代优化算法之遗传算法

    数学建模:现代优化算法之遗传算法 开始了开始了!!! 数学建模 数学建模:现代优化算法之遗传算法 前言 一.Genetic Algorithms(GA算法) 1.模型及算法 2.模型计算法 (1)编码 ...

  6. 数学建模——遗传算法步骤及程序详解

    数学建模--遗传算法步骤及程序详解 文章目录 数学建模--遗传算法步骤及程序详解 前言 一.遗传算法的基础 1.编码和解码 2.适应度函数 3.交叉 4.变异 5.选择 二.遗传算法原理步骤 1.初始 ...

  7. 资料分享:数学建模资料分享 -- 神经网络部分

    背景 周日的时候,为数学建模俱乐部的同学们进行了一场有关人工神经网络方面的分享.虽然在这个方面有一些积累,但过于零散,所以拿了一堆文件拼凑成整体的内容. 幸亏自己有分享的习惯,学会一些知识就写下来,这 ...

  8. 卓金武《MATLAB在数学建模中的应用》 第2版

    内容介绍 本书的作者都具有实际的数学建模参赛经历和竞赛指导经验.书中内容完全是根据数学建模竞赛的需要而编排的,涵盖了绝大部分数学建模问题的matlab求解方法.本书内容分上下两篇.上篇介绍数学建模中常 ...

  9. 数学建模上分利器,小论文中稿神器,赶快学习近15年来较新颖的智能优化算法!

    前言 关于MATLAB系列的精品专栏大家可参见 MATLAB-30天带你从入门到精通 MATLAB深入理解高级教程(附源码) 喜欢的小伙伴可自行订阅,你的支持就是我不断更新的动力哟! 相信各位无论是写 ...

  10. 还在为数学建模的事发愁?带你一起来看看数模竞赛中必备的经典算法

    前言 数学建模比赛是本科生和研究生阶段最重要的比赛之一,包括全国大学生数学建模竞赛(俗称"国赛")和美国大学生数学建模竞赛(俗称"美赛").在这些比赛中取得好成 ...

最新文章

  1. 【某小学生作文】《我的爸爸是名驾驶员》
  2. SCVMM2012 SP1 添加VMware vCenter服务器
  3. 推荐系统笔记(开源工具)
  4. CentOS 6 安装Hadoop 2.6 (二)配置Hadoop
  5. 开发必看 | iOS开发常用设计模式!
  6. js(Dom+Bom)第六天(1)
  7. redisTemplate设置key零点过期,生成自增的单号
  8. Spring构造函数依赖注入示例
  9. [Cubieboard] Node.js 在 Lubuntu 上安装指南
  10. HLSL Tips 1:如何把输入映射到输出像素
  11. 斯坦福NLP名课带学详解 | CS224n 第6讲 - 循环神经网络与语言模型(NLP通关指南·完结)
  12. 设置广告类型的html小窗口,网页两边悬浮窗广告代码
  13. 手机图形计算器matlab,Mathlab计算器安卓版
  14. 易到用车网:没有一辆车的租车公司
  15. java 日期 中文_JAVA的时间类型转换为中文大写方法
  16. 明源云预计年亏超7亿元:被花旗下调评级,“人脸识别”遭质疑
  17. 选购云服务器时云盘该如何选择?(高性能/SSD/增强型/急速型)
  18. 【每日面试】2021政采云Java一面
  19. [费用流]2018 Multi-University Contest 10 L.Videos
  20. [计算机图形学入门]9.几何

热门文章

  1. android短信到邮箱,Android_andoid打包短信发送到gmail邮箱实现代码,andriod短信整合备份发送到gmail - phpStudy...
  2. 此生不戒多巴胺-冲刺日志(第四天)
  3. CKA考试经验:报考和考纲
  4. android 照片加水印,Android 实现图片加水印或logo
  5. Postgresql error could not pull up equivalence class using projected target list (pathkeys.c:1330)
  6. 验证picard迭代c语言,用Picard迭代法解约束绳索动点坐标的数学说明
  7. 「令人心动的offer」为什么面试官不欣赏丁辉?
  8. 上海中专计算机学什么,上海十大中职学校排名表
  9. 微信公众号之模板消息跳转小程序
  10. 【Python文本处理】基于GPX文件的心率、速度、时间等参数更改