当前位置: 首页 > news >正文

遗传算法与深度学习实战——生命模拟与进化论

遗传算法与深度学习实战——生命模拟与进化论

    • 0. 前言
    • 1. 模拟进化
      • 1.1 代码实现
      • 1.2 代码改进
    • 2. 达尔文进化论
    • 3. 自然选择和适者生存
      • 3.1 适者生存
      • 3.2 进化计算中的生物学
    • 小结
    • 系列链接

0. 前言

生命模拟通过计算机模拟生物体的基本特征、遗传机制、环境互动等,试图模拟和理解生物的演化过程。我们已经学习了如何实现简单的生命模型,为了进一步提升生命模拟需要模拟进化,接下来,通过借鉴达尔文的进化论,构建升级版的生命模拟。

1. 模拟进化

在本节中,我们重用了简单生命模型的大部分代码,并对其进行修改,以模拟进化或细胞传递遗传特征的能力。在本节中,我们不再使用单一特征 strength,而是分配了三个新特征,标记为 abc。除此之外,我们还将健康特征替换为更通用的术语——适应度 (fitness)。

1.1 代码实现

(1) 更新 create_cell 函数,该函数需要接受两个输入细胞来生成一个后代。例如,在模拟开始时,没有父代细胞,则为细胞的特征设置随机值;而在有父代细胞时,子代细胞的每个特征为父代双亲特征的平均值,这种平均机制只是创建子代特征值的一种方式:

import random
import time
import matplotlib.pyplot as plt
from livelossplot import PlotLossesMUTATE_RNG = 5
MUTATE_RATE = 10def clamp(num, min_value, max_value):return max(min(num, max_value), min_value)def create_cell(parent1, parent2):if parent1 is None or parent2 is None:return dict(fitness = 0,a = random.randint(1, 100),b = random.randint(1, 100),c = random.randint(1, 100)) else:    return dict(fitness = 0,a = (parent1["a"] + parent2["a"])/2,b = (parent1["b"] + parent2["b"])/2,c = (parent1["c"] + parent2["c"])/2,) 

(2) 更新 reproduce 函数,首先,按适应度对父代细胞进行排序,然后选择前一半作为父代(选择过程),然后循环遍历所选择的父代两次(假设每个父代双亲有两个孩子),随机选择两个父代双亲进行繁殖,然后将这两个父母传递给 create_cell 函数,使用两个父母的特征获得一个新的子代。最后,通过 mutate 函数对细胞执行突变(有多种选择父代的方式,我们将在后续的学习中看到更多选择方式):

def reproduce(cells): parents = sorted(cells, key=lambda d: d['fitness'])[int(len(cells)/2):]    children = [] for i in range(len(parents)*2):mates = random.sample(parents, 2) children.append(create_cell(mates[0], mates[1]))return mutate(children)

(3) mutate 函数能够随机修改子代特征,通过使用此函数来模拟物理世界中生物体(细胞)可能发生的突变,以获取超越父母的特征。突变是进化的关键因素,也是地球上所有高级生命形式的根源:

def mutate(cells):for cell in cells:if random.randint(1,100) < MUTATE_RATE:cell["a"] = clamp(cell["a"] + random.randint(-MUTATE_RNG, MUTATE_RNG), 1, 100)cell["b"] = clamp(cell["b"] + random.randint(-MUTATE_RNG, MUTATE_RNG), 1, 100)cell["b"] = clamp(cell["b"] + random.randint(-MUTATE_RNG, MUTATE_RNG), 1, 100)      return cells

(4) 更新 evaluate 函数,使用一个简单的方程来评估特征 abc 的值,并输出细胞的适应度。该函数在特征 a 上的权重为 2,在特征 b 上的权重为一个负值,而特征 c 权重为 1。进化生命模拟的目标是优化这些特征,以获取高适应度个体。更高的适应度增加了繁殖的可能性,将鼓励更多优秀特征的传递:

def birth(offspring):return [create_cell(None, None) for i in range(offspring)]def evaluate(cells):for cell in cells:cell["fitness"] = 2 * cell["a"] - cell["b"] + cell["c"]return cells

删除 death 函数,专注于 reproduce 函数。之所以这样做,是因为我们简单地假设在繁殖后,所有的父母都不会进一步保留;因此,无需考虑细胞死亡的情况。因此,我们不再关心种群数量的增长,而是关注种群的繁衍。这个假设简化了模拟的过程我们的过程,当然,我们也可以模拟多代之间的繁殖,保留父代中的优秀个体。

(5) 最后,更新 run_generation 函数,函数首先调用 evaluate 函数,更新细胞的适应度。接下来,调用 reproduce 函数产生下一代繁殖种群。之后,再次调用 evaluate 函数更新新一代的适应度值:

def run_generation(cells):  cells = evaluate(cells)cells = reproduce(cells) cells = evaluate(cells)
return cellsgenerations = 25 #@param {type:"slider", min:1, max:25, step:1}
initial_offspring = 10 #@param {type:"slider", min:10, max:1000, step:1}
mutation_rate = 10 #@param {type:"slider", min:1, max:100, step:1}
mutation_range = 20 #@param {type:"slider", min:1, max:100, step:1}MUTATE_RNG = mutation_range
MUTATE_RATE = mutation_rate
cells = birth(initial_offspring)groups = {'Generation': ['population','avg_fitness'], 'Attrributes' : ["avg_a", "avg_b", "avg_c"]}
liveloss = PlotLosses(groups=groups)history = {}
for i in range(generations):  cells = run_generation(cells)  history["population"] = len(cells)   history["avg_fitness"] = sum([cell["fitness"] for cell in cells])/(len(cells)+1)history["avg_a"] = sum([cell["a"] for cell in cells])/(len(cells)+1) history["avg_b"] = sum([cell["b"] for cell in cells])/(len(cells)+1) history["avg_c"] = sum([cell["c"] for cell in cells])/(len(cells)+1) liveloss.update(history)liveloss.send()

代码输出如下图所示。可以看到,与上一节的模拟相比,适应度显著提高,但人口始终保持为 10 个。并且特征 abc 都得到了明显的优化,特征 a 的值明显增加,特征 b 的值明显减少,这是由于我们在适应度方程中定义的特征权重导致的结果。

模拟结果

通过将进化的概念添加到生命模拟中,可以看到适应度和特征优化之间的强相关性,使得修改后的模拟更加健壮和可扩展。事实上,进化的概念是整个进化算法类的基础。

1.2 代码改进

可以通过完成以下问题进一步理解上示生命模拟过程:

  • 修改 evaluate 函数中的适应度计算方法,重新运行模拟过程观察不同权重的优化结果
  • 在细胞中添加一个新特征 d,并相应修改相关代码
  • 将突变率 MUTATE_RATE 改为介于 01 之间的值,更改后重新运行代码,观察突变对细胞进化的影响

2. 达尔文进化论

从达尔文提出自然选择概念和理论开始,对地球上的生命如何通过遗传学分享和传递选择特征的好奇驱使我们不断探索进化理论。
达尔文于 1859 年发表了《物种起源》,这一开创性的作品颠覆了自然科学,并成为许多自然和生物科学的基础。达尔文将自然选择理论描述为:“导致所有有机生命进步的一般法则,即繁殖、突变,令强者生存、弱者死亡。”
根据这一法则,达尔文构建了他的进化理论,认为生命需要通过将更成功的特征传递给后代来繁衍。虽然他未理解细胞有丝分裂和遗传学过程,但他确实总结了多个物种中特征的选择性传递。直到 1865 年,孟德尔通过观察豌豆植物的七个特征,提出了基因遗传理论。
孟德尔使用特征来描述我们现在称为基因的东西。近 30 年后,他的工作才得到认可,遗传学领域就此诞生,此后,基因学快速发展,包括基因治疗、转基因技术等。

3. 自然选择和适者生存

3.1 适者生存

“适者生存”常常被用来定义进化和进化计算,但这个术语是由早期的自然学家赫伯特·斯宾塞首次提出的。但斯宾塞忽略了一个事实:生存只是变化的结果。达尔文很好地解释了这个概念:“生存下来的不是最强壮或最聪明的,而是对变化最敏感的物种。”进化不是发展最强壮或最适合的物种,而是能够最好地适应变化的物种。这意味着,在实际应用中,虽然我们专注于开发能产生最佳适应度的算法,我们真正的目标是发展进化性变化。
在计算中,通过应用进化性变化,确保不仅是最适合或最优秀的个体能够得以生存,这意味着需要确保种群不仅是最好的,而且是最具多样性的。鼓励多样性的种群通常能够更快地解决问题。

3.2 进化计算中的生物学

进化计算借鉴了生物学和进化理论。与神经网络将深度学习 ( Deep learning, DL) 与大脑进行类比一样,并非所有概念都完全等价。在多数情况下,能够使用类似或匹配生物学等效的概念,但为了便于理解,这些生物学概念已经被大幅简化。

小结

生命模拟利用计算机模拟来模拟生命体的行为、生长和进化过程。这些模拟可以基于简单的规则和算法,通过模拟生物个体的互动和繁殖,探索复杂系统如何从简单规则中产生出自组织和复杂性。在本节中,通过借鉴达尔文的进化论,构建了升级版的生命模拟。

系列链接

遗传算法与深度学习实战——进化深度学习
遗传算法与深度学习实战——生命模拟及其应用

相关文章:

遗传算法与深度学习实战——生命模拟与进化论

遗传算法与深度学习实战——生命模拟与进化论 0. 前言1. 模拟进化1.1 代码实现1.2 代码改进 2. 达尔文进化论3. 自然选择和适者生存3.1 适者生存3.2 进化计算中的生物学 小结系列链接 0. 前言 生命模拟通过计算机模拟生物体的基本特征、遗传机制、环境互动等&#xff0c;试图模…...

rt-thread H7 使用fdcan没有外接设备时或发送错误时线程被挂起的解决方案

一、问题查找 使用的开发版是硬石的H7芯片型号STM32H743IIT6&#xff0c;测试时发现如果外面没有连接CAN设备&#xff0c;程序调用CAN发送时会一直等待发送反馈&#xff0c;导致相关线程挂起。 在线仿真时发现是卡在can.c文件的168行_can_int_tx函数&#xff1a;rt_co…...

exptern “C“的作用,在 C 和 CPP 中分别调用 openblas 中的 gemm 为例

openblas提供的sgemm有两种方式&#xff0c;一种是通过cblas&#xff0c;另一种是直接声明并调用 sgemm_ 其中&#xff0c;cblas方式是更正规调用方法&#xff1b; 1&#xff0c;调用openblas的 sgemm 的两种方式 1.1 c语言程序中使用 sgemm hello_sgemm.c #include <st…...

如何提前预防网络威胁

一、引言 随着信息技术的迅猛进步&#xff0c;网络安全议题愈发凸显&#xff0c;成为社会各界不可忽视的重大挑战。近年来&#xff0c;一系列网络安全事件的爆发&#xff0c;如同惊雷般震撼着个人、企业及国家的安全防线&#xff0c;揭示了信息安全保护的紧迫性与复杂性。每一…...

ProviderRpc发送服务二将远程调用来的信息反序列化后调用服务方的方法,并将服务方的结果返回给发送方

在Provider的实现中&#xff0c;OnMessage函数中&#xff0c;处理接收到的连接RPC请求。将接收到的RPC请求&#xff08;包含请求的对象&#xff0c;请求方法和 请求参数&#xff09;&#xff0c;接收到这些信息之后进行反序列化。得到这些参数之后我们即将要做的事情是去调用相…...

Io 35

FIleinputStream字节输入 package File.io;import java.io.*;public class io1 {public static void main(String[] args) throws IOException {// InputStream is new FileInputStream(new File("C:\\Users\\SUI\\Desktop\\Java1\\one\\src\\kaishi"));//简化Input…...

java基础概念11-方法

一、什么是方法 方法&#xff08;method&#xff09;是程序中最小的执行单元。 方法中的程序&#xff0c;要不然就是一起执行&#xff0c;要不然就是一起不执行&#xff01;&#xff01;&#xff01; 二、方法的定义 在Java中&#xff0c;方法定义的一般格式如下&#xff1a;…...

大模型应用中的思维树(Tree of Thought)是什么?

大模型应用中的思维树&#xff08;Tree of Thought&#xff09;是什么&#xff1f; 大模型&#xff0c;特别是基于GPT&#xff08;Generative Pre-trained Transformer&#xff09;架构的模型&#xff0c;在处理复杂任务时&#xff0c;通常需要依赖某种形式的推理和决策机制。…...

学习记录(11):训练图片分类的算法

文章目录 一、卷积神经网络&#xff08;CNN&#xff09;架构1. ResNet&#xff08;Residual Networks&#xff09;2. DenseNet&#xff08;Densely Connected Convolutional Networks&#xff09;3. EfficientNet4. MobileNet 二、变换器&#xff08;Transformer&#xff09;架…...

上网防泄密,这些雷区不要碰!九招教你如何防泄密

李明&#xff1a;“最近看到不少关于信息泄露的新闻&#xff0c;真是让人担忧。咱们在工作中&#xff0c;稍有不慎就可能触碰到泄密的雷区啊。” 王芳&#xff1a;“确实&#xff0c;网络安全无小事。尤其是我们这种经常需要处理敏感信息的岗位&#xff0c;更得小心谨慎。那你…...

数据库篇--八股文学习第十五天| 一条SQL查询语句是如何执行的?,事务的四大特性有哪些?,数据库的事务隔离级别有哪些?

1、一条SQL查询语句是如何执行的&#xff1f; 答&#xff1a; 连接器:连接器负责跟客户端建立连接、获取权限、维持和管理连接。查询缓存: MySQL 拿到一个查询请求后&#xff0c;会先到查询缓存看看&#xff0c;之前是不是执行过这条语句。之前执行过的语句及其结果可能会以…...

elk + filebeat + kafka实验和RSync同步

elk filebeat kafka实验和RSync同步 elk filebeat kafka实验 filebeatkafkaELK实验的操作步骤&#xff1a; #在装有nginx的主机上解压filebeat压缩包 [roottest4 opt]# tar -xf filebeat-6.7.2-linux-x86_64.tar.gz #将解压后的压缩包更改名字 [roottest4 opt]# mv file…...

子类到底能继承父类中的哪些内容?

...

【超详细公式】曝光值(EV)、光圈(AV)、快门(TV)、感光度(SV)、照度(Lux)

文章目录 术语 E V A V T V − S V EV AV TV - SV EVAVTV−SV L u x 2.5 2 E V Lux 2.5 \times 2^{EV} Lux2.52EV通常环境光照度参照表 术语 术语全称中文名EVExposure Value曝光值AVAperture Value光圈值TVTime Value快门值SVSensitive Value感光值BVBrightness Value…...

【Java】增强for遍历集合。

增强for遍历 增强for底层就是迭代器。所有的单列集合和数组才能使用增强for遍历。 在循环过程中无法对集合中的元素进行修改。 package demo;import java.util.ArrayList; import java.util.Collection; import java.util.Iterator;public class submit {public static void …...

【Qt】管理创建子项目

新建项目 打开是这样&#xff0c;无法添加子项目 pro添加 TEMPLATE subdirs有了 点击添加子项目 其他项目-子目录项目 &#xff08;空的子项目&#xff0c;只有pro&#xff0c;无h、cpp&#xff09; 子目录名字 直接创建子目录下子项目 选择有无界面或者其他类型项目 …...

力扣——238.移动零

题目 思路 利用双指针&#xff0c;先找到第一个为0的地方指向&#xff0c;指针2指向下一个&#xff0c;指针1之前是已经处理好的数据&#xff0c;指针2进行遍历&#xff0c;遇到非零则与指针1数据交换&#xff0c;然后指针1。 代码 class Solution { public:void moveZeroes(…...

编程的魅力

在数字化时代&#xff0c;编程已不仅仅是计算机科学家的专属领地&#xff0c;它正逐渐渗透到我们生活的每一个角落&#xff0c;成为连接现实与虚拟、创新与传统的重要桥梁。编程&#xff0c;这一门融合了逻辑、创造与解决问题的艺术&#xff0c;正以其独特的魅力引领着新一轮的…...

想提升跨境电商运营?浏览器多开为你助力!

在日常生活中&#xff0c;我们在使用浏览器访问网站时&#xff0c;可能会遇到一个尴尬的情况&#xff1a;无法同时登录一个网站的多个账号。对于跨境电商卖家来说&#xff0c;这种情况更为常见。例如&#xff0c;当我们需要在亚马逊管理店铺时&#xff0c;我们可能已经使用A账号…...

使用QML的ListView自制树形结构图TreeView

背景 感觉QML自带的TreeView不是很好用&#xff0c;用在文件路径树形结构比较多&#xff0c;但是想用在自己数据里&#xff0c;就不太方便了&#xff0c;所以自己做一个。 用‘ListView里迭代ListView’的方法&#xff0c;制作树形结构&#xff0c;成果图&#xff1a; 代码…...

2.MySQL面试题之索引

1. 为什么索引要用 B树来实现呢&#xff0c;而不是 B 树&#xff1f; MySQL 选择使用 B 树来实现索引&#xff0c;而不是 B 树&#xff0c;主要是基于以下几个原因&#xff1a; 1.1 数据存储和访问效率 B 树&#xff1a;在 B 树中&#xff0c;数据和索引都存储在每个节点中。…...

复制CodeIgniter新版的array_group_by辅助函数

很需要php数组的group_by功能&#xff0c;发现codeIgniter4.5新版中已有这个辅助函数&#xff0c;但我用的codeIgniter4.14没有&#xff0c;又不想升级php等一系列东西&#xff0c;就想把把codeIgniter4.5中array_group_by函数复制过来用。 先试着把新版本的array_helper文件及…...

合并两个 ES (Elasticsearch) 的数据

要将两个 Elasticsearch 实例中的同一个索引(/test_index)的数据合并到一个实例中,你可以按照以下步骤操作: 假设 Elasticsearch 1 (ES1) 和 Elasticsearch 2 (ES2) 都有相同的索引 /test_index。希望将 ES2 中的数据合并到 ES1 中。步骤 导出 ES2 的数据:使用 Elasticse…...

Linux网络协议.之 tcp,udp,socket网络编程(四).之网络转换函数htonl,ntohs等介绍

字节转换函数 把给定系统所采用的字节序称为主机字节序&#xff0c;为了避免不同类别主机之间在数据交换时由于对于字 节序的不同而导致的差错&#xff0c;引入了网络字节序。 主机字节序到网络字节序 u_long htonl(u_long hostlong); u_short htons(u_short short); 网络字节…...

LXC和udev知识点

1 POSIX pthread_create原理 1&#xff09;fork()、pthread_create()、vfork()对应的系统调用分别是sys_fork()、sys_clone()、sys_vfork()&#xff0c;它们在内核中都是通过do_fork()实现的。 2&#xff09;系统中所有的进程都组织在init_task.tasks链表下面&#xff0c;每个进…...

基于springboot+vue+uniapp的智慧校园管理系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…...

论文辅导 | 基于概率密度估计与时序Transformer网络的风功率日前区间预测

辅导文章 模型描述 本文所提出的时序优化Transformer 结构&#xff0c;该模型从结构上看由三部分组成&#xff1a;向量映射、编码器和解码器。编码器输入为数值天气预报数据以及相应的时间编码。解码器输入为预测日之前输出功率历史数据以及相应的时间编码。这些数据在经过向量…...

金蝶云星空单据体数量汇总-分组列信息

文章目录 金蝶云星空单据体数量汇总-分组列信息BOS配置效果展示 金蝶云星空单据体数量汇总-分组列信息 BOS配置 效果展示...

树状数组基础知识以及相关习题

文章目录 什么是树状数组&#xff1f;如何理解树状数组如何理解精髓lowbit二叉树和树状数组的结构树状数组的优点树状数组模板单点修改&#xff0c;区间查询区间修改&#xff0c;单点查询区间修改&#xff0c;区间查询树状数组法线段树法 树状数组基础练习题逆序对动态求连续区…...

2023大数据-架构师案例(八)

Lambda架构 nginx &#xff08;b&#xff09; Hbase &#xff08;c&#xff09;Spark Streaming &#xff08;d&#xff09;Spark &#xff08;e&#xff09;MapReduce &#xff08;f&#xff09;ETL &#xff08;g&#xff09;MemSQL &#xff08;h&#xff09;HDFS &#x…...