目录

  • 遗传算法求解过程
    • 算法参数
    • 构建初始化种群
    • 解码(二进制>十进制)
    • 自然选择
    • 交叉
    • 变异
    • 解码(新种群>十进制)
    • 计算新种群的适应度
  • 完整代码及其可视化版本
  • 其他
    • numpy中的随机数

下面我们使用遗传算法尝试求解一元函数的最值
y=sin(x2−1)+2cos(2x),x∈[0,10]y=sin(x^2-1)+2cos(2x),x\in [0,10]y=sin(x2−1)+2cos(2x),x∈[0,10]

遗传算法求解过程

算法参数

# 种群数量
m_population = 50
# 迭代次数(种群进化代数)
epoch = 99
# 基因个数
L = 40
# 交叉概率
mp = 0.5
# 变异概率
mm = 0.01# 最大函数值
mf = 0
# 最大函数值对应的自变量
mx = 0
# 变量约束
bound = [0, 10]
# 存储每一代的最优个体
f_list = []
x_list = []

构建初始化种群

生成二进制数组,形状为(种群个体数,个体基因个数),即(m_population, L)

population = np.random.randint(0, 2, (m_population, L))

运行结果

解码(二进制>十进制)

  1. 将生成的二进制数组先转换为十进制数字,便于计算个体适应度
    二进制转十进制有多种方法,这里笔者提供一种:由于个体基因是以二进制数组的形式存在,我们先将二进制数组转换为二进制字符串,然后使用int()函数实现转换过程
for i in range(m_population):transform_middle = int(''.join(map(lambda x: str(x), population[i])), 2)
  1. 然后进行标准化。由于二进制字符串的长度为40,转化得到的十进制数字将会非常大,我们的自变量约束区域为bound=[0,10]bound=[0,10]bound=[0,10],我们将得到的十进制数字都转化到0−100-100−10之间,
    transform_[i] = bound[0] + (bound[1] - bound[0]) * transform_middle / pow(2, L)
  1. 求不同个体的的适应度
f = fun(transform_)

自然选择

这是事关重要的一步,我们知道适应度大的个体有更大的概率存活下来,如何使用代码实现这一过程?
我们使用频数来代替概率,在原来种群的基础之上,我们通过概率选择一些个体出来,数量等于原来的种群个体数量相等,这样选择出来的个体在组成一个新的种群,这样我们便完成了自然选择这一过程

bingo = np.random.choice(np.arange(m_population), m_population, True, f / sum(f))
select_populaton = population[bingo]# 生成目前种群的两个复制版本,实际上不生成也行,但是这样有利于模拟两个体的交配过程
last_gen = select_populaton
new_gen = select_populaton.copy()

交叉

交叉相当于两个个体(染色体)交配。遗传算法中有多种方式实现交叉,笔者在这里采用一种叫做单点交叉的方式

match = np.random.choice(np.arange(m_population), m_population, False)
for i in range(m_population // 2):# 种群中的个体两两结合if np.random.rand() < mp:# 以交叉概率location = np.random.randint(0, L)# 交叉点last_gen[match[i]][:location], new_gen[match[L - i - 1]][:location] = \new_gen[match[L - i - 1]][:location], last_gen[match[i]][:location]

变异

for i in range(m_population):for j in range(L):if np.random.rand() < mm:new_gen[i][j] = 1 if new_gen[i][j]==0 else 0

此时上一代繁衍基本结束,new_gen即为新一代种群

将population更新为新种群

population = new_gen

解码(新种群>十进制)

transform_1 = np.zeros(m_population)
for i in range(m_population):transform_middle = int(''.join(map(lambda x: str(x), new_gen[i])), 2)transform_1[i] = bound[0] + (bound[1] - bound[0]) * transform_middle / pow(2, L)

计算新种群的适应度

# 计算适应度
new_f = fun(transform_1) - 4
# 选择出最优的个体
mx = transform_1[np.argmax(new_f)]
# 最优适应度
mf = new_f.max()
# 将每一代最优个体及其适应度添加到数组中便于统计
f_list.append(mf)
x_list.append(mx)

运行结果

完整代码及其可视化版本

可视化,即使用matplotlib库动态绘制遗传算法求解该问题的过程,主要添加的代码如下

  1. 绘制该函数图像
  2. 以散点图的形式绘制每一代个体的最优个体及其适应度
import numpy as np
import matplotlib.pyplot as plt# 定义适应度函数
def fun(x):return np.sin(x ** 2 - 1) + 2 * np.cos(2 * x) + 4plt.ion()
inputs=np.arange(0,10,0.1)
output=[fun(i)-4 for i in inputs]
plt.plot(inputs,output)
# 种群数量
m_population = 50
# 迭代次数
epoch = 99
# 基因个数
L = 40
# 交叉概率
mp = 0.5
# 变异概率
mm = 0.01# 最大函数值
mf = 0
# 最大函数值对应的自变量
mx = 0bound = [0, 10]f_list = []
x_list = []
# 生成二进制种群
population = np.random.randint(0, 2, (m_population, L))
transform_ = np.zeros(m_population)
# 二进制>十进制,并标准化
for i in range(m_population):transform_middle = int(''.join(map(lambda x: str(x), population[i])), 2)transform_[i] = bound[0] + (bound[1] - bound[0]) * transform_middle / pow(2, L)
# 计算当前种群适应度
f = fun(transform_)
for num in range(epoch):# 自然选择bingo = np.random.choice(np.arange(m_population), m_population, True, f / sum(f))select_populaton = population[bingo]# 生成目前种群的两个复制版本,实际上不生成也行,但是这样有利于模拟两个体的交配过程last_gen = select_populatonnew_gen = select_populaton.copy()# 交叉match = np.random.choice(np.arange(m_population), m_population, False)for i in range(m_population // 2):if np.random.rand() < mp:location = np.random.randint(0, L)last_gen[match[i]][:location], new_gen[match[L - i - 1]][:location] = \new_gen[match[L - i - 1]][:location], last_gen[match[i]][:location]# 变异for i in range(m_population):for j in range(L):if np.random.rand() < mm:new_gen[i][j] = 1 - new_gen[i][j]# 现在new_gen就是新生成的种群,我们需要将其转化为十进制# 我们先生成一个空数组,然后使用它储存转化后的种群十进制transform_1 = np.zeros(m_population)for i in range(m_population):transform_middle = int(''.join(map(lambda x: str(x), new_gen[i])), 2)transform_1[i] = bound[0] + (bound[1] - bound[0]) * transform_middle / pow(2, L)# 计算适应度new_f = fun(transform_1) - 4# 选择出最优的个体mx = transform_1[np.argmax(new_f)]# 将当前的种群视为最优的种群population = new_gen# 最优适应度mf = new_f.max()f_list.append(mf)x_list.append(mx)plt.scatter(mx,mf)plt.title(f'epoch:{num+1}')plt.pause(0.1)
plt.ioff()
plt.show()print(max(x_list), max(f_list))
>>> 9.93222096441059 2.9685353661257627

运行结果

其他

numpy中的随机数

  1. np.random.randint
numpy.random.randint(low, high=None, size=None, dtype=int)

返回(low,high](low,high](low,high]之间的随机整数或形状为size的随机整数数组

  1. np.random.choice
numpy.random.choice(a, size=None, replace=True, p=None)

从一维数组a中抽取随机样本

参数 描述
size int or tuple of ints, optional 随机样本的数组形状
replace boolean, optional 表示样本是否可以重复出现
p 1-D array-like, optional 每个样本被抽取到的概率

python遗传算法(应用篇1)--求解一元函数极值相关推荐

  1. 运用遗传算法求解函数极值(fortran)

    运用遗传算法求解函数极值(fortran) 写在前面 遗传算法的前世今生 算法步骤简介 遗传算法的主体结构 开始求解: 结果显示: 最后再来说一些需要注意的地方 写在前面 这篇文章适合一些应急学习最优 ...

  2. 遗传算法求解一元函数最大值

    基于遗传算法求解一元函数最大值python 一.问题介绍 二.算法设计 2.1 类数据成员 2.2 初始化种群 2.3 转换种群编码 2.4 适应度计算 2.5 种群选择 2.6 种群交配 2.7 基 ...

  3. Python遗传算法求一元函数最大值

    Python遗传算法求一元函数最大值 前言 代码 后记 参考文献 前言 最近接触遗传算法,参考了众多例子,有些又不尽然对,所以自己边理解边修改,然后写出了下面这堆传说中的屎山... PS1:遗传算法原 ...

  4. 利用遗传算法求解函数极值

    1.利用遗传算法求解函数极值 例1 利用遗传算法求函数 f(x) = 11sin(6x) + 7cos(5x),x∈[- π,π]的最大值点. 解:在MATLAB中编制绘制函数曲线的代码,运行得到题中 ...

  5. Python机器学习基础篇三《无监督学习与预处理》

    前言 前期回顾: Python机器学习基础篇二<为什么用Python进行机器学习> 上面这篇里面写了文本和序列相关. 我们要讨论的第二种机器学习算法是无监督学习算法.无监督学习包括没有已知 ...

  6. Python深度学习篇

    Python深度学习篇一<什么是深度学习> Excerpt 在过去的几年里,人工智能(AI)一直是媒体大肆炒作的热点话题.机器学习.深度学习 和人工智能都出现在不计其数的文章中,而这些文章 ...

  7. Python深度学习篇六《深度学习用于文本和序列》

    前言 前期回顾: Python深度学习篇五<深度学习用于计算机视觉> 上面这篇里面写了计算机视觉相关. 卷积神经网络是解决视觉分类问题的最佳工具. 卷积神经网络通过学习模块化模式和概念的层 ...

  8. 使用 Python 和 OpenCV 构建 SET 求解器

    作者 | 小白 来源 | 小白学视觉 小伙伴们玩过 SET 吗?SET 是一种游戏,玩家在指定的时间竞相识别出十二张独特纸牌中的三张纸牌(或 SET)的模式.每张 SET 卡都有四个属性:形状.阴影/ ...

  9. python猜数字游戏简单-python猜数字游戏快速求解解决方案

    python猜数字游戏快速求解解决方案.使用方法: 1. 保存代码为guessall.py 2. 执行python guessall.py > result.txt 3. 打开result.tx ...

最新文章

  1. 如何使用基于组件的设计方法
  2. [13] 弧面(Arc)图形的生成算法
  3. ProjectEuler 005题
  4. 怎么实现登录之后跳转到登录之前的页面?SpringMVC+Freemarker
  5. 针对大表 设计高效的存储过程【原理篇】 附最差性能sql语句进化过程客串
  6. nagios监控服务器的搭建
  7. C/C++宏的使用总结
  8. golang安装grpc,timeout问题
  9. 10大开源文档管理系统_开源文档的5大趋势
  10. 百度宣布7nm制程AI芯片“昆仑芯2”实现量产
  11. 【Flink】Flink报错OutofMemoryError : Direct buffer memory
  12. ONNX系列二 --- 使用ONNX使Keras模型可移植
  13. BZOJ 3203 Sdoi2013 保护出题人 凸包+三分
  14. wap手机网页html5通过特殊链接移动设备:打电话,发短信,发邮件详细教程
  15. Springboot的常规属性配置和类型安全配置
  16. 扫线法快速判断凹多边形相交
  17. 华尔街持续唱多美股市场,微美全息发布VR设备领涨科技股
  18. 《 人机交互技术》第三章 交互设备
  19. IE11 zh_HANS_CN国际化问题
  20. ★如何解释特修斯之船问题?

热门文章

  1. LiLi-OM: 面向高性能固态激光雷达惯性里程计和建图系统
  2. iFunk S机械键盘游戏本登陆苏宁
  3. 多平台的思维导图软件
  4. 最长回文子串(马拉车算法)
  5. 最长回文子串——动态规划法
  6. BUUCTF:秘密文件
  7. 计算机真有趣作文,真有趣作文(五篇)
  8. 洛谷:明明的随机数,C语言
  9. 【Microsoft Azure 的1024种玩法】六十.通过Azure Virtual Machines快速搭建个人Ghost博客系统
  10. 剖析ELF文件格式的内容———文件头,段表,符号....(第三章)