智能优化算法——python手动实现交叉进化算法

遗传算法。交叉进化算法也是进化算法的一种,他具有参数少,易实现的优点(经测试,由于算法特性,暂时不能像遗传算法一样拟合图片),我们将通过拟合函数来介绍交叉进化算法

依赖包

我们用random来生成随机数,matplotlib画图,同时设置rcParams来保证正常显示中文标签

from random import randint, random
import matplotlib.pyplot as plt
import numpy as np
import os

plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

超参数

我们用max_group表示种群中个体数;savePath来确定图像保存位置;feature即特征数,即函数由几个参数构成;F0为初始变异算子,后续会根据labda进行调整,后续的正在的变异算子F由F0和labda得出
%E5%85%B6%E5%85%B3%E7%B3%BB%E5%BC%8F%E4%B8%BA%3A%20%5C%5C%20%5Clambda%3De%5E%7B1-%20%5Cfrac%7BG_m%7D%7BG_m%20%2B%201%20-G%7D%7D%20%5C%5C%20F%3DF0%20%5Ctimes2%20%5E%7B%5Clambda%7D%20%5C%5C%20%E5%85%B6%E4%B8%ADG_m%E4%B8%BA%E6%9C%80%E5%A4%A7%E8%BF%AD%E4%BB%A3%E6%AC%A1%E6%95%B0%EF%BC%8CG%E4%B8%BA%E5%BD%93%E5%89%8D%E8%BF%AD%E4%BB%A3%E6%AC%A1%E6%95%B0%20%5C%5C%20%E7%AC%AC%E4%B8%80%E6%AC%A1%E8%BF%AD%E4%BB%A3F%E7%9A%84%E5%80%BC%E6%8E%A5%E8%BF%912F0%2C%20%E9%9A%8F%E5%90%8E%E9%80%90%E6%B8%90%E6%8E%A5%E8%BF%91F0

max_group = 50  # 种群中个体数
savePath = "./plt_image"
features = 2  # 个体特征数
F0 = 0.5  # 初始变异算子
CR = 0.1  # 交叉算子
epochs = 100
lower_range = -6
upper_range = 6
labda = np.e ** (1 - epochs / (epochs + 1))
bestScore = 0
bestOne = None

待优化功能

为了便于后续的类封装,我们在优化时只使用func作为优化的函数,f函数仅用于画图

def f(x, y):
   return np.sin(np.sqrt(x ** 2 + y ** 2))

def func(x):
    X = x.reshape(-1, features).copy()
    return np.sin(np.sqrt(X[:, 0] ** 2 + X[:, 1] ** 2))

初始化

生殖人口
这时候要注意生成矩阵的形状和范围要满足条件

groups = np.random.rand(max_group,features) * (upper_range - lower_range) + lower_range  # 随机生成族群

算法体

突变

v = []

def variation(g):
    global groups
    for i in range(max_group):
        r1 = randint(0, max_group - 1)
        while r1 == i:
            r1 = randint(0, max_group - 1)

        r2 = randint(0, max_group - 1)
        while r2 == i or r2 == r1:
            r2 = randint(0, max_group - 1)

        r3 = randint(0, max_group - 1)
        while r3 == i or r3 == r1 or r3 == r2:
            r3 = randint(0, max_group - 1)

        x1 = groups[r1]
        x2 = groups[r2]
        x3 = groups[r3]
        labda = np.e * (1 - epochs / (epochs + 1 - g))
        F = F0 * 2 ** labda
        v.append(x1 + F * (x2 - x3))

交点满足的关系是
u_%7Bi%2CG%2B1%7D%3D%28u_%7B1i%2CG%2B1%7D%2Cu_%7B2i%2CG%2B1%7D%2C%20%5Ccdot%20%5Ccdot%20%5Ccdot%20%2C%20u_%7BDi%2CG%2B1%7D%29
u_%7Bji%2C%20G%2B1%7D%3D%5Cbegin%7Bcases%7D%20v_%7Bji%2C%20G%2B1%7D%2C%20%26%20%7Brandb%28j%29%20%5Cleq%20CR%E6%88%96j%3Drnbr%28i%29%7D%20%5C%5C%20x_%7Bji%2CG%2B1%7D%2C%20%26%20%7Brandb%28j%29%20%3E%20CR%E4%B8%94j%20%5Cnot%3D%20rnbr%28i%29%7D%20%5Cend%7Bcases%7D
%28i%3D1%2C%202%2C%20%5Ccdot%20%5Ccdot%20%5Ccdot%2CNP%2C%20j%3D1%2C%202%2C%5Ccdot%20%5Ccdot%20%5Ccdot%2C%20D%20%29
其中v为变异向量,x为原本的向量,u为实验向量,NP为种群最多容纳的个体数,D为每个个体的特征数。randb(j) 为随机生成的概率值,与CR做比较。rnbr(i)为随机的下标,与当前个体下标做对比

u = []  # 选择种群

def cross():
    r = randint(0, max_group - 1)
    for i in range(max_group):
        cr = random()
        if cr <= CR or i == r:
            u.append(v[i])
        else:
            u.append(groups[i])

选择

通过将同一位置的实验向量与原始组向量(即原始向量)进行比较,更好的将替换原始组对应的向量,并注意边界除数。

bestPath = []

def select():
    global bestScore
    global bestOne
    for i in range(max_group):
        s1 = func(u[i].copy())
        s2 = func(groups[i].copy())
        if s1 > s2 and s1 > bestScore:
            groups[i] = u[i]
            for j in range(len(groups[i])):
                if groups[i][j] < lower_range:
                    groups[i][j] = lower_range
                if groups[i][j] > upper_range:
                    groups[i][j] = upper_range

            bestScore = s1
            bestOne = groups[i]
    bestPath.append(bestOne.copy())

在正式组装各个组件之前,我们先构建一个绘图功能,直观地观察装配过程

def plt_image(cur):
    if not os.path.exists(savePath):
        os.mkdir(savePath)

    x = np.linspace(-6, 6, 30)
    y = np.linspace(-6, 6, 30)

    X, Y = np.meshgrid(x, y)
    Z = f(X, Y)
    ax = plt.axes(projection='3d')
    ax.contour3D(X, Y, Z, 25, c=Z)
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    ax.set_title('寻优过程')
    if bestOne is not None:
        ax.plot3D(bestPath[:, 0], bestPath[:, 1], func(bestPath), c="r")
    plt.savefig(os.path.join(savePath, str(cur) + '.png'))
    plt.show()

交叉进化和召唤

def Alternative_Evolutionary():
    for i in range(epochs):
        global v
        v = []
        variation()
        global u
        u = []
        cross()
        select()
        global bestScore
        global bestOne

        print("Epoch : ", i, " Score : ", bestScore)



Alternative_Evolutionary()
bestPath = np.array(bestPath)
plt_image(0)

拟合效果

由于初始化(生成随机数)不同,所以每次运行的结果不会完全相同,但是最终的bestScore总是相似的
智能优化算法——python手动实现交叉进化算法
智能优化算法——python手动实现交叉进化算法

代码

执行以上所有代码,才能成为完整的代码
如果需要类封装后的代码,可以从下面下载

GitHub地址:
https://github.com/AiXing-w/Python-Intelligent-Optimization-Algorithms
CSDN地址:
https://download.csdn.net/download/DuLNode/84048830

版权声明:本文为博主艾醒原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/DuLNode/article/details/123367702

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2022年3月11日 下午4:29
下一篇 2022年3月11日 下午4:44

相关推荐