文章目录
- 前言
- 一、优化的内容
- 二、优化后的代码部分
- 三、遗传算法使用心得总结
前言
本文主要记录一下我在优化带约束的遗传算法过程踩的一些雷,以及需要注意的一些问题。优化代码的主要部分可以见前面的文章(利用深度学习模型基于遗传算法(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时,收敛情况如下图:
当初始种群数量选择200时,会频繁震荡
2、基因编码的位数不宜过多过少,例如,当选择编码位数为10时,有下图
当选择基因编码位数为5时,有下图
3、惩罚函数不宜过大过小,惩罚函数过大会导致直接收敛,容易陷入局部最优解,过小会导致求解震荡。
4、当求解震荡时,可能是因为适应度取值太小,解决方案可以选择,一、进行指数扩大,放大适应度,二、加判定收敛的条件,当适应度变化连续小于多少时,结束循环。前者适用于适应度很小影响大的,后者适用于适应度小范围变化影响不大的情况,如本文中的,虽然从图像来看波动很大,但实际上,适应度变化很小,是因为坐标轴刻度比较小。