睿智的智能优化算法4——进化策略(Evolution Strategy)

2023-11-06

遗传算法是一种基于达尔文进化论的与基因相关的优化算法,但由于其编码方式需要用到01编码,所以其存在实数处理方面的局限性;本文将介绍遗传算法的姊妹,进化策略,其可以用于实数处理。关于什么是遗传算法,及其实现方式,大家可以关注我的另一篇博文睿智的智能优化算法2——遗传算法的python实现
在这里插入图片描述

1、算法思路

进化策略的思路与遗传算法相似,二者都是利用进化理论进行优化,即利用遗传信息一代代传承变异,通过适者生存的理论,保存适应度高的个体,得到最优解。
了解进化策略,首先要从进化策略的个体入手。
进化策略的每个个体都具有两个特点。
1、基因,通过基因进行运算可以得到每个个体的适应度。
2、变异强度,变异强度则是每次基因杂交完,基因变化的一个范围。
假设一个种群有四个个体,四个个体的参数如图所示:
在这里插入图片描述
进化策略的更新方式主要分为两个部分:
1、通过现有的种群,更新后代,其中需要经过杂交、基因突变两个过程。
2、将生成的后代与他们的父母辈合成一个种群,在其中淘汰低适应度个体。
接下来我将详细讲述杂交、基因突变、淘汰低适应度个体的过程。

1.1、杂交方式

与遗传算法不同,进化策略的杂交方式主要分为 步:
1、随机选择双亲。
2、从双亲身上分别取指定位置的基因,二者组合成为新基因。
3、从双亲身上分别取指定位置的杂交强度,二者组合成为新的变异强度。
其执行示意图如下:
在这里插入图片描述
执行代码如下所示:

# 杂交,随机选择父母
p1, p2 = np.random.choice(self.pop_size, size=2, replace=False)
# 选择杂交点
cp = np.random.randint(0, 2, self.gene_size, dtype=np.bool)
# 当前孩子基因的杂交结果
kv[cp] = self.pop['DNA'][p1, cp]
kv[~cp] = self.pop['DNA'][p2, ~cp]
# 当前孩子变异强度的杂交结果
ks[cp] = self.pop['mut_strength'][p1, cp]
ks[~cp] = self.pop['mut_strength'][p2, ~cp]

1.2、基因突变

在算法中,每次个体杂交完,都会进行一定的变异,变异的多少由个体的变异强度决定,其变异的代码如下。其中np.random.randn()满足正态分布。

# kv代表DNA,ks代表变异强度
kv += ks * np.random.randn()

变异的示意图如下:
在这里插入图片描述
由于算法最终要收敛,所以变异强度需要不断变小,但不可以低于0,变小方式如下:

# 变异强度要大于0,并且不断缩小
ks[:] = np.maximum(ks + (np.random.rand()-0.5), 0.)    

1.3、淘汰低适应度个体。

淘汰低适应度个体前首先需要合并父种群和子种群

# 进行vertical垂直叠加
for key in ['DNA', 'mut_strength']:
    self.pop[key] = np.vstack((self.pop[key], self.kids[key]))

再计算整个种群的适应度:

# 计算fitness
self.pred = F(self.pop['DNA'])
fitness = self.get_fitness()

最后对整个适应度进行,获得适应度从大到小的索引,并选择适应度最大的POP_SIZE个个体:

# 读出按照降序排列fitness的索引
max_index = np.argsort(-fitness)
# 选择适应度最大的POP_SIZE个个体
good_idx = max_index[:POP_SIZE]   
for key in ['DNA', 'mut_strength']:
    self.pop[key] = self.pop[key][good_idx]

其整体的执行过程如图所示:
在这里插入图片描述

2、与遗传算法对比

2.1、相同点:

进化策略的思路与遗传算法相似,二者都是利用进化理论进行优化,即利用遗传信息一代代传承变异,通过适者生存的理论,保存适应度高的个体,得到最优解。

2.2、不同点:

1、遗传算法采用二进制编码杂交;而进化策略使用实数。
2、遗传算法采用二进制0->1,1->实现变异;而进化策略则使用变异强度实现变异。

3、遗传算法仅需要一条编码链,用于存储个体的基因;进化策略在编码时,不仅要有实数编码链,还要有变异强度编码链。

4、遗传算法在交叉繁殖的时候,仅实现基因的交叉;进化策略则要实现两条链的交叉,父母辈的实数链交叉形成子辈的实数链,变异强度编码链交叉形成子辈的变异强度编码链。

5、遗传算法在变异时,随机选择基因段变异;进化策略则是将实数链上的实数值看作正态分布的均值μ,将变异强度编码链上变异强度值看作正态分布的标准差σ。

6、遗传算法在自然选择时,通过轮盘赌实现自然选择;进化策略则将子种群加入到父种群中,按照适应度排序,直接选出适应度最大的pop_size个个体。

实现代码

本次实现代码源自莫烦python,但我将其改成了class的形式。

import numpy as np
import matplotlib.pyplot as plt

# 每个个体的长度
GENE_SIZE = 1
# 每个基因的范围
GENE_BOUND = [0, 5]    
# 200代   
N_GENERATIONS = 200
# 种群的大小
POP_SIZE = 100          
# 每一代生成50个孩子
N_KID = 50  

# 寻找函数的最大值
def F(x): 
    return np.sin(10*x)*x + np.cos(2*x)*x    

class ES():
    def __init__(self,gene_size,pop_size,n_kid):
        # 基因长度代表字符串的长度
        self.gene_size = gene_size
        # 种群的大小代表种群中有几个个体
        self.pop_size = pop_size
        self.n_kid = n_kid
        self.init_pop()
        print(self.pop)
    # 降到一维
    def get_fitness(self): 
        return self.pred.flatten()

    # 初始化种群
    def init_pop(self):
        self.pop = dict(DNA=5 * np.random.rand(1, self.gene_size).repeat(POP_SIZE, axis=0),
           mut_strength=np.random.rand(POP_SIZE, self.gene_size))

    # 更新后代
    def make_kid(self):
        # DNA指的是当前孩子的基因
        # mut_strength指的是变异强度
        self.kids = {'DNA': np.empty((self.n_kid, self.gene_size)),
                'mut_strength': np.empty((self.n_kid, self.gene_size))}

        for kv, ks in zip(self.kids['DNA'], self.kids['mut_strength']):
            # 杂交,随机选择父母
            p1, p2 = np.random.choice(self.pop_size, size=2, replace=False)
            # 选择杂交点
            cp = np.random.randint(0, 2, self.gene_size, dtype=np.bool)
            # 当前孩子基因的杂交结果
            kv[cp] = self.pop['DNA'][p1, cp]
            kv[~cp] = self.pop['DNA'][p2, ~cp]
            # 当前孩子变异强度的杂交结果
            ks[cp] = self.pop['mut_strength'][p1, cp]
            ks[~cp] = self.pop['mut_strength'][p2, ~cp]

            # 变异强度要大于0,并且不断缩小
            ks[:] = np.maximum(ks + (np.random.rand()-0.5), 0.)    
            kv += ks * np.random.randn()
            # 截断
            kv[:] = np.clip(kv,GENE_BOUND[0],GENE_BOUND[1])   

    # 淘汰低适应度后代
    def kill_bad(self):
        # 进行vertical垂直叠加
        for key in ['DNA', 'mut_strength']:
            self.pop[key] = np.vstack((self.pop[key], self.kids[key]))

        # 计算fitness
        self.pred = F(self.pop['DNA'])
        fitness = self.get_fitness()
        
        # 读出按照降序排列fitness的索引
        max_index = np.argsort(-fitness)
        # 选择适应度最大的50个个体
        good_idx = max_index[:POP_SIZE]   
        for key in ['DNA', 'mut_strength']:
            self.pop[key] = self.pop[key][good_idx]


test1 = ES(gene_size = GENE_SIZE,pop_size = POP_SIZE,n_kid = N_KID)

plt.ion()     
x = np.linspace(*GENE_BOUND, 200)
plt.plot(x, F(x))

for _ in range(N_GENERATIONS):
    # 画图部分
    if 'sca' in globals(): sca.remove()
    sca = plt.scatter(test1.pop['DNA'], F(test1.pop['DNA']), s=200, lw=0, c='red', alpha=0.5)
    plt.pause(0.05)

    # ES更新
    kids = test1.make_kid()
    pop = test1.kill_bad()

plt.ioff(); plt.show()

GITHUB下载连接

https://github.com/bubbliiiing/Optimization_Algorithm

希望得到朋友们的喜欢。
有问题的朋友可以提问噢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

睿智的智能优化算法4——进化策略(Evolution Strategy) 的相关文章

随机推荐

  • WinCE5.0显卡驱动修改笔记

    WinCE5 0显卡驱动修改笔记公司前段时间让我在Geode上安装一个CE5 0 我把系统安装好之后发现显卡驱动不支持开发板的屏幕 我们的屏幕是800x480的 所以我只能自己动手写修改了一下驱动让它能够支持800x480 一下是我对驱动的
  • python报错code for hash md5 was not found解决方案

    因为开发机服务器不能上网 只能手动安装Python 但是装完后import hashlib出现异常 出现不支持sha256 sha512 md5等错误 现象如下 gt gt gt import hashlib ERROR root code
  • 排序算法之时间复杂度为O(N^2)的算法

    背景知识 排序算法算是比较基础的算法了 但是在面试过程中偶尔也会被问到 虽然很多语言都内置了排序函数 例如php的sort函数等等 但是还是有必要聊聊排序算法 这篇文章中将介绍时间复杂度为O N 2 的几个排序算法 本文基于从小到大排序讲解
  • react面试题(30个)

    1 React Native相对于原生的ios和Android有哪些优势 react native一套代码可以开发出跨平台app 减少了人力 节省了时间 避免了 iOS 与 Android 版本发布的时间差 开发新功能可以更迅速 等等 2
  • go语言后端调用以太坊rpc

    任务要求 使用golang作为后端语言 获取eth 私链 中的账户信息以及创建新的账号 1 启动geth geth identity aaron datadir data0 rpcport 8545 rpccorsdomain port 3
  • 分布式工程团队建设的十大教训

    转自 https www zybuluo com lsmn note 1059823 摘要 人才招聘 培养并促进分布式工程团队的发展并非一日之功 但是值得投资 Bruno提出了一些非常重要的见解 揭示了如何让团队全力以赴 而不管地理位置在哪
  • 初识springBoot

    springboot初学应该了解哪些 了解更多请看Spring Boot 初识 系列 会持续更新 Spring Boot 初识丨一 入门实战 Spring Boot 初识丨二 maven Spring Boot 初识丨三 starter S
  • springcloud搭建标配配置(参考)

    文章目录 架构图 shop parent 后端父项目 pom xml shop common 公共项目 pom xml CommonConstants UserInfo 用户对象 BusinessException 自定义异常 Common
  • SpringBoot+WebSocket+Netty实现消息推送

    实现思路 前端使用webSocket与服务端创建连接的时候 将用户ID传给服务端 服务端将用户ID与channel关联起来存储 同时将channel放入到channel组中 如果需要给所有用户发送消息 直接执行channel组的writeA
  • FusionSphere华为服务器虚拟化解决方案定位、架构、原理、应用场景

    目录 定位 应用场景 架构 原理 定位 华为fusion sphere虚拟化套件是业界领先的虚拟化解决方案 能够帮助客户解决数据中心基础设施的资源利用率低 业务上线周期时间长 数据中心能耗高等问题 应用场景 1 从应用侧来看 可应用于帮助客
  • 配置控制(自用)

    wd 123123 snh 123123
  • android开发之代理Window.Callback

    Window Callback是window类的一个内部接口 该接口包含了一系列类似于dispatchXXX和onXXX的接口 当window接收到外界状态改变的通知时 就会回调其中的相应方法 比如 当用户点击某个控件时 就会回调Windo
  • enncy-admin ant design vue 后台管理系统脚手架

    github 项目地址 https github com enncy enncy admin vue3 版本的请看我的另一个项目 https github com enncy funny blog admin 在 template 分支你可
  • Hyper-V服务开启or关闭

    1 概念 Hyper V服务是一个微软的虚拟机 所以如果要在windows上启动虚拟机的话 先需要把Hyper V服务功能关闭 2 Hyper V服务关闭 以管理员身份运行命令提示符 执行以下命令 bcdedit set hyperviso
  • BSN-DDC 基础网络关键知识点(五)跨链机制、官方 SDK 说明、开发资料汇总

    id BSN 2021 公众号 BSN研习社 2022年1月25日 区块链服务网络发展联盟 简称 BSN联盟 上线推出了 BSN DDC基础网络 并进入试商用阶段 同时 BSN DDC官网门户 ddc bsnbase com 上线发布 供D
  • C# 写入二进制文件

    试验1 using System using System IO using System Runtime Serialization Formatters Binary namespace 创建二进制文件 Serializable cla
  • 利用ChatGPT做市场营销的终极指南【建议收藏】

    ChatGPT是一种基于AI技术的语言模型 它可以与用户进行对话和交互 它被广泛应用于各个领域 包括市场营销 作为一名市场营销人员 您可以使用ChatGPT来获得创意 解决问题和生成内容 下面是190个ChatGPT提示 可帮助营销人员更好
  • C语言:数组的应用2——扫雷(递归实现地图变化)

    之前呢跟大家分享了二维数组实现的小游戏 三子棋 井字棋 大家都看懂了吗 今天给大家分享一下用数组实现的扫雷小游戏 先看看最终的效果吧 我设计的这个扫雷游戏 可以让玩家自己选择游戏难度 有简单 适中 困难三种模式 并利用递归的方式去改变地图
  • ThreadPoolExecutor类讲解

    一 ThreadPoolExecutor类讲解 1 线程池状态 五种状态 线程池 的状态 说明 RUNNING 允许提交并处理任务 SHUTDOWN 不允许提交新的任务 但是会处理完已提交的任务 STOP 不允许提交新的任务 也不会处理阻塞
  • 睿智的智能优化算法4——进化策略(Evolution Strategy)

    睿智的智能优化算法4 进化策略 Evolution Strategy 1 算法思路 1 1 杂交方式 1 2 基因突变 1 3 淘汰低适应度个体 2 与遗传算法对比 2 1 相同点 2 2 不同点 实现代码 GITHUB下载连接 遗传算法是