为了应对更加复杂的问题,不同的编码方式的问题,对此进行代码讲解,个人觉得这个遗传算法库做的很好,上手比较快,适用性很强,强烈推荐,用的很顺手。
示例说明:
a = [0~30连续数] * _num
b = [1 ~ num num个数排列排序] 即数列 1~num 不重复排列
c = [0~30离散数(整数)] * _num
score 设置为a,b,c进行运算后数列的最大值
import geatpy as ea
import numpy as np
# 示例说明:
# a = [0~30连续数] * _num
# b = [1 ~ num num个数排列排序] 即数列 1~num 不重复排列
# c = [0~30离散数(整数)] * _num
def func(a, b, c):
return np.sin(np.pi * a * b) * np.cos(np.pi * c * b) * np.tan(np.pi * a * b * c)
# 初始化文件num大小
_num = 10
# 自定义 GA
class My_nsga(ea.Problem):
def __init__(self):
global _num
name = 'GEATPY Facilitate Learning'
# 只优化func一个变量
M = 1
# 最大化变量
maxormins = [-1] * M
# 一共有 a.size + b.size + c.size 个数
Dim = _num + _num + _num
# a 连续, b and c 离散
varTypes = [0] * _num + [1] * _num + [1] * _num
# a ∈ [0,30], b ∈ [1,_num], c ∈ [0,30]
lb = [0] * _num + [1] * _num + [0] * _num
ub = [30] * _num + [_num] * _num + [30] * _num
# 下限可取
lbin = [1] * Dim
# 上限可取
ubin = [1] * Dim
# 保存最大数据
self.max_ans = 0
# epoch
self.epoch = 0
# super
ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)
# 目标函数即神经网络返回值
def evalVars(self, Vars):
# init ans
ans = np.zeros(len(Vars), dtype=float).reshape(len(Vars), 1)
for i in range(len(Vars)):
# 一定要确定区域选择是否正确
a = Vars[i][:_num]
# 可以选择int类型防止特定错误,因为正常输出时为float,具体问题可能会出错
b = list(map(int, Vars[i][_num: _num + _num]))
c = Vars[i][-_num:]
score = func(a, b, c)
ans[i] = score.max()
self.max_ans = (now_max := ans.max())
print(f"Epoch: {self.epoch + 1}, Epoch Max: {now_max}, Global Max: {self.max_ans}")
self.epoch += 1
return ans
# 运行 GA
def Run_nsga(ndind=10, maxgen=100, *args, **kwargs):
global _num
# init problem
problem = My_nsga()
# 染色体编码方式为[格雷编码,排列编码,格雷编码]
encodings = ["RI", "P", "RI"]
# 设置具体field,一定要多加这一部,geatpy还没有具体到能直接输入encoding: List[str],需要进行转换才能使用
# 一定要注意数组范围,报错的话一定要仔细检查!!!
field1 = ea.crtfld(encodings[0], problem.varTypes[:_num], problem.ranges[:, :_num], problem.borders[:, :_num])
field2 = ea.crtfld(encodings[1], problem.varTypes[_num: _num + _num], problem.ranges[:, _num: _num + _num], problem.borders[:, _num: _num + _num])
field3 = ea.crtfld(encodings[2], problem.varTypes[-_num:], problem.ranges[:, -_num:], problem.borders[:, -_num:])
# 合并field
fields = [field1, field2, field3]
# 代入模板
myAlgorithm = ea.soea_psy_EGA_templet(problem, ea.PsyPopulation(Encodings=encodings, Fields=fields, NIND=ndind), MAXGEN=maxgen, logTras=0)
# 是否画图
myAlgorithm.drawing = 0
# 进行优化
res = ea.optimize(myAlgorithm, seed=1, verbose=False, drawing=0, outputMsg=True, drawLog=False, saveFlag=False, dirName='result')
return res['Vars'][0]
if __name__ == "__main__":
Run_nsga(50, 1000)
如果你的问题还要复杂,需要对数据进行初始化,对种群进行初始化,使得模型训练更加可靠,可以在 ea.optimize 添加 prophet=prophet 。示例如下
def getProphet(dim, ndind, *args, **kwargs):
prophet = np.zeros(shape=(ndind, dim), dtype=int)
for i in range(ndind):
prophet[i] = [random.random()] * dim
return prophet
prophet = getProphet(_num * 3, ndind)
res = ea.optimize(myAlgorithm, prophet=prophet, seed=1, verbose=False, drawing=0, outputMsg=True, drawLog=False, saveFlag=False, dirName='result')