Python用遗传算法求复杂函数在一个区间内的最大值(优化目标函数方法)

Geatpy是一个高性能的Python遗传算法库以及开放式进化算法框架,由华南理工大学、华南农业大学、德州奥斯汀公立大学学生联合团队开发。

  • Website (including documentation): http://www.geatpy.com
  • Source: https://github.com/geatpy-dev/geatpy

Geatpy提供了许多已实现的遗传和进化算法相关算子的库函数,如初始化种群、选择、交叉、变异、重插入、多种群迁移、多目标优化非支配排序等,并且提供开放式的进化算法框架来实现多样化的进化算法。其执行效率高于Matlab遗传算法工具箱和Matlab第三方遗传算法工具箱Gaot、gatbx、GEATbx,学习成本低。

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

直接上代码,日后可以作为工具使用,具体原理日后再说。。。

import numpy as np
import geatpy as ga  # 导入geatpy库
import matplotlib.pyplot as plt
import time

"""============================目标函数============================"""


def aim(x):  # 传入种群染色体矩阵解码后的基因表现型矩阵
    return x * np.sin(10 * np.pi * x) + 2.0


x = np.linspace(-2, -1, 200)

plt.plot(x, aim(x), 'r')  # 绘制目标函数图像

start_time = time.time()  # 开始计时
"""============================变量设置============================"""
x1 = [-2, -1]  # 自变量范围
b1 = [1, 1]  # 自变量边界
codes = [1]  # 变量的编码方式,2个变量均使用格雷编码
precisions = [5]  # 变量的精度
scales = [0]  # 采用算术刻度
ranges = np.vstack([x1]).T  # 生成自变量的范围矩阵

borders = np.vstack([b1]).T  # 生成自变量的边界矩阵
"""========================遗传算法参数设置========================="""
NIND = 40  # 种群个体数目
MAXGEN = 25  # 最大遗传代数
GGAP = 0.9  # 代沟:说明子代与父代的重复率为0.1
"""=========================开始遗传算法进化========================"""
FieldD = ga.crtfld(ranges, borders, precisions, codes, scales)  # 调用函数创建区域描述器

Lind = np.sum(FieldD[0, :])  # 计算编码后的染色体长度
Chrom = ga.crtbp(NIND, Lind)  # 根据区域描述器生成二进制种群
variable = ga.bs2rv(Chrom, FieldD)  # 对初始种群进行解码

ObjV = aim(variable)  # 计算初始种群个体的目标函数值
# plt.scatter(variable, ObjV)
# plt.show()
pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)  # 定义进化记录器,初始值为nan
ind_trace = (np.zeros((MAXGEN, Lind)) * np.nan)  # 定义种群最优个体记录器,记录每一代最优个体的染色体,初始值为nan
# 开始进化!!
for gen in range(MAXGEN):
    FitnV = ga.ranking(-ObjV)  # 根据目标函数大小分配适应度值(由于遵循目标最小化约定,因此最大化问题要对目标函数值乘上-1)
    SelCh = ga.selecting('sus', Chrom, FitnV, GGAP)  # 选择,采用'sus'随机抽样选择
    SelCh = ga.recombin('xovsp', SelCh, 0.7)  # 重组(采用单点交叉方式,交叉概率为0.7)
    SelCh = ga.mutbin(SelCh)  # 二进制种群变异
    variable = ga.bs2rv(SelCh, FieldD)  # 对育种种群进行解码(二进制转十进制)
    ObjVSel = aim(variable)  # 求育种个体的目标函数值

    plt.plot(x, aim(x), 'r')  # 绘制目标函数图像
    plt.scatter(variable, ObjVSel)

    # plt.show()

    [Chrom, ObjV] = ga.reins(Chrom, SelCh, 1, 1, 1, -ObjV, -ObjVSel, ObjV, ObjVSel)  # 重插入得到新一代种群
    # 记录
    best_ind = np.argmax(ObjV)  # 计算当代最优个体的序号
    pop_trace[gen, 0] = ObjV[best_ind]  # 记录当代种群最优个体目标函数值
    pop_trace[gen, 1] = np.sum(ObjV) / ObjV.shape[0]  # 记录当代种群的目标函数均值
    ind_trace[gen, :] = Chrom[best_ind, :]  # 记录当代种群最优个体的变量值
# 进化完成
end_time = time.time()  # 结束计时
"""============================输出结果及绘图================================"""
print('目标函数最大值:', np.max(pop_trace[:, 0]))  # 输出目标函数最大值
variable = ga.bs2rv(ind_trace, FieldD)  # 解码得到表现型
print('用时:', end_time - start_time)
# plt.plot(variable, aim(variable), 'bo')
# plt.show()

你可能感兴趣的:(机器学习)