Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python遗传和进化算法框架(一)Geatpy快速入门[通俗易懂]

Python遗传和进化算法框架(一)Geatpy快速入门[通俗易懂]

作者头像
全栈程序员站长
发布于 2022-08-31 00:59:51
发布于 2022-08-31 00:59:51
3.3K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

Geatpy是一个高性能实用型的Python遗传算法工具箱,提供一个面向对象的进化算法框架,经过全面改版后,新版Geatpy2目前由华南农业大学、暨南大学、华南理工等本硕博学生联合团队开发及维护。

Geatpy提供了许多已实现的遗传和进化算法相关算子的库函数,如初始化种群、选择、交叉、变异、重插入、多目标优化非支配排序等,并且提供诸多已实现的进化算法模板来实现多样化的进化算法。其执行效率高于Matlab、Java和Python编写的一些知名工具箱、平台或框架等,学习成本低、模块高度脱耦、扩展性高。

Geatpy支持二进制/格雷码编码种群、实数值种群、整数值种群、排列编码种群。支持轮盘赌选择、随机抽样选择、锦标赛选择。提供单点交叉、两点交叉、洗牌交叉、部分匹配交叉(PMX)、顺序交叉(OX)、线性重组、离散重组、中间重组等重组算子。提供简单离散变异、实数值变异、整数值变异、互换变异等变异算子。支持随机重插入、精英重插入。支持awGA、rwGA、nsga2、快速非支配排序等多目标优化的库函数、提供进化算法框架下的常用进化算法模板等。

关于遗传算法、进化算法的学习资料,在官网中https://www.geatpy.com 有详细讲解以及相关的学术论文链接。同时网上也有很多资料。

闲话少说……下面讲一下怎么安装和使用:

先说一下安装方法:

首先是要windows系统,Python要是3.5,3.6或3.7版本 ,并且安装了pip。只需在控制台执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install geatpy

即可安装成功。或者到github上下载源码进行编译安装:https://github.com/geatpy-dev/geatpy 。推荐是直接用pip的方式安装。因为这样方便后续的更新。我为了方便运行demo代码以及查看源码和官方教程文档,因此另外在github上也下载了(但仍用pip方式安装)。

有些初学Python的读者反映还是不知道怎么安装,或者安装之后不知道怎么写代码。这里推荐安装Anaconda,它集成了Python的许多常用的运行库,比如Numpy、Scipy等。其内置的Spyder开发软件的风格跟Matlab类似,给人熟悉的感觉,更容易上手。

再说一下更新方法:

Geatpy在持续更新。可以通过以下命令使电脑上的版本与官方最新版保持一致:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install --upgrade geatpy

若在更新过程中遇到”–user”错误的问题,这是用pip进行安装时遇到的常见问题之一。意味着需要以管理员方式运行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install --user --upgrade geatpy

Geatpy提供2种方式来使用进化算法求解问题。先来讲一下第一种最基本的实现方式:编写编程脚本。

1. 编写脚本实现遗传算法:

以一个非常简单的单目标优化问题为例:求f(x)=x*sin(10*pi*x)+2.0 在 x∈[-1,2] 上的最大值。

直接编写脚本如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"""demo.py"""
import numpy as np
import geatpy as ea # 导入geatpy库
import matplotlib.pyplot as plt
import time

"""============================目标函数============================"""
def aim(x):                    # 传入种群染色体矩阵解码后的基因表现型矩阵
    return x * np.sin(10 * np.pi * x) + 2.0
x = np.linspace(-1, 2, 200)
plt.plot(x, aim(x)) # 绘制目标函数图像
"""============================变量设置============================"""
x1 = [-1, 2]                   # 自变量范围
b1 = [1, 1]                    # 自变量边界
varTypes = np.array([0])       # 自变量的类型,0表示连续,1表示离散
Encoding = 'BG'                # 'BG'表示采用二进制/格雷编码
codes = [1]                    # 变量的编码方式,2个变量均使用格雷编码
precisions =[4]                # 变量的编码精度
scales = [0]                   # 采用算术刻度
ranges=np.vstack([x1]).T       # 生成自变量的范围矩阵
borders=np.vstack([b1]).T      # 生成自变量的边界矩阵
"""=========================遗传算法参数设置========================="""
NIND = 40;                     # 种群个体数目
MAXGEN = 25;                   # 最大遗传代数
FieldD = ea.crtfld(Encoding,varTypes,ranges,borders,precisions,codes,scales) # 调用函数创建区域描述器
Lind = int(np.sum(FieldD[0, :]))          # 计算编码后的染色体长度
obj_trace = np.zeros((MAXGEN, 2))         # 定义目标函数值记录器
var_trace = np.zeros((MAXGEN, Lind))      # 定义染色体记录器,记录每一代最优个体的染色体
"""=========================开始遗传算法进化========================"""
start_time = time.time()                             # 开始计时
Chrom = ea.crtbp(NIND, Lind)                         # 生成种群染色体矩阵
variable = ea.bs2ri(Chrom, FieldD)                 # 对初始种群进行解码
ObjV = aim(variable)                                 # 计算初始种群个体的目标函数值
best_ind = np.argmax(ObjV)                           # 计算当代最优个体的序号
# 开始进化
for gen in range(MAXGEN):
    FitnV = ea.ranking(-ObjV)                        # 根据目标函数大小分配适应度值(由于遵循目标最小化约定,因此最大化问题要对目标函数值乘上-1)
    SelCh=Chrom[ea.selecting('rws', FitnV, NIND-1), :] # 选择,采用'rws'轮盘赌选择
    SelCh=ea.recombin('xovsp', SelCh, 0.7)           # 重组(采用两点交叉方式,交叉概率为0.7)
    SelCh=ea.mutbin(Encoding, SelCh)                 # 二进制种群变异
    # 把父代精英个体与子代合并
    Chrom = np.vstack([Chrom[best_ind, :], SelCh])
    variable = ea.bs2ri(Chrom, FieldD)             # 对育种种群进行解码(二进制转十进制)
    ObjV = aim(variable)                             # 求育种个体的目标函数值
    # 记录
    best_ind = np.argmax(ObjV)                       # 计算当代最优个体的序号
    obj_trace[gen, 0] = np.sum(ObjV) / NIND          # 记录当代种群的目标函数均值
    obj_trace[gen, 1] = ObjV[best_ind]               # 记录当代种群最优个体目标函数值
    var_trace[gen, :] = Chrom[best_ind, :]           # 记录当代种群最优个体的变量值
# 进化完成
end_time = time.time() # 结束计时
"""============================输出结果及绘图================================"""
best_gen = np.argmax(obj_trace[:, [1]])
print('目标函数最大值:', obj_trace[best_gen, 1]) # 输出目标函数最大值
variable = ea.bs2ri(var_trace[[best_gen], :], FieldD) # 解码得到表现型
print('对应的决策变量值为:')
print(variable[0][0]) # 因为此处variable是一个矩阵,因此用[0][0]来取出里面的元素
print('用时:', end_time - start_time)
plt.plot(variable, aim(variable),'bo')
ea.trcplot(obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])

运行结果如下:

目标函数最大值: 3.850272716105895 对应的决策变量值为: 1.8505813776055176 用时: 0.02496051788330078

仔细查看上述代码,我们会发现Geatpy的书写风格与Matlab大同小异,有Matlab相关编程经验的基本上可以无缝转移到Python上利用Geatpy进行遗传算法程序开发。

Geatpy提供了详尽的API文档,比如要查看上面代码中的”ranking”函数是干什么的,可以在python中执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import geatpy as ga
help(ga.ranking)

即可看到”ranking”函数的相关使用方法。

另外官网上也有更多详尽的Geatpy教程:文档 – Geatpy

2. 利用框架实现遗传算法。

Geatpy提供开放的面向对象进化算法框架。即“问题类”+“进化算法模板类+种群类”。对于一些复杂的进化算法,如多目标进化优化、改进的遗传算法等,按照上面所说的编写脚本代码是非常麻烦的,而用框架的方法可以极大提高编程效率。

这里给出一个利用框架实现NSGA-II算法求多目标优化函数ZDT-1的帕累托前沿面的例子:

第一步:首先编写ZDT1的问题类,写在“MyProblem.py”文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding: utf-8 -*-
"""MyProblem.py"""
import numpy as np
import geatpy as ea

class MyProblem(ea.Problem): # 继承Problem父类
    def __init__(self):
        name = 'ZDT1' # 初始化name(函数名称,可以随意设置)
        M = 2 # 初始化M(目标维数)
        maxormins = [1] * M # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)
        Dim = 30 # 初始化Dim(决策变量维数)
        varTypes = [0] * Dim # 初始化varTypes(决策变量的类型,0:实数;1:整数)
        lb = [0] * Dim # 决策变量下界
        ub = [1] * Dim # 决策变量上界
        lbin = [1] * Dim # 决策变量下边界
        ubin = [1] * Dim # 决策变量上边界
        # 调用父类构造方法完成实例化
        ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)
    
    def aimFunc(self, pop): # 目标函数
        Vars = pop.Phen # 得到决策变量矩阵
        ObjV1 = Vars[:, 0]
        gx = 1 + 9 * np.mean(Vars[:, 1:30], 1)
        hx = 1 - np.sqrt(ObjV1 / gx)
        ObjV2 = gx * hx
        pop.ObjV = np.array([ObjV1, ObjV2]).T # 把结果赋值给ObjV
    
    def calReferObjV(self): # 计算全局最优解作为目标函数参考值
        N = 10000 # 生成10000个参考点
        ObjV1 = np.linspace(0, 1, N)
        ObjV2 = 1 - np.sqrt(ObjV1)
        globalBestObjV = np.array([ObjV1, ObjV2]).T
        
        return globalBestObjV

上面代码中,问题类的构造函数__init__()是用于定义与ZDT1测试问题相关的一些参数,如决策变量范围、类型、边界等等。aimFunc()是待优化的目标函数。calReferObjV()用来计算理论的全局最优解,这个理论最优解可以是通过计算得到的,也可以是通过导入外部文件的数据得到的,如果待求解的问题没有或尚不知道理论最优解是多少,则这个calReferObjV()函数可以省略不写。

第二步:在同一个文件夹下编写执行脚本,实例化上述问题类的对象,然后调用Geatpy提供的nsga2算法的进化算法模板(moea_NSGA2_templet),最后结合理论全局最优解PF(即俗称的“真实前沿点”)通过计算GD、IGD、HV等指标来分析优化效果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding: utf-8 -*-
import geatpy as ea  # import geatpy
from MyProblem import MyProblem

if __name__ == '__main__':
    problem = MyProblem()  # 生成问题对象
    # 构建算法
    algorithm = ea.moea_NSGA2_templet(problem,
                                      ea.Population(Encoding='RI', NIND=50),
                                      MAXGEN=200,  # 最大进化代数。
                                      logTras=1)  # 表示每隔多少代记录一次日志信息,0表示不记录。
    # 求解
    res = ea.optimize(algorithm, verbose=True, drawing=1, outputMsg=True, drawLog=False, saveFlag=False, dirName='result')

运行结果如下:

。。。

上述代码中已经对各个流程进行了详细的注释。其中进化算法的核心逻辑是写在进化算法模板内部的,可前往查看对应的源代码。此外,我们还可以参考Geatpy进化算法模板的源代码来自定义算法模板,以实现丰富多样的进化算法,如各种各样的改进的进化算法等:

最后值得注意的是:目标函数aimFunc()那一块地方最容易写错。aimFunc()的输入参数pop是一个种群对象(有关种群对象可以查看工具箱中的Population.py类源码,或者查看Geatpy数据结构)。pop.Phen是种群的表现型矩阵,意思是种群染色体解码后得到的表现型矩阵,它对应的即为问题类中的决策变量。Phen是一个矩阵,每一行对应种群中的一个个体的表现型。在计算目标函数时,可以把这个Phen拆成一行一行,即逐个逐个个体地计算目标函数值,然后再拼成一个矩阵赋值给pop对象的ObjV属性。也可以利用Numpy的矩阵化计算来“一口气”把种群所有个体的目标函数值计算出来。无论采用的是哪种计算方法,最后得到的目标函数值是要保存在pop对象的ObjV属性中的,这个ObjV是“种群目标函数值矩阵”,每一行对应一个个体的所有目标函数值,每一列对应一个目标。比如:

它表示有种群3个个体,待优化目标有2个。

后面的博客将深入理解Geatpy的数据结构、进化算法框架的用法与扩展,以及探讨框架的核心——进化算法模板的实现。还会讲一些使用Geatpy解决问题的案例。欢迎继续跟进~感谢!

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/144522.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于Numpy图像处理基础技巧
图像基础处理是计算机视觉和数字图像处理的第一步,旨在通过简单而有效的操作改善图像质量或提取关键信息。
皮大大
2025/05/07
1430
传统图像降噪算法之BM3D原理详解
图像降噪是一个十分具有实用价值的研究方向,因为噪声总是无处不在的。当处于比较昏暗的环境时,噪声将极大地影响着我们所拍摄的图像。如今,随着深度学习算法以及相关硬件的不断发展,深度卷积网络同样在图像降噪领域占据了主流,并且代表了该领域最优异的成绩。但是,深度神经网络同样有着其缺点,例如模型过于庞大而计算复杂度过高,以及缺乏一些理论上的解释性,当然这些缺点正不断地得到弥补。为了更好地理解图像降噪的基本原理,我们有必要回过头来仔细研读一些传统算法的具体思路,了解其所使用基本理论依据,以及一些巧妙的改进方法。在这些传统降噪算法中,最经典而强大的莫过于 BM3D 了。这篇文章将全面地对其原理进行解读,并且对其论文中一些没有提及的细节进行补充,让各位读者能够更加轻松地理解其算法的内核。在开始这篇文章之前,本人建议大家可以先看一下以下的文章,主要是对本文中一些需要用到但是为了节省篇幅而没有细讲的基本原理进行补充:
全栈程序员站长
2022/06/26
2.1K0
传统图像降噪算法之BM3D原理详解
BM3D算法介绍「建议收藏」
论文名称:Image denoising by sparse 3D transform-domain collaborative filtering
全栈程序员站长
2022/09/02
8700
BM3D算法介绍「建议收藏」
图像去噪序列——BM3D图像去噪模型实现
(1) 在噪声图像上,利用局部区域搜索相似块,并进行堆叠,在变换域(DCT域、FFT域)利用硬阈值去噪方法对堆叠的图像块进行去噪,获得堆叠相似块的估计值,最后,根据均值权重进行聚合;
全栈程序员站长
2022/09/05
2.7K0
图像去噪序列——BM3D图像去噪模型实现
BM3D(Block-Matching and 3D filtering)读后感[通俗易懂]
BM3D是2007年TIP的文章,题目是Image denoising by sparse 3D transform-domain collaborative ltering,论文、项目的地址是http://www.cs.tut.fi/~foi/GCF-BM3D/,提供matlab代码;http://www.ipol.im/pub/art/2012/l-bm3d/为C++的实现,这篇论文里面有对BM3D实现的更为详细的说明。
全栈程序员站长
2022/06/26
1.6K0
BM3D(Block-Matching and 3D filtering)读后感[通俗易懂]
BM3D 算法原理详细解析 按过程步骤讲解(附C++实现代码)[通俗易懂]
BM3D是2007年提出的算法了,至今已经有一些年头了,但是仍然不妨碍它基本上还是最强的去噪算法。
全栈程序员站长
2022/09/01
2.4K0
BM3D图像去噪算法
一种非局部去噪方法Non-local method[1],可以归类到spatial method中,另外用的比较多的还有transform method,基于transform method的方法在image denoise中也取得了很好的效果,不过理论阐述会比较繁琐,如BLS-GSM-Wavelet。
全栈程序员站长
2022/08/14
9100
BM3D图像去噪算法
BM3D的学习与Matlab实现「建议收藏」
BM3D是2007年TIP的文章,题目是《Image Denoising by Sparse 3-D Transform-Domain Collaborative Filtering》。最近想尝试一下图像去噪,看看能否应用到项目中,顺便测试了一下效果,结果不是太理想,主要问题是时间,去噪效果还是可以的。担心以后找起来(实现)麻烦,就当做个笔记了。
全栈程序员站长
2022/08/15
1.5K0
BM3D的学习与Matlab实现「建议收藏」
bm3d matlab,Note — BM3D「建议收藏」
denoise中也取得了很好的效果,不过理论阐述会比较繁琐,如BLS-GSM-Wavelet。
全栈程序员站长
2022/09/06
3220
BM3D 图像去噪
论文:Image denoising by sparse 3-D transform-domain collaborative filtering 代码:python 代码 介绍:图像去噪算法:BM3D
全栈程序员站长
2022/08/25
6650
BM3D 图像去噪
BM3D改进算法
论文名称:Collaborative Filtering of Correlated Noise:Exact Transform-Domain Variance for Improved Shrinkage and Patch Matching
全栈程序员站长
2022/09/05
4870
BM3D改进算法
BM3D算法「建议收藏」
BM3D(Block-matching and 3D filtering,3维块匹配滤波) 2007-TIP-Image denoising by sparse 3D transform-domain collaborative ltering
全栈程序员站长
2022/06/26
1.4K0
BM3D算法「建议收藏」
低光照图像增强算法汇总
在现实场景中,由于光线、视角等问题会导致我们拍摄出来的照片比较阴暗,具体的图片如下图中的1、3、5列所示,然后这些阴暗的图片不仅会影响我们的观察,而且会极大的影响计算机视觉处理算法的效果,2、4、6列表示的是使用了低光照图像增强算法之后的效果。本文主要针对低光照的图片展开论述,对经典的一些低光照图像增强算法进行了总结和初略的分析。
狼啸风云
2020/10/26
9K0
低光照图像增强算法汇总
通俗语言说BM3D
随着友商某以摄像著称的旗舰机型的发布,其SOC中ISP5.0采用的所谓单反级降噪算法BM3D一下火热起来,本文试图用尽量通俗易懂的语言从算法原理的角度揭开BM3D算法的神秘面纱。
全栈程序员站长
2022/06/26
3.2K2
通俗语言说BM3D
匹配追踪算法进行图像重建
匹配追踪的过程已经在匹配追踪算法(MP)简介中进行了简单介绍,下面是使用Python进行图像重建的实践。
卡尔曼和玻尔兹曼谁曼
2019/01/22
2.4K0
匹配追踪算法进行图像重建
教程:使用iPhone相机和openCV来完成3D重建(第三部分)
在第二部分,我们分析了一个计算相机矩阵和失真系数的脚本。这些是三维重建过程中所必需的相机固有参数。
AI研习社
2019/05/08
1.7K0
教程:使用iPhone相机和openCV来完成3D重建(第三部分)
熟练掌握CV中最基础的概念:图像特征,看这篇万字的长文就够了
目录 1,图像特征 2,角点特征 3,使用OpenCV和PIL进行特征提取和可视化 4,特征匹配 5,图像拼接
deephub
2020/05/09
4K0
熟练掌握CV中最基础的概念:图像特征,看这篇万字的长文就够了
优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码)。
用户1138785
2018/01/03
1.6K0
优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码)。
高翔Slambook第七讲代码解读(3d-2d位姿估计)
上回咱们读完了pose_estimation_2d2d.cpp这个文件,基本上明白了通过对极几何计算相机位姿变换的过程,简单地说就是:你给我两帧图像,我给你算个R、t。
小白学视觉
2019/10/24
1.7K0
bm3d算法matlab,BM3D算法实现图像降噪.doc[通俗易懂]
4.4 BM3D降噪算法(Block Matching 3D Filter Algorithm)7
全栈程序员站长
2022/09/05
7650
推荐阅读
相关推荐
基于Numpy图像处理基础技巧
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验