文章目录

  • 前言
  • 一、优化的内容
  • 二、优化后的代码部分
  • 三、遗传算法使用心得总结



前言

本文主要记录一下我在优化带约束的遗传算法过程踩的一些雷,以及需要注意的一些问题。优化代码的主要部分可以见前面的文章(利用深度学习模型基于遗传算法(GA)寻求最优解)。

一、优化的内容

简单介绍一下需要的优化的部分,调用的深度学习模型有四个输出,需要根据其中两个进行优化。保证在输出热量最小的前提下,获取最大的流量。由于模型训练时进行了归一化,所以在求真实值时,要先还原。

二、优化后的代码部分

简单说一下优化思路:以流量作为遗传算法的适应度。既然要保证最小热量,先求出最小热量对应的流量,在此基础上乘一个惩罚系数得到非最小热量点能达到的最大流量SCCM_max,其他非最小热量点对应的流量都应小于SCCM_max,再依据热量的大小分配适应度的大小,Y_TEMP = 1e-7 + (Q_real_max - abs(Q_real))/(Q_real_max-Q_real_min)*SCCM_max ,热量越小,适应度越大,最大值SCCM_max,最小0。

def F(x):
    num = x.shape[0]
    X2 = []
    T = False
    SCCM_max = 4   #非热中性点和非最低热值点可以取的最大值(归一化后)
    Q_real_min = 10  #热量真实值最小值初值
    Q_real_max = 0  #热量真实值最大值初值
    for i in range(num):   #将种群参数加上固定参数组成训练模型的输入
        X = [nor_V, nor_I, nor_T, x[i]]
        X2.append(X)
    Xtest = np.array(X2)
    X_test = Xtest.reshape(-1, 4)
    Y_pre = model.predict(X_test)

    for i in range(num):  #遍历,判断能否达到热中性
        if Y_pre[i, 0] > 3.8 or Y_pre[i, 0] < 0:  # 当预测值出现偏差超出最大流量限制,或比最小流量小时,跳出循环
                print("\n参数选择异常,SCCM>1200或SCCM<300,请重新选择合理参数\n")
                exit()
        Q_real = (Y_pre[i, -1] - 0.2) / 0.8 * (9.4078 + 1.4588) - 1.4588  # 将输出参数由归一化值转为实际值

        # if Y_pre[i, 0] < SCCM_min:  #流量的最小值(归一化后)   最小值可能比能达到的最大值SCCM_MAX大  所以不如取0
        #     SCCM_min = Y_pre[i, 0]

        if abs(Q_real) < 1e-7:
            T = True
            if Y_pre[i, 0] < SCCM_max:
                SCCM_max = 0.7 * Y_pre[i, 0]   #如果能达到热中性,所有热中性点中的最小SCCM为非热中性点可以达到的最大值,非热中性点适应度应当更小,加上惩罚数
        if abs(Q_real) > Q_real_max:
            Q_real_max = abs(Q_real)   #得到该条件下热量真实值最大值

    i_last = 0
    if T == False:   #如果达不到热中性计算热量最小值
        for i in range(num):
            Q_real = (Y_pre[i, -1] - 0.2) / 0.8 * (9.4078 + 1.4588) - 1.4588  # 将输出参数由归一化值转为实际值
            if abs(Q_real) < Q_real_min:
                Q_real_min = abs(Q_real)
                i_last = i
                SCCM_max = 0.7 * Y_pre[i, 0] #最小放热量对应的流量,应成为其他点可以达到的最大适应度

    # if SCCM_max < 0:  #防止非热中性点的流量归一化值在加上惩罚数以后小于最小0
    #     SCCM_max = 0.0000001

    for i in range(num):    #限制条件:热中性,同时排除个别误差值较大的数据的影响
        Q_real = (Y_pre[i, -1] - 0.2) / 0.8 * (9.4078 + 1.4588) - 1.4588  # 将输出参数由归一化值转为实际值
        if abs(Q_real) > 1e-7:
            if abs(Q_real) > Q_real_min:
                Y_TEMP = 1e-7 + (Q_real_max - abs(Q_real))/(Q_real_max-Q_real_min)*SCCM_max  #惩罚函数,无法达到热中性时减小适应度,离最低Q越近适应度越大,不能超过SCCM_max
                if Y_TEMP < Y_pre[i, 0]:   #加上惩罚函数的适应度小于原适应度,替换原适应度
                    Y_pre[i, 0] = Y_TEMP

    Q_MIN_EPOCH.append(Q_real_min)
    xH2O.append(Xtest[i_last, 3])

    return Y_pre[:, 0]   #返回燃料极流量归一化值

三、遗传算法使用心得总结

1、初始种群数量不宜过大过小,一般在50-200,对不同问题的适应程度也不一样,过大会导致收敛慢,最大适应度的个体对整体进化的影响小,可能会导致优化解震荡,过小可能陷入局部最优。例如:当初始种群数量选择100时,收敛情况如下图:

遗传算法优化bp神经网络步骤 遗传算法优化cnn_SCCM


当初始种群数量选择200时,会频繁震荡

遗传算法优化bp神经网络步骤 遗传算法优化cnn_python_02


2、基因编码的位数不宜过多过少,例如,当选择编码位数为10时,有下图

遗传算法优化bp神经网络步骤 遗传算法优化cnn_python_03


当选择基因编码位数为5时,有下图

遗传算法优化bp神经网络步骤 遗传算法优化cnn_算法_04


3、惩罚函数不宜过大过小,惩罚函数过大会导致直接收敛,容易陷入局部最优解,过小会导致求解震荡。

4、当求解震荡时,可能是因为适应度取值太小,解决方案可以选择,一、进行指数扩大,放大适应度,二、加判定收敛的条件,当适应度变化连续小于多少时,结束循环。前者适用于适应度很小影响大的,后者适用于适应度小范围变化影响不大的情况,如本文中的,虽然从图像来看波动很大,但实际上,适应度变化很小,是因为坐标轴刻度比较小。