进化算法------代码示例

目录

    • 前言
    • 代码示例
      • 1、寻找函数最大值
      • 2、句子匹配

前言

遗传算法就是在一个解空间上,随机的给定一组解,这组解称为父亲种群,通过这组解的交叉,变异,构建出新的解,称为下一代种群,然后在目前已有的所有解中抽取表现好的解组成新的父亲种群,然后继续上面的过程,直到达到了迭代条件或者获取到了最优解。

进化算法流程框架
在这里插入图片描述
下面我们来解释下这个流程图里面的一些概念

  • 适应度

所谓的适应度,本质上可以理解为一个代价函数,或者一个规则,通过对初始种群中的个体计算适应度,能够得到对初始种群中的个体是否优劣的一个度量

  • 选择

选择操作是根据种群中的个体的适应度函数值所度量的优、劣程度决定它在下一代是被淘汰还是被遗传

  • 交叉
    交叉操作是将选择的两个个体p1和 p2
    作为父母节点,将两者的部分码值进行交换。假设有下面的两个节点的二进制编码表示:
    在这里插入图片描述
    随机产生一个1到7之间的随机数,假设为3,则将p1和 p2的低三位进行互换,如下图所示,就完成了交叉操作:
    在这里插入图片描述
  • 变异
    变异操作就是改变一个DNA序列上某一个点,
    在这里插入图片描述
    我们以一定的概率进行变异的操作,例如上方的DNA序列的第6个结点,由1变成了0
    在这里插入图片描述

代码示例

1、寻找函数最大值

在这里插入图片描述

首先我们生成POP_SIZE个长度为DNA_SIZE的DNA序列
在这里插入图片描述

pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE))

定义函数图像

def F(x):"""定义一个函数,就是图像中的线条:param x::return:"""return np.sin(10*x)*x + np.cos(2*x)*x     # to find the maximum of this function

我们可以将DNA转换为函数中x轴中的某个点,将0 1 DNA序列翻译成范围在(0, 5)的数字

def translateDNA(pop):"""将0 1 DNA序列翻译成范围在(0, 5)的数字:param pop::return:"""return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2**DNA_SIZE-1) * X_BOUND[1]

x轴上对应的y轴上的值,我们将其称为适应度

def get_fitness(pred):"""获取个体的适用度:param pred::return:"""return pred + 1e-3 - np.min(pred)   #防止适应度为负数

我们从种群中选择个体
注意: 并不是每次都选择适应度最高的个体,只是适应度高的个体选择的概率比较大,其它适应度较低的个体,选择的概率小,将来适应度低的个体变异后,适应度可能会变大

def select(pop, fitness):    # nature selection wrt pop's fitness"""从种群中选择:param pop::param fitness::return: 所选个体的下标,可重复选择replace=True"""idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,p=fitness/fitness.sum())return pop[idx]pop = select(pop, fitness)

之后我们对选择后的种群进行交叉和变异


def crossover(parent, pop):     # mating process (genes crossover)"""交叉配对:param parent::param pop::return:"""if np.random.rand() < CROSS_RATE:i_ = np.random.randint(0, POP_SIZE, size=1)                             # select another individual from pop 从种群中选择一个个体,cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool_)   # choose crossover points  生成要交叉的位置parent[cross_points] = pop[i_, cross_points]                            # mating and produce one child   进行交叉return parentdef mutate(child):"""变异:param child::return:"""for point in range(DNA_SIZE):if np.random.rand() < MUTATION_RATE:child[point] = 1 if child[point] == 0 else 0return child# 复制一个副本pop_copy = pop.copy()# 进行遗传 和变异for parent in pop:child = crossover(parent, pop_copy)child = mutate(child)parent[:] = child  # parent is replaced by its child 父亲个体被孩子代替

最后,我们对其迭代多次

    for _ in range(N_GENERATIONS):# 得到图像上的y值F_values = F(translateDNA(pop))# 更新散点图if 'sca' in globals(): sca.remove()sca = plt.scatter(translateDNA(pop), F_values, s=200, lw=0, c='red', alpha=0.5)plt.pause(0.1)# 获取每一个个体的适应度fitness = get_fitness(F_values)#获取最好适用度的个体下标i = np.argmax(fitness)print("最优DNA",pop[i,:])pop = select(pop, fitness)# 复制一个副本pop_copy = pop.copy()# 进行遗传 和变异for parent in pop:child = crossover(parent, pop_copy)child = mutate(child)parent[:] = child  # parent is replaced by its child 父亲个体被孩子代替

完整代码:

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import timeimport numpy as np
import matplotlib.pyplot as pltDNA_SIZE = 10            # DNA length  DNA长度
POP_SIZE = 100           # population size  种群大小
CROSS_RATE = 0.8         # mating probability (DNA crossover)  交叉配对的概率
MUTATION_RATE = 0.003    # mutation probability  编译的概率
N_GENERATIONS = 200     #   代数
X_BOUND = [0, 5]         # x upper and lower bounds   x轴范围def F(x):"""定义一个函数,就是图像中的线条:param x::return:"""return np.sin(10*x)*x + np.cos(2*x)*x     # to find the maximum of this functiondef get_fitness(pred):"""获取个体的适用度:param pred::return:"""return pred + 1e-3 - np.min(pred)   #防止适应度为负数
def translateDNA(pop):"""将0 1 DNA序列翻译成范围在(0, 5)的数字:param pop::return:"""return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2**DNA_SIZE-1) * X_BOUND[1]def select(pop, fitness):    # nature selection wrt pop's fitness"""从种群中选择choice replace是true 那么适应度高的基因会被重复多选,达到进化的目的:param pop::param fitness::return: 所选个体的下标,可重复选择replace=True"""idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,p=fitness/fitness.sum())return pop[idx]def crossover(parent, pop):     # mating process (genes crossover)"""交叉配对:param parent::param pop::return:"""if np.random.rand() < CROSS_RATE:i_ = np.random.randint(0, POP_SIZE, size=1)                             # select another individual from pop 从种群中选择一个个体,cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool_)   # choose crossover points  生成要交叉的位置parent[cross_points] = pop[i_, cross_points]                            # mating and produce one child   进行交叉return parentdef mutate(child):"""变异:param child::return:"""for point in range(DNA_SIZE):if np.random.rand() < MUTATION_RATE:child[point] = 1 if child[point] == 0 else 0return childif __name__ == '__main__':# initialize the pop DNA   s生成0-1的POP_SIZE行 DNA_SIZE列的种群pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE))plt.ion()  # something about plotting# x轴x = np.linspace(*X_BOUND, 200)plt.plot(x, F(x))# 迭代N_GENERATIONS次for _ in range(N_GENERATIONS):# 得到图像上的y值F_values = F(translateDNA(pop))# 更新散点图if 'sca' in globals(): sca.remove()sca = plt.scatter(translateDNA(pop), F_values, s=200, lw=0, c='red', alpha=0.5)plt.pause(0.1)# 获取每一个个体的适应度fitness = get_fitness(F_values)#获取最好适用度的个体下标i = np.argmax(fitness)print("最优DNA",pop[i,:])pop = select(pop, fitness)# 复制一个副本pop_copy = pop.copy()# 进行遗传 和变异for parent in pop:child = crossover(parent, pop_copy)child = mutate(child)parent[:] = child  # parent is replaced by its child 父亲个体被孩子代替plt.ioff()plt.show()

2、句子匹配

在这里插入图片描述
句子匹配与寻找函数最大值的区别就是DNA的表示不同,寻找函数最大值的DNA为0 1表示的,而句子匹配将字母转换为ASCII表示,多个字母组成的ASCII序列就表示为DNA
[ 89 111 117 32 103 101 116 32 105 116 33]ASCII翻译过来就是句子'You get it!'

其次 代码将进化算法封装到了一个类中

完整代码:

#!/usr/bin/env python 
# -*- coding:utf-8 -*-import numpy as npTARGET_PHRASE =  b'You get it!'       # target DNA 目标句子
POP_SIZE = 300                      # population size  种群大小
CROSS_RATE = 0.4                    # mating probability (DNA crossover)  交叉的概率
MUTATION_RATE = 0.01                # mutation probability   变异的概率
N_GENERATIONS = 1000                # 迭代次数DNA_SIZE = len(TARGET_PHRASE)      #DNA长度(就是句子长度)
TARGET_ASCII = np.frombuffer(TARGET_PHRASE, dtype=np.uint8)  # convert string to number   我们用ASCII代替句子中的字母并表示DNA [64,32,56....]
ASCII_BOUND = [32, 126]   #字母范围class GA(object):def __init__(self, DNA_size, DNA_bound, cross_rate, mutation_rate, pop_size):self.DNA_size = DNA_sizeDNA_bound[1] += 1self.DNA_bound = DNA_boundself.cross_rate = cross_rateself.mutate_rate = mutation_rateself.pop_size = pop_size# 随机生成pop_size行,大小为DNA_size的矩阵,即pop_size个DNA序列self.pop = np.random.randint(*DNA_bound, size=(pop_size, DNA_size)).astype(np.int8)  # int8 for convert to ASCIIdef translateDNA(self, DNA):"""将DNA翻译成字母:param DNA::return:"""return DNA.tobytes().decode('ascii')def get_fitness(self):"""计算每一个个体的适应度适应度:个体的DNA与TARGET_ASCII有多少个对应位置匹配的个数:return:"""match_count = (self.pop == TARGET_ASCII).sum(axis=1)return match_countdef select(self):"""选择个体成为新的种群可重复选择同一个个体 replace=True:return: 所选个体的下标"""fitness = self.get_fitness() + 1e-4     # 避免适应度为0,不严后面概率为0,就无法选择适应度为0的个体了idx = np.random.choice(np.arange(self.pop_size), size=self.pop_size, replace=True, p=fitness/fitness.sum())return self.pop[idx]def crossover(self, parent, pop):"""交叉配对:param parent::param pop::return:"""if np.random.rand() < self.cross_rate:i_ = np.random.randint(0, self.pop_size, size=1)                        # select another individual from popcross_points = np.random.randint(0, 2, self.DNA_size).astype(np.bool_)   # choose crossover pointsparent[cross_points] = pop[i_, cross_points]                            # mating and produce one childreturn parentdef mutate(self, child):"""变异:param child::return:"""for point in range(self.DNA_size):if np.random.rand() < self.mutate_rate:child[point] = np.random.randint(*self.DNA_bound)  # choose a random ASCII indexreturn childdef evolve(self):pop = self.select()pop_copy = pop.copy()for parent in pop:  # for every parentchild = self.crossover(parent, pop_copy)child = self.mutate(child)parent[:] = childself.pop = popif __name__ == '__main__':# 初始化ga = GA(DNA_size=DNA_SIZE, DNA_bound=ASCII_BOUND, cross_rate=CROSS_RATE,mutation_rate=MUTATION_RATE, pop_size=POP_SIZE)# 迭代多次for generation in range(N_GENERATIONS):# 得到每一个个体的适应度fitness = ga.get_fitness()# 打印显示最好的DNAbest_DNA = ga.pop[np.argmax(fitness)]best_phrase = ga.translateDNA(best_DNA)print('Gen', generation, ': ', best_phrase,best_DNA)#得到目标句子就可以结束了if best_phrase == TARGET_PHRASE:breakga.evolve()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/105542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

集成内部高端电源开关LTC3637HMSE、LTC3637MPMSE稳压器,TJA1443AT汽车CAN FD收发器。

一、LTC3637 76V、1A 降压型稳压器 &#xff08;简介&#xff09;LTC3637是一款高效率降压DC/DC稳压器&#xff0c;集成内部高端电源开关&#xff0c;功耗仅12μA DC&#xff0c;空载时可保持稳定的输出电压。LTC3637可提供高达1A的负载电流&#xff0c;并具有可编程峰值电流限…

【Redis】Java客户端使用zset命令

zadd/zrange zcard zrem zscore zrank

毅速丨模具3D打印材料有哪些选择

当前1.2709和CX是市面上最常用的3D打印模具钢材料&#xff0c;模具3D打印有没有更多的材料选择呢&#xff1f; 据了解&#xff0c;上海毅速推出的几款3D打印新材料正在被越来越多的行业所采用。如毅速的EM191S高性能高抛光不锈钢粉末&#xff0c;这款材料的抗开裂和耐腐蚀性能是…

Python学习基础笔记七十——模块和库1

模块和库&#xff1a; 一个python代码文件就实现了功能。功能比较单一。 在企业中&#xff0c;项目开发的文件&#xff0c;可能有成百上千个。 不同的代码文件&#xff0c;实现了不同的功能模块&#xff0c;就像一块块积木一样。这些功能文件整合起来&#xff0c;实现一个完…

javascript将html中的dom元素转图片

javascript将html中的dom元素转图片 百度网盘下载html2canvas.min.js&#xff1a; 全部文件-》js插件-》 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>网页中的某个区域转图片</title></head><body styl…

Django 使用Mysql数据库

目录 Django 使用Mysql数据库本地安装Mysql数据服务安装好Pymysql服务Django配置数据库迁移各种报错无法找到mysqlclient数据库拒绝连接 Django 使用Mysql数据库 本地安装Mysql数据服务 安装好Pymysql服务 python3 -m pip install PyMySQL官方文档介绍 Django配置 官网文档 …

Ubuntu中不能使用ifconfig命令

​ 问题 打开终端使用如下命令不能运行&#xff1a; ifconfig显示如下错误: 解决方法 在VMware中的虚拟机下面打开“编辑虚拟机设置”&#xff0c;或者在已经打开的虚拟机面板上面打开“虚拟机—设置” 选择网络适配器&#xff0c;选择“NAT模式”&#xff0c;没开机的就…

微软10月补丁 | 修复103个漏洞,包括2个零日漏洞,13个严重漏洞

近日&#xff0c;微软发布了2023年10月的补丁更新&#xff0c;解决了其软件中的103个漏洞。 在这103个漏洞中&#xff0c;有13个的评级为严重漏洞&#xff0c;90个被评为重要漏洞。自9月12日以来&#xff0c;谷歌已经解决了基于chrome的Edge浏览器的18个安全漏洞。 这两个零日…

第一个C++程序

1.include指令 也称包含指令&#xff0c;可根据文件名将文件内容包含进来。包含文件类型有.h头文件、.c, .cpp ,.txt等编译器能识别的代码文件。 2.头文件 C程序头文件是以.h为后缀&#xff0c;但在文件包含时规定要去掉.h后缀&#xff0c;放入std名字空间中 若头文件是C也有…

在不安全的集群上启用 Elasticsearch Xpack 安全性

本博文详细描述如何把一个没有启动安全的 Elasticsearch 集群升级为一个带有 HTTPS 访问的启用 Elasticsearch xpack 安全的集群。 为了增强 Elasticsearch 集群的安全性&#xff0c;你需要执行完全集群重启&#xff0c;并在客户端进行一些更改。 启用身份验证后&#xff0c;所…

YOLOv5算法改进(19)— Neck网络介绍(AFPN和BiFPN)

前言:Hello大家好,我是小哥谈。Neck网络是目标检测中的一个重要组成部分,主要用于对检测器提取的特征进行进一步处理和融合,以提高检测精度。通常,Neck网络由一系列卷积层、池化层、上采样层等组成,可以将不同层次的特征进行融合,同时也可以对特征进行降维和升维操作。本…

【Rust】包和模块,文档注释,Rust格式化输出

文章目录 包和模块包 CrateRust 的标准目录结构 模块 Module用路径引用模块使用super引用模块使用self引用模块结构体和枚举的可见性 使用 use 引入模块及受限可见性基本引入方式绝对路径引入模块相对路径引入模块中的函数 避免同名引用 注释和文档文档注释包和模块级别的注释注…

【Java学习之道】线程的创建与启动

引言 如果你正在学习Java编程&#xff0c;那么你可能已经知道Java是一种多线程编程语言。多线程编程可以帮助我们更高效地利用CPU&#xff0c;同时完成多项任务。但是&#xff0c;你可能还不知道如何在Java中创建和启动线程。在本节中&#xff0c;我们将深入探讨Java中的线程创…

Windows下Qt读取系统的内存、CPU、GPU等使用信息

一、前言 在当今计算机应用广泛的领域中&#xff0c;了解系统的内存、CPU和GPU使用情况是非常重要的。对于开发人员和系统管理员来说&#xff0c;准确获取这些信息可以帮助他们优化软件性能、诊断问题并做出相应的调整。在Windows平台上实现这一目标会涉及到调用Windows系统AP…

基于springboot实现心灵治愈心理健康平台系统项目【项目源码+论文说明】

基于springboot实现心灵心理健康平台系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个心灵治愈交流平台 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论…

【SOA-KELM分类】基于海鸥算法优化核极限学习机分类研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

C++智能指针(二)——weak_ptr初探

文章目录 1. shared_ptr 存在的问题2. 使用weak_ptr2.1 初始化 weak_ptr2.2 访问数据 3. 附录4. 参考文献 1. shared_ptr 存在的问题 与 shared_ptr 的引入要解决普通指针存在的一些问题一样&#xff0c;weak_ptr 的引入&#xff0c;也是因为 shared_ptr 本身在某些情况下&…

040:mapboxGL鼠标hover更换选中feature颜色

第040个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中通过鼠标hover的方式来更换选中feature颜色。这里面利用了mousemove和mouseleave的方法,通过选中图层的feature,来设置hover的true或者false,从而通过opacity的case状态来判断透明度用哪一个值。 直接复…

微信小程序备案流程操作详解

1、2023年9月1号小程序开始必须备案了,各位小程序商城只需要按流程自主去微信小程序后台操作即可; 2、对未上架的微信小程序,从2023年9月1号开始需先备案才能上架; 3、对存量已上架的小程序,需在2024年3月31号前完成备案即可。逾期未完成备案,平台将按照备案相关规定于…

kafka安装步骤以及初步入门

安装Java sudo apt install default-jdk # 执行完直接直接查看版本就好了 java -versionhttps://blog.csdn.net/CyberSparkZ/article/details/132441191 安装zookeeper https://blog.csdn.net/supercrsky/article/details/124570611 https://blog.csdn.net/xiaozhang_man/ar…