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

2023-11-01 08:40

本文主要是介绍睿智的智能优化算法4——进化策略(Evolution Strategy),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

  • 1、算法思路
    • 1.1、杂交方式
    • 1.2、基因突变
    • 1.3、淘汰低适应度个体。
  • 2、与遗传算法对比
    • 2.1、相同点:
    • 2.2、不同点:
  • 实现代码
  • GITHUB下载连接

遗传算法是一种基于达尔文进化论的与基因相关的优化算法,但由于其编码方式需要用到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_sizeself.n_kid = n_kidself.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]))# 计算fitnessself.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

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

这篇关于睿智的智能优化算法4——进化策略(Evolution Strategy)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/321821

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time