差分进化算法

一、简介

差分进化(DE)是一种算法,通过创建一些随机个体,将它们与预定义的评估指标进行比较,并保留最好的个体,然后通过混合剩余个体的特征来创建新的个体,并重复这个过程来解决全局优化问题。在接下来的编码中,向大家仔细地解释这个过程。

二、代码

# 创建一个对象。
from typing import List, Dict, Tuple, Unionclass Individual:def __init__(self,parameters: Dict[str, float],score: Union[float, None] = None) -> None:super().__init__()self.parameter_values = parametersself.score = score# 该对象保存单个个体的参数和分数。具有参数的个体x=2, y=3     
parameter_value = {"x":2, "y":3}
score = 13
# 评分
def scoring(ind: Individual) -> float:return ind.parameter_values["x"] ** 2 + ind.parameter_values["y"] ** 2
# 创造一个群体并进化它们。
class Population:# 最大化方向常量MAXIMIZE = 1# 最小化方向常量MINIMIZE = -1def __init__(self,pop_size,  # 种群大小direction: int,  # 优化方向(1 表示最大化,-1 表示最小化)bounds: Dict[str, Tuple[float, float]],  # 参数的边界范围字典parameters: List[str]  # 参数名称列表) -> None:"""初始化 Population 类的实例参数:pop_size (int):种群的大小direction (int):优化的方向,1 表示最大化,-1 表示最小化bounds (Dict[str, Tuple[float, float]]):包含每个参数的边界范围的字典parameters (List[str]):参数的名称列表"""self.pop_size = pop_sizeself.direction = directionself.bounds = boundsself.parameters = parametersself.individuals: List[Individual] = []  # 存储个体的列表def _create_individual(self) -> Individual:"""内部方法,用于创建一个个体返回:Individual:创建的个体"""dict_parameters = {}  # 用于存储个体的参数值for parameter in self.parameters:# 在参数的边界范围内生成随机值param_value = random.uniform(self.bounds[parameter][0], self.bounds[parameter][1])dict_parameters[parameter] = param_valueindividual = Individual(parameters=dict_parameters)  # 创建个体对象individual.score = scoring(individual)  # 计算个体的得分return individualdef initiate(self):"""初始化种群,创建指定数量的个体并添加到 individuals 列表中"""for i in range(self.pop_size):individual = self._create_individual()self.individuals.append(individual)def get_best_individual(self) -> Individual:"""获取种群中得分最优的个体返回:Individual:得分最优的个体"""self.best_individual = max(self.individuals, key=lambda x: x.score * self.direction)return self.best_individualdef get_worst_individual(self) -> Individual:"""获取种群中得分最差的个体返回:Individual:得分最差的个体"""self.best_individual = min(self.individuals, key=lambda x: x.score * self.direction)return self.best_individualdef get_mean_score(self) -> float:"""计算种群中个体得分的平均值返回:float:个体得分的平均值"""self.mean_score = sum([ind.score for ind in self.individuals]) / len(self.individuals)return self.mean_scoredef get_std_score(self) -> float:"""计算种群中个体得分的标准差返回:float:个体得分的标准差"""self.std_score = sum([(ind.score - self.mean_score) ** 2 for ind in self.individuals]) / len(self.individuals)return self.std_scoreclass Optimization:def __init__(self, f: float, cp: float, population: Population):"""初始化 Optimization 类的实例参数:f (float):某个相关的浮点数参数cp (float):某个相关的浮点数参数population (Population):种群对象"""self.f = fself.cp = cpself.population = population@staticmethoddef _mutant_choose(population: Population) -> Tuple[Individual, Individual, Individual]:"""静态方法,从种群中选择 3 个随机个体参数:population (Population):要选择个体的种群返回:Tuple[Individual, Individual, Individual]:随机选择的 3 个个体"""# 从种群的个体列表中随机抽取 3 个个体individuals = population.individualsrandom_individuals = random.sample(individuals, 3)return tuple(random_individuals)@staticmethoddef _handle_boundaries(parameter_value: float, bounds: Tuple[float, float]) -> float:"""静态方法,处理参数值超出边界的情况参数:parameter_value (float):要检查的参数值bounds (Tuple[float, float]):参数的边界范围返回:float:处理后的参数值"""# 如果参数值大于上界,将其设为上界if parameter_value > bounds[1]:parameter_value = bounds[1]# 如果参数值小于下界,将其设为下界elif parameter_value < bounds[0]:parameter_value = bounds[0]return parameter_value@staticmethoddef _calculate_parameter(semi_parents: Tuple[Individual, Individual, Individual],parameter_name: str,bounds: Tuple[float, float],f: float) -> float:"""静态方法,根据半亲代计算试验个体的参数参数:semi_parents (Tuple[Individual, Individual, Individual]):三个半亲代个体parameter_name (str):参数的名称bounds (Tuple[float, float]):参数的边界范围f (float):某个相关的浮点数参数返回:float:计算得到的试验个体的参数值"""# 根据半亲代计算试验个体的参数trial_parameter = semi_parents[0].parameter_values[parameter_name] + \f * (semi_parents[1].parameter_values[parameter_name] -semi_parents[2].parameter_values[parameter_name])# 处理参数值超出边界的情况trial_parameter = Optimization._handle_boundaries(trial_parameter, bounds)return trial_parameterdef _mutation(self, population: Population) -> Individual:"""执行变异操作,创建试验个体参数:population (Population):要操作的种群返回:Individual:创建的试验个体"""# 选择半亲代semi_parents = Optimization._mutant_choose(population)trial_parameters = {}# 对于每个参数名称for parameter in population.parameters:# 计算试验个体的参数trial_parameter = self._calculate_parameter(semi_parents, parameter,population.bounds[parameter],self.f)trial_parameters[parameter] = trial_parameter# 创建试验个体trial_individual = Individual(parameters=trial_parameters)return trial_individualdef _crossover(self, parent: Individual, trial: Individual, parameters):"""执行交叉操作,生成子代个体参数:parent (Individual):父代个体trial (Individual):试验个体parameters (List[str]):参数列表返回:Individual:生成的子代个体"""child_parameters = {}# 对于每个参数for parameter in parameters:# 生成随机概率prob = random.random()# 根据概率决定子代参数取值来自父代还是试验个体if prob < self.cp:child_parameters[parameter] = parent.parameter_values[parameter]else:child_parameters[parameter] = trial.parameter_values[parameter]# 创建子代个体child = Individual(parameters=child_parameters)return child@staticmethod
def _selection(child: Individual, parent: Individual, direction: int) -> bool:"""执行选择操作,比较子代和父代个体的得分,并根据方向决定是否选择子代参数:child (Individual):子代个体parent (Individual):父代个体direction (int):优化方向(1 表示最大化,-1 表示最小化)返回:bool:如果子代更优(或得分相等且倾向于选择子代),则返回 True,否则返回 False"""child.score = scoring(child)# 在得分相等的情况下倾向于选择子代if direction == Population.MAXIMIZE:return child.score >= parent.scoreelse:return child.score <= parent.scoredef main(self, generations: int):"""主函数,执行多代的优化过程参数:generations (int):要执行的代数"""population = self.populationfor gen in range(generations):new_individuals = []for i in range(population.pop_size):# 变异操作trial_individual = self._mutation(population)# 交叉操作parent = population.individuals[i]child = self._crossover(parent, trial_individual, population.parameters)# 选择操作if self._selection(child, parent, self.population.direction):new_individuals.append(child)else:new_individuals.append(parent)# 用新的个体更新种群population.individuals = new_individuals# 在每一代结束时更新统计信息或执行其他必要任务best_individual = population.get_best_individual()worst_individual = population.get_worst_individual()mean_score = population.get_mean_score()std_score = population.get_std_score()# 打印或存储关于这一代的相关信息print(f"Generation {gen + 1}: Best Score - {best_individual.score}, Worst Score - {worst_individual.score}, Mean Score - {mean_score}, Std Score - {std_score}")# 完成所有代后,可以返回或执行任何最终操作final_best_individual = population.get_best_individual()print(f"Optimization complete. Best individual: {final_best_individual.parameter_values}, Score: {final_best_individual.score}")population = Population(pop_size=50,direction=Population.MINIMIZE,bounds={"x": (-100, 100), "y": (-100, 100)},parameters=["x", "y"]
)
population.initiate()optimization = Optimization(f=0.5,cp=0.7,population=population
)optimization.main(20)

三、局限性

尽管差分进化算法用途广泛,但它也并非没有缺点。这些限制中最明显的是许多元启发式算法所面临的局部最优问题。DE算法或任何遗传算法都不能保证它们找到的最佳参数就是最佳解。想象一下一个深谷,我们的人口想要穿过它,人们想要降低地面,所以他们都可能会进入山谷并被困在那里,而其他地方有一个更深的山谷。更改参数以使其更加多样化,并围绕解决方案空间采取更大的步骤可以有所帮助,但会带来性能成本。

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

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

相关文章

嵌入式c语言4——类型修饰符

register&#xff0c;将变量保存在寄存器中&#xff0c;使得访问速度增加 const是常量&#xff0c;static是静态量&#xff0c;volatile是

从0-1实现一个前端脚手架

https://gitee.com/childe-jia/kfc-cli.git gitee完整地址 介绍 为什么需要脚手架&#xff1f; 脚手架本质就是一个工具&#xff0c;作用是能够让使用者专注于写代码&#xff0c;它可以让我们只用一个命令就生成一个已经配置好的项目&#xff0c;而不用我们再花时间去配置和安…

zabbix 与 grafana 对接

一.安装 grafana 1.初始化操作 初始化操作 systemctl disable --now firewalld setenforce 0 vim /etc/selinux/config SELINUXdisabled 2.上传数据包并安装 cd /opt grafana-enterprise-9.4.7-1.x86_64.rpm #上传软件包 yum localinstall -y grafana-enterprise-9.4.7-1…

Faster R-CNN 和 YOLO 对比

Faster R-CNN 和 YOLO 是两种常用的目标检测算法&#xff0c;它们在结构、性能和适用场景上有显著的区别。以下是两者的详细对比&#xff0c;包括各自的优缺点&#xff1a; Faster R-CNN 结构和原理&#xff1a; 两阶段检测器&#xff1a;Faster R-CNN 先通过区域提议网络&a…

Javascript常见数据结构和设计模式

在JavaScript中&#xff0c;常见的数据结构包括两大类&#xff1a;原始数据类型&#xff08;Primitive Types&#xff09;和对象类型&#xff08;Object Types&#xff09;。对象类型又可以进一步细分为多种内置对象、数组、函数等。下面是一些JavaScript中常见的数据结构&…

Nginx 虚拟主机和反向代理 (同一个ip多个二级域名配置不同的前端服务)

把多个二级域名映射到不同的文件目录&#xff0c;例如 bbs.abc.com&#xff0c;映射到 html/bbs blog.abc.com 映射到 html/blog http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;server {listen 80…

PyFluent入门之旅(4)算例求解

在网格划分完成或已有网格的情况下&#xff0c;可以进行算例的求解。 1. 切换/打开求解器 一般启动求解器前有两种情况&#xff1a; 已启动FluentMeshing并生成了网格&#xff0c;需要在不退出FluentMeshing的情况下直接切换至Fluent求解器。已经有现成的网格文件&#xff0…

检测到弱密码:并非所有密码套件均支持完全前向保密解决方案

问题 检测到弱密码&#xff1a;并非所有密码套件均支持完全前向保密&#xff08;弱密码套件 - ROBOT 攻击&#xff1a;服务器支持易受攻击的密码套件&#xff09; 背景介绍 HTTP 协议自身没有加密机制&#xff0c;但可以通过与 TLS (Transport Layer Security) / SSL (Secur…

【AI资讯】快手 可灵web端上线

可灵 AI – 新一代 AI 创意生产力平台 快手 可灵web端上线了&#xff0c;目前登录即可用&#xff0c;感兴趣可以试试。

释放扩展的束缚:精通 IPython 的 %uninstall_ext 命令

释放扩展的束缚&#xff1a;精通 IPython 的 %uninstall_ext 命令 IPython&#xff0c;这个强大的交互式计算工具&#xff0c;通过扩展提供了无限的可能性。然而&#xff0c;有时候我们可能需要移除一些不再需要的扩展。本文将详细指导如何在 IPython 中使用 %uninstall_ext 命…

GitHub每日最火火火项目(7.7)

项目名称&#xff1a;microsoft / graphrag 项目介绍&#xff1a;这是一个模块化的基于图的检索增强生成&#xff08;RAG&#xff09;系统。它可能在处理和生成与图结构相关的数据方面具有强大的能力&#xff0c;能够利用图的信息来增强检索和生成的效果。该系统的模块化设计可…

90元搭建渗透/攻防利器盒子!【硬件篇】

前言 以下内容请自行思考后进行实践。 使用场景 在某些情况下开软件进行IP代理很麻烦&#xff0c;并不能实现真正全局&#xff0c;而且还老容易忘记&#xff0c;那么为了在实景工作中&#xff0c;防止蓝队猴子封IP&#xff0c;此文正现。 正文 先说一下实验效果&#xff1…

53-1 内网代理3 - Netsh端口转发(推荐)

靶场还是用上一篇文章搭建的靶场 :52-5 内网代理2 - LCX端口转发(不推荐使用LCX)-CSDN博客 一、Netsh 实现端口转发 Netsh是Windows自带的命令行脚本工具,可用于配置端口转发。在一个典型的场景中,如果我们位于公网无法直接访问内网的Web服务器,可以利用中间的跳板机通过…

【LeetCode】十三、分治法:多数元素 + 最大子序列和

文章目录 1、分治法2、leetcode169&#xff1a;多数元素3、leetcode53&#xff1a;最大子序和 1、分治法 分治一般都搭配递归使用&#xff1a; 用分治法的一个应用——归并排序&#xff1a;将一组数不停的一分为二&#xff0c;直到分到每组只有一个数的时候 分到每组只有一个数…

Python28-7.5 降维算法之t-分布邻域嵌入t-SNE

t-分布邻域嵌入&#xff08;t-distributed Stochastic Neighbor Embedding&#xff0c;t-SNE&#xff09;是一种用于数据降维和可视化的机器学习算法&#xff0c;尤其适用于高维数据的降维。t-SNE通过将高维数据嵌入到低维空间&#xff08;通常是二维或三维&#xff09;中&…

git github gitee 三者关系

Git&#xff1a; Git 是一个分布式版本控制系统&#xff0c;用于跟踪源代码的更改。它由 Linus Torvalds 于 2005 年开发&#xff0c;目的是更好地管理 Linux 内核开发。Git 是一个命令行工具&#xff0c;具有以下特点&#xff1a; 分布式&#xff1a;每个开发者的工作目录都是…

【深度学习】什么是交叉注意力机制?

文章目录 区别传统的自注意力机制交叉注意力机制区别总结应用实例自注意力机制的应用&#xff1a;交叉注意力机制的应用&#xff1a; 代码自注意力机制的实现交叉注意力机制的实现说明 交叉注意力机制的发展趋势 区别 交叉注意力机制&#xff08;Cross-Attention Mechanism&am…

【Git】入门到专家,Git手动配置Config脚本

为什么要手动配置脚本 手动配置脚本&#xff0c;好比是一个专家模式&#xff0c;它能加深你对Git的理解 如果纯粹复制粘贴网上的指令&#xff0c;不懂得其中原理&#xff0c;项目一多&#xff0c;仓库一多&#xff0c;发生冲突时自己就没法解决 Git的脚本非常简单&#xff0…

【php相关总结】

php相关总结 一、分库分表 垂直拆分和水平拆分 垂直拆分&#xff1a; 1.大表拆小表&#xff0c;常用的字段单独拆分出来&#xff0c;直接访问小表 2.每个库表不一样&#xff0c;但是有一个相同的外键关联 水平拆分&#xff1a; 1.hash取模拆分。 2.每个库表结构都一样&#xf…

Edge浏览器油猴插件的安装与使用

油猴 (又称篡改猴或Tampermonkey) 是最流行的浏览器扩展之一。它允许用户自定义并增强网页的功能。用户脚本是小型 JavaScript 程序&#xff0c;可用于向网页添加新功能或修改现有功能。使用油猴&#xff0c;您可以轻松在任何网站上创建、管理和运行这些用户脚本。 1.插件的安…