智能优化算法之遗传算法(GA)的实现(基于二进制编码,Python附源码)

2023-11-15

一、遗传算法的实现思路

遗传算法(Genetic Algorithm,GA)是一种借鉴生物进化理论,仿照生物的多代遗传过程的随机搜索算法,它以目标问题的不同解作为不同的个体生成种群,然后对种群进行选择、交配、变异操作来寻求最优个体以实现对目标问题的求解。
其主要算法步骤如下:
1)编码生成种群个体,编码方式一般为实数编码或二进制编码;
2)计算种群个体适应度值;
3)选择操作,选出种群中适应度较高的个体,一般使用轮盘赌方法或比例选择法进行选择;
4)交叉操作,根据交叉概率对经过选择后的种群个体进行个体间基因片段的交换,交叉概率一般为固定值;
5)变异操作,根据变异概率对经过选择后的种群个体进行基因片段的改变,变异概率一般为固定值。
6)重复步骤3到步骤5,当达到最大迭代次数或满足停止条件后停止迭代,然后输出种群中的最优个体。

二、基于二进制编码方式的遗传算法的实现

待求解问题Rastrigin函数:
f(x)=20+x^2-10 cos⁡(2πx)+y^2-10cos⁡(2πy)
求最小值,取值范围:x∈[-5,5],y∈[-5,5],精度精确到小数点后五位。

1、库的导入

NumPy(Numerical Python)是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
Matplotlib 是 Python 的绘图库,它能让使用者很轻松地将数据图形化,并且提供多样化的输出格式。
这两个库需要提前安装在当前python路径下,在cmd中执行安装指令即可安装在当前python路径,指令如下:

pip install numpy
pip install matplotlib

库的导入指令如下:

import numpy as np
import matplotlib.pyplot as plt

2、目标函数

将上述问题中的x,y视作种群中的一个个体X,待求解问题f(x)即为目标函数,同时作为适应度函数。

def fitness_func(X):
    pi = np.pi
    x = X[:, 0]
    y = X[:, 1]
    return 20 + x ** 2 - 10 * np.cos(2 * pi * x) + y ** 2 - 10 * np.cos(2 * pi * y)

3、个体编码函数

将二进制编码的每个个体转换成十进制编码,由于for函数是从第0位开始,而二进制转换成十进制需要从个位数开始,因此需要另外的计算将其转换成原数值。

def decode(x, a, b):
    xt = 0
    for i in range(len(x)):
        xt = xt + x[i] * np.power(2, i)
    return a + xt * (b - a) / (np.power(2, len(x)) - 1)

4、个体解码函数

调用3中的解码统一函数decode(),将每个个体解码成由x,y组成的数组形式。

def decode_X(X: np.array):
    # X.shape[0]为50,即个体数量
    X2 = np.zeros((X.shape[0], 2))
    for i in range(X.shape[0]):
        #获得x的十进制数
        xi = decode(X[i, :20], -5, 5)
        #获得y的十进制数
        yi = decode(X[i, 20:], -5, 5)
        #将x、y组成的个体赋给数组X2
        X2[i, :] = np.array([xi, yi])
    return X2

5、选择函数

使用比例选择法,由于是求最小值,因此要取倒数来评价适应度值,适应度值越大,选择的概率越大。

def select(X, fitness):
    fitness = 1 / fitness  # fitness越小表示越优秀,被选中的概率越大,因此取倒数做1/fitness 处理
    fitness = fitness / fitness.sum()  # 获得每个个体的概率
    # 将X的每一行(也就是每个个体)选取出来,并排排在一起生成一个新的列表,然后将列表转换成一维数组idx
    idx = np.array(list(range(X.shape[0])))
    # 从idx中按照适应度值随机选出50个个体,生成一维数组X2_idx,每个个体被选中的概率与其适应度大小相关
    X2_idx = np.random.choice(idx, size=X.shape[0], p=fitness)
    # 将X2_idx里的每一列取出来作为数组X的每一行,之后将数组X赋给X2
    X2 = X[X2_idx, :]
    return X2

6、交叉函数

每两个个体为一组,针对每组个体的每个基因,随机生成0-1之间的随机数,与交叉概率比较,若小于交叉概率,则对该基因进行交换,完成交换后,新的一组个体取代原先的一组个体。

def crossover(X, c):
    for i in range(0, X.shape[0], 2):
        xa = X[i, :]
        xb = X[i + 1, :]
        # X.shape[1]为40,即二进制编码长度
        for j in range(X.shape[1]):
            # 产生0-1区间的均匀分布随机数,判断是否需要进行交叉替换
            if np.random.rand() < c:
                # 如果进行交叉,则将对应的第j个位置的数进行交叉
                xa[j], xb[j] = xb[j], xa[j]
        # 用新的个体取代原先的个体        
        X[i, :] = xa
        X[i + 1, :] = xb
    return X

7、变异函数

针对种群中的每个个体的每个基因,随机生成0-1之间的随机数,与变异概率比较,若小于变异概率,则对该基因进行变异,即0变成1,1变成0,完成变异后,新的个体取代原先的个体。

def mutation(X, m):
    for i in range(X.shape[0]):
        for j in range(X.shape[1]):
            if np.random.rand() < m:
                # 0变成1,1变成0
                X[i, j] = (X[i, j] + 1) % 2
    return X

8、算法主流程

将交叉概率设为0.3、变异概率设为0.05,种群数量为50,每个个体都是由x,y组成,且x,y都是二进制编码,由于x与y取值范围在[-5,5]之间,且精确到小数点后五位,因此x、y的编码长度均为20,即每个个体的编码长度为40。
二进制编码随机初始化种群个体后进入循环迭代过程,迭代次数为100次,每次迭代过程中依次进行选择、交叉、变异操作,之后将种群解码并计算适应度值,然后保存此次迭代中的最优适应度值(best_fitness)以及对应的最优个体(best_xy),然后将此时的种群作为下一次迭代时的初始种群。
每次迭代过程中输出当前迭代次数以及最优适应度值。
迭代结束后输出最优适应度值以及对应的个体取值。

c = 0.3  # 交叉概率
m = 0.05  # 变异概率
best_fitness = []  # 记录每次迭代最优适应度值
best_xy = [] # 记录每次迭代最优个体
iter_num = 100  # 最大迭代次数
X0 = np.random.randint(0, 2, (50, 40))  # 随机初始化种群,50个个体,每个个体编码长度为40,为50*40的0-1矩阵
for i in range(iter_num):
    X1 = decode_X(X0)  # 染色体解码
    fitness = fitness_func(X1)  # 计算个体适应度
    X2 = select(X0, fitness)  # 选择操作
    X3 = crossover(X2, c)  # 交叉操作
    X4 = mutation(X3, m)  # 变异操作
    # 将二进制转换成十进制,分别获得x,y
    X5 = decode_X(X4)
    # 计算适应度值
    fitness = fitness_func(X5)
    # 计算结果最小的即为最优适应度值,保存到best_fitness中
    best_fitness.append(fitness.min())
    # 将最优个体保存到best_xy中
    x, y = X5[fitness.argmin()]
    best_xy.append((x, y))
    # 将此次的种群作为新一次迭代过程中的初始种群
    X0 = X4
    # 输出当前迭代最优效果
    print("当前迭代次数:", i+1)
    print("最优适应度值是:", best_fitness[i])
#迭代结束后的最终效果
print("最优值是:%.5f" % best_fitness[-1])
print("最优解是:x=%.5f, y=%.5f" % best_xy[-1])

9、结果绘图
将best_fitness(每次迭代的最优适应度值)进行绘图并保存,可通过图片查看迭代过程中最优适应度值的变化情况。

plt.plot(best_fitness, color='r')
plt.savefig("GA.png")
plt.show()

图中横轴为迭代次数,纵轴为最优适应度值。
在这里插入图片描述
参考源码

遗传算法实数编码参考:
智能优化算法之遗传算法(GA)的实现(基于实数编码,Python附源码)

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

智能优化算法之遗传算法(GA)的实现(基于二进制编码,Python附源码) 的相关文章

随机推荐

  • vue使用文件流和url下载文件

    改为使用后台返回url下载文件 方法1 这个会导致在点击下载按钮的时候 页面会跳转到奇怪的url window location href row downloadUrl 方法2 点击下载按钮 不会在新窗口打开 const download
  • 刷脸支付算法和硬件不断升级消费更有保障

    刷脸支付设备依靠3D传感摄像头进行人脸识别 其内置的点阵投影仪可以投射出3万多个肉眼不可见的红外点到用户脸部 多维度 多角度在颜色 纹理 深度等数据进行高层次对比 安全性和精准性更高 识别速度更快 尽管现在刷脸支付的安全性已经达到极高的金融
  • 【数据结构与算法】栈的实现(附源码)

    目录 一 栈的概念和结构 二 接口实现 A 初始化 Stackinit 销毁 Stackdestroy 1 Stackinit 2 Stackdestroy B 插入 Stackpush 删除 Stackpop 1 Stackpush 2
  • 接口未正确配置:wx.getLocation(暂无权限)

    原因 腾讯地理位置接口新增与相关流程 地理位置接口新增说明 由于精确地理位置接口只允许部分类目的小程序申请使用 为了满足开发者在更多场景使用地理位置接口 自 2022 年 7 月 14 日起 新增获取模糊地理位置接口 wx getFuzzy
  • 计算机网络第六章——应用层(下)

    等闲变却故人心 却道故人心易变 文章目录 用户代理就是用户和电子邮件系统之间的一个接口 通常都是运行在电脑中的一个程序 用户代理又可以称为电子邮件客户端软件 用户代理可以为用户提供一个比较友好的接口 邮件服务器作为一个服务器就需要长时间的工
  • 责任链模式(Chain of Responsibility) Java实现

    责任链模式 责任链模式 Chain of Responsibility 定义 责任链模式是一种对象的行为模式 在责任链模式里 很多对象由每一个对象对其下家的引用而连接起来形成一条链 请求在这个链上传递 直到链上的某一个对象决定处理此请求 发
  • 以太网(Ethernet)相关基础知识

    最近正好在学习以太网 感觉非常有用 进行一个总结 欢迎指正 如今 以太网已在现实中大量使用 低廉的价格和较快的速度都是它从许多网络中存活下来的因素 学校 公司中大多用得都是以太网 目录 以太网电缆 Ethernet Cabling 曼彻斯特
  • 移动端点击(click)事件延迟问题的解决方法

    移动端 click 事件会有 300ms 的延时 原因是移动端屏幕双击会缩放 double tap to zoom 页面 解决方案 1 禁用缩放 浏览器禁用默认的双击缩放行为并且去掉300ms 的点击延迟 2 利用touch事件自己封装这个
  • (mac)配置vue

    安装参考 https www jianshu com p cc722eba1f46 1 安装brew 一个安装 卸载软件的程序 https blog csdn net poppy rain article details 88406390
  • Java面试题第一季学习笔记

    Java面试题第一季 1 自增变量 2 单例设计 2 1 什么是Singleton 2 2 代码示例 3 类初始化 3 1 代码 3 2 考点 3 3 Override 重写 和Overload 重载 区别 4 方法的传递机制 4 1 代码
  • java 反射中的method.invoke()方法详解

    public class TestReflect public static void main String args String names tom tim allen alice Class
  • java关于ArrayList,Vector,LinkedList,Set及其面试题+LeetCode136两种方式实现

    ArrayList ArrayList的遍历补充 将list转换为数组 使用toArray 方法将列表转换为数组 再对数组进行遍历 Test void test01 List
  • vue3实现鼠标左键拖拽画矩形框框选功能

    vue3 elementuiPlus 实现鼠标左键拖拽画矩形框 框选列表功能 仿照桌面框选功能 效果如图 vue3鼠标框选 代码
  • Hibernate的核心配置

    Hibernate的设计思路 Hibernate是一种全自动化管理持久化对象的ORM框架 既提供了完全面向对象的封装完整的对象持久化接口 屏蔽db层的差异化 提升代码可移植性 也提供了操作HQL和SQL的半自动化DB访问接口 提供复杂查询的
  • JSVC的配置与使用详解

    JSVC是apache出的所谓common daemon的一个工具套件 他利用一个daemon程序 从而使tomcat这样的程序能在开机的时候自动启动 而且能使tomcat被 chkconfig这样的工具所管理 在之前的一篇文章中对jsvc
  • 算法岗面试问题总结(二)

    文章目录 1 SVM的loss是啥 2 kmeans聚类如何选择初始点 3 RF和GBDT谁更容易过拟合 偏差和方差 4 xgb的分类树也是用残差吗 不是的话是什么 5 讲讲数据倾斜怎么处理 6 请你说说SVM的优缺点 7 LR和SVM的联
  • C++中的typeInfo用法总结

    最近在做测试 在大型程序中 模板类型加上继承关系搞得我混乱 还好有tpyeinfo帮助捋顺关系 typeInfo与typeid简单总结说明 和sizeof这类的操作符一样 typeid是C 的关键字之一 typeid操作符的返回结果是名为t
  • jenkins学习笔记第十六篇 jenkins权限控制

    创建用户 对用户进行权限控制 在实际项目中 根据不同的用户 大致可分为 测试用户 开发用户 运维用户等 这时就需要给不同的用户赋予不能的权限 首选需要安装插件 Role based Authorization Strategy 这个插件主要
  • ctfshow-WEB-web14( 利用数据库读写功能读取网站敏感文件)

    ctf show WEB模块第14关是一个SQL注入漏洞 绕过switch循环后可以拿到一个登录界面 登录界面存在SQL注入 脱库以后会提示flag在另一个文件中 利用数据库的文件读写功能读取文件内容即可拿到flag 开局是一个switch
  • 智能优化算法之遗传算法(GA)的实现(基于二进制编码,Python附源码)

    文章目录 一 遗传算法的实现思路 二 基于二进制编码方式的遗传算法的实现 1 库的导入 2 目标函数 3 个体编码函数 4 个体解码函数 5 选择函数 6 交叉函数 7 变异函数 8 算法主流程 一 遗传算法的实现思路 遗传算法 Genet