优化算法:1.遗传算法(GA)及Python实现

一、定义

        遗传算法就像是在模拟“优胜劣汰”的进化过程,通过选择最优秀的个体,交配产生下一代,并引入一定的变异,逐步优化解决问题。

二、具体步骤

  1. 初始化种群(Initialization):

    假设你要找到一个迷宫的最佳出口路径。首先,你随机生成一群“路径”作为初始种群(就像是一群随机的迷宫探险者)。     

    生成初始种群 P(0),其中 P(0)={x1​,x2​,…,xN​}。每个个体x_i是一个解的候选向量,随机生成。

    P(0) = \{ \mathbf{x}_1, \mathbf{x}_2, \ldots, \mathbf{x}_N \}

  2. 计算适应度(Fitness Calculation):

    每条路径都有一个“适应度”,代表了它的好坏。比如,走的距离短、碰到的墙少的路径适应度更高。

    对种群中的每个个体,计算其适应度值 f(\mathbf{x}_i),适应度函数 f 用于评估个体的优劣。

    f(\mathbf{x}_i), \quad \text{for} \quad \mathbf{x}_i \in P(t)

  3. 选择 (Selection):

    根据适应度选择一些表现最好的路径。适应度高的路径被选中的概率更大(就像在自然界中适应环境的生物更容易生存)。

    根据适应度值选择个体,以组建下一代。常用的方法包括轮盘赌选择、排序选择等。假设用轮盘赌选择,每个个体被选择的概率为:

    p_i = \frac{f(\mathbf{x}_i)}{\sum_{j=1}^N f(\mathbf{x}_j)}

  4. 交叉(交配)(Crossover):

    选择出来的好路径进行“交配”,生成新的路径(下一代)。交配的过程类似于把两条路径的不同部分组合在一起,形成新的路径。

    从选出的个体中随机配对进行交叉,生成新的子代。假设单点交叉,两个个体 x1​ 和 x2​ 在位置  k 进行交叉生成新个体:

    \mathbf{x}_1' = (\mathbf{x}_{1,1}, \mathbf{x}_{1,2}, \ldots, \mathbf{x}_{1,k}, \mathbf{x}_{2,k+1}, \ldots, \mathbf{x}_{2,n})

    \mathbf{x}_2' = (\mathbf{x}_{2,1}, \mathbf{x}_{2,2}, \ldots, \mathbf{x}_{2,k}, \mathbf{x}_{1,k+1}, \ldots, \mathbf{x}_{1,n})

  5. 变异 (Mutation):

    在新生成的路径中,随机改变一些部分(变异)。比如,某条路径的某一步骤突然改变方向。这就像是自然界中的基因突变。

    对新个体进行变异操作,即随机改变个体的某些基因。假设变异在第 j 个位置,对 xi​ 变异后得到 xi′​:

    \mathbf{x}_i' = (\mathbf{x}_{i,1}, \mathbf{x}_{i,2}, \ldots, \mathbf{x}_{i,j-1}, \mathbf{x}_{i,j}', \mathbf{x}_{i,j+1}, \ldots, \mathbf{x}_{i,n})

    其中 \mathbf{x}_{i,j}' 是变异后的值。

  6. 重复(Iteration):

    重复上述过程多次,每次都选择最好的路径进行交配和变异。经过若干代的进化,路径会越来越接近理想的解决方案。

    重复步骤2到5,直到满足终止条件(如达到最大迭代次数或适应度满足某个阈值)。

    P(t+1) = \text{Selection}(\text{Crossover}(\text{Mutation}(P(t))))

三、例子

        想象你在一个迷宫里找出口,你和一群朋友决定用遗传算法来找最快的路。

  1. 第一步:每个人随便走一条路,大家都出发了。
  2. 第二步:回来后,大家比较谁走的路最短,谁碰到的障碍最少。
  3. 第三步:选出几个走得最好的朋友,让他们把自己的路线告诉大家。
  4. 第四步:大家根据好朋友的路线,进行一些组合和调整,再次出发。
  5. 第五步:有时候,你们会决定“赌一把”,随便改变下路线中的某个部分,希望能找到更好的路。
  6. 第六步:重复这个过程,经过多次尝试,你们最终找到了迷宫的最佳出口路径。

四、Python示例

        举一个简单的例子,我们不妨用遗传算法优化一个一维二次函数 x^2。这个函数在数学上是一个凸函数,其最小值为 0,出现在 x=0 处。尽管简单,但它展示了遗传算法的基本原理和步骤,包括种群初始化、适应度评估、选择、交叉和变异等。可以直观地理解遗传算法是如何通过迭代逐步逼近最优解的。我已将详细的注释写在了代码中。

import numpy as np
import matplotlib.pyplot as plt# 定义目标函数
# 最小化的函数是 x^2
def fitness(x):return x ** 2# 初始化种群
# 生成一个大小为 size 的种群,每个个体的值在 bounds 范围内。生成的是一个二维数组,每个个体是一个一维数组
def initialize_population(size, bounds):return np.random.uniform(bounds[0], bounds[1], (size, 1))# 选择个体(轮盘赌选择)
# 基于个体的适应度值进行选择。适应度值越低的个体被选择的概率越高(因为我们在最小化函数)
def selection(pop, fitness_values):total_fitness = np.sum(fitness_values)  # 所有个体的总适应度值probabilities = fitness_values / total_fitness  # 每个个体被选择的概率indices = np.random.choice(len(pop), size=len(pop), p=probabilities.flatten())  # 根据这些概率随机选择个体,生成新的种群return pop[indices]# 交叉操作(单点交叉)
def crossover(pop, crossover_rate=0.7):offspring = []for i in range(0, len(pop), 2):  # 以步长为2遍历种群parent1, parent2 = pop[i], pop[i + 1]  # 随机选择两个父代if np.random.rand() < crossover_rate and parent1.size > 1:  # 如果随机数小于交叉概率且父代长度大于1cross_point = np.random.randint(1, parent1.size)  # 选择一个交叉点child1 = np.concatenate([parent1[:cross_point], parent2[cross_point:]])  # 在该点进行单点交叉生成两个子代child2 = np.concatenate([parent2[:cross_point], parent1[cross_point:]])else:  # 如果不满足交叉条件,直接复制父代作为子代。child1, child2 = parent1, parent2offspring.append(child1)offspring.append(child2)return np.array(offspring)# 变异操作(简单变异)
def mutation(pop, mutation_rate=0.01, bounds=(-10, 10)):for i in range(len(pop)):if np.random.rand() < mutation_rate:  # 如果随机数小于变异概率mut_point = np.random.randint(0, pop[i].size)  # 随机选择该个体中的一个基因位置pop[i][mut_point] = np.random.uniform(bounds[0], bounds[1])return pop# 主遗传算法流程
def genetic_algorithm(pop_size, bounds, num_generations, crossover_rate, mutation_rate):# 初始化种群pop = initialize_population(pop_size, bounds)best_solutions = []for gen in range(num_generations):# 计算适应度fitness_values = fitness(pop)# 选择selected_pop = selection(pop, fitness_values)# 交叉offspring = crossover(selected_pop, crossover_rate)# 变异pop = mutation(offspring, mutation_rate, bounds)# 保存当前代的最佳个体best_solutions.append(np.min(fitness_values))return pop, best_solutions# 参数设置
pop_size = 5000  # 种群大小  增大种群规模: 5000->100000
bounds = (-10, 10)  # 每个个体的取值范围
num_generations = 200  # 遗传算法运行的代数 增加迭代次数: 100->200
crossover_rate = 0.7  # 交叉概率
mutation_rate = 0.01  # 变异概率  增加变异率以增加多样性: 0.01->0.05# 运行遗传算法
final_pop, best_solutions = genetic_algorithm(pop_size, bounds, num_generations, crossover_rate, mutation_rate)# 绘制结果
plt.plot(best_solutions)
plt.xlabel('Generation')
plt.ylabel('Fitness (Minimized Value of x^2)')
plt.title('Genetic Algorithm Optimization')
plt.show()# 输出最终的最佳解
best_individual = final_pop[np.argmin(fitness(final_pop))]
print("Best solution found:", best_individual)
print("Fitness of the best solution:", fitness(best_individual))

       结果如下:

Best solution found: [0.09278514]
Fitness of the best solution: [0.00860908]

        该结果已经找到了一个较精确的解,接近全局最优解(即 x=0)。我们不妨将 pop_size 增大到 10000,以覆盖更大的搜索空间;将 num_generations 增加到 400,让算法有更多时间收敛;将 mutation_rate 增加到 0.05,以增加种群的多样性,经过漫长的等待,会得到一个更加精确的结果。

Best solution found: [-0.01888039]
Fitness of the best solution: [0.00035647]

        若要进一步提高算法的表现,我们还可以尝试以下几种改进方法:

  1. 调整选择策略:使用锦标赛选择等替代选择策略。
  2. 增加种群多样性:引入精英保留策略,将最优个体直接保留到下一代。
  3. 检查适应度函数:确保适应度函数正确计算。
  4. 调整初始化种群范围:可能初始化范围太大导致搜索空间过于分散。

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

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

相关文章

CTF-NSSCTF[GKCTF 2021]

[GKCTF 2021]easycms 考察&#xff1a; 用扫描工具扫描目录&#xff0c;扫描到后台登录界面/admin.php 题目提示了密码是五位弱口令&#xff0c;试了试弱口令admin和12345直接成功了 任意文件下载 点击设计-->主题然后随便选择一个主题&#xff0c;点击自定义&#xff0…

故障诊断 | 基于Transformer故障诊断分类预测(Matlab)

文章目录 预测效果文章概述程序设计参考资料预测效果 文章概述 Transformer故障诊断/分类预测 | 基于Transformer故障诊断分类预测(Matlab) Transformer 模型本质上都是预训练语言模型,大都采用自监督学习 (Self-supervised learning) 的方式在大量生语料上进行训练,也就是…

CTF之网站被黑

简单看一下网页和源码没发现什么明显漏洞 那就扫描一下目录 发现了/shell.php文件&#xff0c;访问一下&#xff0c;发现是一个后台管理登录页面 别无他法只能爆破喽&#xff0c;爆破后发现密码是hack flag{25891d9e9d377f006eda3ca7d4c34c4d}

@JSONField(format = “yyyyMMddHH“)的作用和使用

JySellerItqrdDataDO对象中的字段为&#xff1a; private Date crdat; 2.数据库中的相应字段为&#xff1a; crdat datetime DEFAULT NULL COMMENT 创建时间,2. 打印出的结果为&#xff1a; “crdat”:“2024072718” 年月日时分秒 3. 可以调整format的格式 4. 这样就把Date类…

RedHat8安装Oracle19C

RedHat8安装Oracle19C 1、 更新yum源 更新yum源为阿里云镜像源&#xff1a; # 进入源目录 cd /etc/yum.repos.d/ # 删除 redhat 默认源 rm redhat.repo # 下载阿里云的centos7源 curl -O http://mirrors.aliyun.com/repo/Centos-8.repo # 替换 Centos-8.repo 中的 $releasev…

初学Mybatis之 Lombok 篇

idea 安装 Lombok 插件&#xff1a; File->Settings->Plugins->搜索 lombok 下载 在项目中导入 lombok 的 jar 包&#xff1a; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.…

C语言程序设计之数学函数篇

程序设计之数学函数 问题1_1代码1_1结果1_1 问题1_2代码1_2结果1 _2 问题1_3代码1_3结果1_3 问题1_1 函数 f u n fun fun 的功能是计算&#xff1a; s ln ⁡ ( 1 ) ln ⁡ ( 2 ) ln ⁡ ( 3 ) ⋯ ln ⁡ ( n ) s\sqrt{\ln(1)\ \ \ln(2)\ \ \ln(3)\ \ \cdots \ \ \ln(n)\ } …

ReentrantReadWriteLock详解

目录 ReentrantReadWriteLock详解1、ReentrantReadWriteLock简介2、ReentrantReadWriteLock类继承结构和类属性3、ReentrantReadWriteLock的读写锁原理分析4、ReentrantReadWriteLock.WriteLock类的核心方法详解非公平写锁的获取非公平写锁的释放公平写锁的获取公平写锁的释放 …

win11查找句柄泄露

1.打开任务管理器&#xff0c;不会的网上搜 2.选择详细信息 3.注意了 比较坑的一点 win11上详细信息不会默认显示句柄数。&#xff08;默认没有句柄那一列&#xff0c;妈的花了我好长时间找&#xff09; 右键&#xff0c;点击选择列 选择句柄 下面的列表里就能看到进程使用…

显著提升“视触觉传感器耐磨性”的贴金工艺,在植物和古生物化石检测上取得良好的识别效果

贴金&#xff0c;一种古老的技艺&#xff0c;是中华民族民间传统工艺的瑰宝&#xff01;金箔和贴金工艺的结合让朴实无华的工艺品重获新生。正如《天工开物》所述&#xff1a;“凡色至于金&#xff0c;为人间华美贵重&#xff0c;故人工成箔而后施之”。这项古老技艺如今可用于…

PyCharm 常用 的插件

Material Theme UI Lite&#xff1a;‌提供多种不同的页面风格&#xff0c;‌为PyCharm界面增添个性化元素。‌Chinese (Simplified) Language Pack&#xff1a;‌为中文用户提供简体中文的界面、‌菜单、‌提示信息&#xff0c;‌提升使用体验。‌Tabnine&#xff1a;‌基于人…

Harmony学习(三)

1.模版字符串 let name:string 模版字符串 let age:number 18 console.log(字符串:,${name}和${age})2.字符串和数字互相转换 //字符串转数字 let str1:string 1.1 console.log(转换,Number(str1)) //output: 1.1 console.log(转换,parseInt(str1)) //output: 1 conso…

3.k8s:服务发布:service,ingress;配置管理:configMap,secret,热更新;持久化存储:volumes,nfs,pv,pvc

目录​​​​​​​ 一、服务发布 1.service &#xff08;1&#xff09;service和pod之间的关系 &#xff08;2&#xff09; service内部服务创建访问 &#xff08;3&#xff09;service访问外部服务 &#xff08;4&#xff09;基于域名访问外部 &#xff08;5&#xff…

Java中的优先级队列(PriorityQueue)(如果想知道Java中有关优先级队列的知识点,那么只看这一篇就足够了!)

前言&#xff1a;优先级队列&#xff08;Priority Queue&#xff09;是一种抽象数据类型&#xff0c;其中每个元素都关联有一个优先级&#xff0c;元素按照优先级顺序进行处理。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 …

足浴行业押金原路退回怎么开通?

一手机版和电脑版差别 手机版押金管理的优点&#xff1a; 1. 便携性&#xff1a;管理人员可以随时随地通过手机查看和处理押金相关事务&#xff0c;不受地点限制。例如&#xff0c;当不在店内时&#xff0c;仍能及时了解押金的收支情况&#xff0c;对突发问题进行处理。 2. 实…

基于微信小程序的校园二手交易平台/Java的二手交易网站/基于Javaweb校园二手商品交易系统(附源码)

摘 要 使用校园二手交易平台管理校园二手物品交易&#xff0c;不仅实现了智能化管理&#xff0c;还提高了管理员的管理效率&#xff0c;用户查询的功能也需要校园二手交易平台来提供。 设计校园二手交易平台是毕设的目标&#xff0c;校园二手交易平台是一个不断创新的系统&…

【通信模块】简单玩转WiFi模块(ESP32、ESP8266)

笔者学习太极创客的学习笔记&#xff0c;链接如下&#xff1a;www.taichimaker.com 前期准备 电脑端口 固件烧录 WIFI到网页 对应七层网络协议 WIFI工作模式&#xff08;链路层&#xff09; 接入点模式、无线中断模式、混合模式 IP协议&#xff08;网络层&#xff09; 子网…

Kafka知识总结(选举机制+控制器+幂等性)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 选举机制 控制器&#xff08;Broker&#xff09;选举 控制器就是…

springboot使用Gateway做网关并且配置全局拦截器

一、为什么要用网关 统一入口&#xff1a; 作用&#xff1a;作为所有客户端请求的统一入口。说明&#xff1a;所有客户端请求都通过网关进行路由&#xff0c;网关负责将请求转发到后端的微服务 路由转发&#xff1a; 作用&#xff1a;根据请求的URL、方法等信息将请求路由到…

【初阶数据结构篇】时间(空间)复杂度

文章目录 算法复杂度时间复杂度1. 定义2. 表示方法3. 常见时间复杂度4.案例计算分析冒泡排序二分查找斐波那契数列&#xff08;递归法&#xff09;斐波那契数列&#xff08;迭代法&#xff09; 空间复杂度案例分析冒泡排序斐波那契数列&#xff08;递归法&#xff09;斐波那契数…