今天将用python实现GEP算法中,初始化操作:
生成样本数据、定义函数、参数初始化,生成初始种群
【PS:注意结合前边内容,本次也是首次开始用Python 的编程,如果对一些python库比较陌生的可以边学边看,对于Genome 类,开始可能不清楚为什么这样设置,也不用太纠结。重点在如何初始种群。】
基因表达式编程(GEP)自学 第【1】天 Python 实现
基因表达式编程(GEP)自学 第【2】天 Python 实现
基因表达式编程(GEP)自学 第【3】天 Python 实现
import random
import math
import numpy as np
import sympy
为了方便之后边的测试,这里我将自动生成样本数据:
GenerateData(DataCount=10)
随机生成样本数据:根据:Function的公式生成
X_Input 保存输入参数
Y_Output 保存输出值
InputsOutputs 保存输入与输出集合
输出格式:
X_Input:
[[3, 1], [1, 1], [0, 4]]
Y_Output:
[[35], [15], [20]]
InputsOutputs:
([[3, 1], [1, 1], [0, 4]], [[35], [15], [20]])
def GenerateData(DataCount=10):
'''
随机生成样本数据:根据:Function的公式生成
X_Input 保存输入参数
Y_Output 保存输出值
InputsOutputs 保存输入与输出集合
输出格式:
X_Input:
[[3, 1], [1, 1], [0, 4]]
Y_Output:
[[35], [15], [20]]
InputsOutputs:
([[3, 1], [1, 1], [0, 4]], [[35], [15], [20]])
'''
X_Input=[]
Y_Output=[]
for i in range(DataCount):
random.seed(i)
A = random.randint(0, 5)
random.seed(i+DataCount)
B = random.randint(0, 5)
X_Input.append([A,B])
Y_Output.append([Function(A,B)])
#---------------输出测试Begin--------------#
# print("X_Input:\n",X_Input)
# print("Y_Output:\n",Y_Output)
# print("InputsOutputs:\n",InputsOutputs)
#----------------输出测试end---------------#
InputsOutputs=(X_Input,Y_Output)
return InputsOutputs
输出结果:
X_Input:
[[3, 1], [1, 1], [0, 4]]
Y_Output:
[[35], [15], [20]]
InputsOutputs:
([[3, 1], [1, 1], [0, 4]], [[35], [15], [20]])
在初始化前,我们要定义下函数、终结符:
class Genome():
'''对函数符运算进行定义、终结符定义'''
def __init__(self):
'''定义函数、终结符
functions 保存函数 如:*,/,+,—
terminals 保存终结符 如:a,b
genicTerminals 保存连接基因的终结符 如:0,1,2
'''
self.functions = {"max_arity": 0}
self.terminals = []
self.genicTerminals = range(1)
#定义 add ,sub ,mul ,div 函数的运算
#进行div保护,当除数为小于1e-6时,将除数设置为1
def add(inputs):
inputs.append(inputs.pop(-2) + inputs.pop(-1))
def sub(inputs):
inputs.append(inputs.pop(-2) - inputs.pop(-1))
def mul(inputs):
inputs.append(inputs.pop(-2) * inputs.pop(-1))
def div(inputs):
if abs(inputs[-1]) < 1e-6:
inputs[-1] = 1
inputs.append(inputs.pop(-2) / inputs.pop(-1))
#运算符特征【'+':2,'-':2,'a':0,'b':0】
def symbols(self):
symbols = self.functions.copy()
symbols.pop("max_arity", None)
for symbol in symbols.keys():
symbols[symbol] = symbols[symbol][1]
symbols.update({terminal: 0 for terminal in self.terminals + list(self.genicTerminals)})
return symbols
'''传统基因函数集合、连接基因函数集合:
对于:{"+": (add, 2),"max_arity": 2}
+是运算符,add保存是对应的运算,2是需要参数个数
max_arity 是保存最大需要的参数个数,2是最大需要参数个数'''
arithmetic_set = {"+": (add, 2), "-": (sub, 2), "*": (mul, 2), "/": (div, 2),"max_arity": 2}
linker_set = {"+": (add, 2), "-": (sub, 2), "*": (mul, 2), "/": (div, 2),"max_arity": 2}
深度解析 :
arithmetic_set:
‘’‘传统基因函数集合、连接基因函数集合:
对于:{“+”: (add, 2),“max_arity”: 2}
+是运算符,add保存是对应的运算,2是需要参数个数
max_arity 是保存最大需要的参数个数,2是最大需要参数个数’‘’
arithmetic_set = {“+”: (add, 2), “-”: (sub, 2), ““: (mul, 2), “/”: (div, 2),“max_arity”: 2}
linker_set = {”+": (add, 2), “-”: (sub, 2), "”: (mul, 2), “/”: (div, 2),“max_arity”: 2}
symbols 函数:
作用理解为保留数字特征,
在 arithmetic_set 中保留了
运算符、运算,参数个数、和特别的最大需要的参数个数"max_arity": 2
symbols 作用将保留运算符和特征 如下:
假设self.functions = arithmetic_set
self.terminals = [“a”,“b”]
self.genicTerminals=[“0”]
将运算符特征 arithmetic_set = {“+”: (add, 2), “-”: (sub, 2), “*”: (mul, 2), “/”: (div, 2),“max_arity”: 2}
返回 symbols 为{‘+’: 2, ‘-’: 2, ‘*’: 2, ‘/’: 2, ‘a’: 0, ‘b’: 0, 0: 0}
def symbols(self):
symbols = self.functions.copy()
symbols.pop("max_arity", None)
for symbol in symbols.keys():
symbols[symbol] = symbols[symbol][1]
symbols.update({terminal: 0 for terminal in self.terminals + list(self.genicTerminals)})
return symbols
设计的思路:主要是分为Environment、Chromosome、Gene
简单理解Environment理解为种群;一个种群有多个Chromosome 染色体,而一个Chromosome里有多个Gene 基因。
初始化部分:
class Environment:
def __init__(self):
'''
population 种群:用于保存染色体
bestChromosome 最佳染色体:保存当代最佳染色体
bestfitness 最佳染色体的适应度:保证当代最佳染色体的适应度
homeoticRate 连接基因突变率
mutationRate 突变
ISTranspositionRate IS
RISTranspositionRate RIS
geneTranspositionRate 基因转座
onePointRecombinationRate 单点重组
twoPointRecombinationRate 两点重组
geneRecombination 基因重组
'''
self.population = []
self.bestChromosome=[]
self.bestfitness=0
self.homeoticRate = 0
self.mutationRate = 0
self.ISTranspositionRate = 0
self.RISTranspositionRate = 0
self.geneTranspositionRate = 0
self.onePointRecombinationRate = 0
self.twoPointRecombinationRate = 0
self.geneRecombination=0
def setRates(self, homeoticRate=0, mutationRate=0,ISTranspositionRate=0, RISTranspositionRate=0, geneTranspositionRate=0, onePointRecombinationRate=0, twoPointRecombinationRate=0, geneRecombinationRate=0):
'''
homeoticRate 连接基因突变率
mutationRate 突变
ISTranspositionRate IS
RISTranspositionRate RIS
geneTranspositionRate 基因转座
onePointRecombinationRate 单点重组
twoPointRecombinationRate 两点重组
geneRecombination 基因重组
'''
self.homeoticRate = homeoticRate
self.mutationRate = mutationRate
self.ISTranspositionRate = ISTranspositionRate
self.RISTranspositionRate = RISTranspositionRate
self.geneTranspositionRate = geneTranspositionRate
self.onePointRecombinationRate = onePointRecombinationRate
self.twoPointRecombinationRate = twoPointRecombinationRate
self.geneRecombinationRate = geneRecombinationRate
def init(self, populationSize, numGenes, numHomeotics, headLength, homeoticHeadLength, genome,link_genome):
'''
初始化种群
populationSize 种群大小
numGenes 染色体基因个数
numHomeotics 染色体连接基因个数
headLength 基因头部长度
homeoticHeadLength 连接基因头部长度
genome 基因 Genome类
link_genome 连接 link_genome 类
'''
self.population = [Chromosome().initRand(numGenes, numHomeotics, headLength, homeoticHeadLength, genome,link_genome) for i in range(populationSize)]
初始化部分
class Chromosome():
def __init__(self):
'''
genes 基因:用于保存传统基因
homeotics 连接基因:用于保存连接基因
'''
self.genes = []
self.homeotics = []
#染色体(基因、连接函数)
def initRand(self, numGenes, numHomeotics, headLength, homeoticHeadLength, genome, link_genome):
'''
初始化染色体
:param numGenes: 基因个数
:param numHomeotics: 连接基因个数
:param headLength: 基因头部长度
:param homeoticHeadLength: 连接基因头部长度
:param genome: 基因 Genome
:param link_genome: 连接基因 Genome
:return self:
genes 基因:用于保存传统基因
homeotics 连接基因:用于保存连接基因
'''
self.genes = [Gene(genome, False).initRand(headLength, numGenes) for i in range(numGenes)]
self.homeotics = [Gene(link_genome, True).initRand(homeoticHeadLength, numGenes) for i in range(numHomeotics)]
return self
初始化部分
class Gene():
def __init__(self, genome, homeotic_flag):
'''
genome: 基因的 Genome
homeotic_flag: Flag值 True:为homeotic基因 False: 为传统基因
head 基因头部
tail 基因尾部
'''
self.genome = genome
self.homeotic_flag = homeotic_flag
self.head = []
self.tail = []
def initRand(self, headLength, numGenes):
'''
:param headLength: 基因头部长度
:param numGenes: 基因个数
:return:self
max_arity 保存最大需要的参数个数
functions 保存Genome中操作符 如:["+","-","*","/"]
homeotic_flag: Flag值 True:为homeotic基因 False: 为传统基因
'''
max_arity = self.genome.functions["max_arity"]
functions = list(self.genome.functions.keys())
functions.pop(functions.index("max_arity")) # functions中剔除max_arity
#生成homeotic的terminals、
if self.homeotic_flag:
terminals = list(range(numGenes))
if numGenes > list(self.genome.genicTerminals)[-1]:
self.genome.genicTerminals = range(numGenes)
else:
terminals = self.genome.terminals
self.head = [random.choice(functions + terminals) for i in range(headLength)]
self.tail = [random.choice(terminals) for i in range(headLength * (max_arity - 1) + 1)]
#基因首个为运算符
self.head[0] = random.choice(functions)
return self
为了更好的我们的观察:
我们在Environment中在定义个函数 printChromosomes用于打印染色体
def printChromosomes(self, generation):
'''
打印染色体
:param generation: 迭代的代数
:return: None
'''
print(generation)
for i in range(len(self.population)):
print(i, ':', end='')
for gene in self.population[i].genes:
print(gene.head + gene.tail, end=':')
for homeotic in self.population[i].homeotics:
print(homeotic.head + homeotic.tail, end=':')
print()
print()
if __name__=='__main__':
#---------------操作数设置 Begin--------------#
genome = Genome()
genome.functions.update(Genome.linker_set)
genome.terminals = ['a','b']
genome.symbols()
my_link_genome=Genome()
my_link_genome.functions.update(Genome.linker_set)
#----------------操作数设置 end---------------#
#---------------种群初始化 Begin--------------#
environment = Environment()
environment.init(populationSize=20,numGenes=3,numHomeotics=1,headLength=4,homeoticHeadLength=5,genome=genome,link_genome=my_link_genome)
environment.setRates(homeoticRate=0.5, mutationRate=0.044,ISTranspositionRate=0.1,
RISTranspositionRate=0.1, geneTranspositionRate=0.1,onePointRecombinationRate=0.3,
twoPointRecombinationRate=0.3, geneRecombinationRate=0.1)
##----------输出测试----------##
environment.printChromosomes(0)
#----------------种群初始化 end---------------#
输出结果:
1
0 :['+', '+', '+', 'b', 'a', 'b', 'a', 'a', 'b']:['+', '/', '/', '-', 'b', 'a', 'b', 'b', 'a']:['/', '-', '-', 'b', 'b', 'b', 'b', 'a', 'b']:['-', '*', 2, 0, 2, 2, 2, 2, 0, 0, 1]:
1 :['/', '-', '*', '-', 'b', 'b', 'a', 'a', 'b']:['*', 'a', 'a', '+', 'a', 'b', 'b', 'b', 'a']:['*', 'a', '-', 'b', 'b', 'b', 'a', 'b', 'a']:['+', 2, 1, '+', 1, 1, 0, 1, 2, 1, 0]:
2 :['/', '+', 'b', '-', 'a', 'b', 'b', 'b', 'b']:['-', '+', '/', 'a', 'b', 'b', 'a', 'a', 'b']:['*', 'b', '-', 'a', 'a', 'b', 'b', 'a', 'a']:['-', '/', '/', 2, 1, 0, 1, 2, 1, 1, 2]:
3 :['*', '+', 'b', 'a', 'a', 'b', 'a', 'b', 'a']:['+', '-', 'a', '+', 'b', 'a', 'a', 'a', 'a']:['*', '+', '/', '*', 'a', 'b', 'a', 'a', 'a']:['/', '+', 1, 1, 2, 0, 0, 0, 2, 2, 0]:
4 :['*', '*', 'b', '-', 'a', 'b', 'a', 'b', 'a']:['+', '/', '*', 'b', 'a', 'b', 'a', 'a', 'a']:['-', '+', 'b', '/', 'b', 'a', 'a', 'b', 'b']:['*', '-', '-', '+', '*', 1, 0, 2, 0, 2, 2]:
5 :['+', '-', '-', '*', 'a', 'a', 'a', 'b', 'b']:['*', '+', '-', 'a', 'a', 'b', 'a', 'b', 'b']:['+', '/', 'b', '-', 'a', 'b', 'b', 'b', 'a']:['+', '/', '+', '+', '-', 1, 2, 1, 1, 2, 1]:
6 :['+', '+', 'b', '/', 'a', 'a', 'a', 'a', 'a']:['*', '+', '-', '+', 'b', 'a', 'a', 'b', 'a']:['*', '*', '-', '+', 'b', 'a', 'b', 'a', 'b']:['-', '*', '/', 0, '+', 2, 1, 0, 0, 1, 0]:
7 :['*', 'b', '-', '-', 'a', 'a', 'a', 'a', 'b']:['/', '+', '+', '/', 'b', 'b', 'a', 'a', 'a']:['*', 'b', '*', '*', 'b', 'a', 'a', 'a', 'b']:['-', '/', '+', 0, '-', 2, 0, 2, 2, 2, 1]:
8 :['-', '-', '*', '+', 'b', 'b', 'b', 'a', 'b']:['*', '*', 'b', 'b', 'b', 'a', 'a', 'b', 'b']:['*', '*', '-', '*', 'a', 'b', 'a', 'a', 'a']:['*', '-', '*', 2, '/', 2, 1, 1, 2, 2, 1]:
9 :['*', '*', '+', 'b', 'b', 'a', 'a', 'a', 'a']:['/', 'a', 'b', '-', 'b', 'a', 'a', 'a', 'a']:['+', '-', '*', '*', 'a', 'b', 'b', 'a', 'a']:['/', '*', '*', '-', 0, 2, 2, 2, 0, 1, 1]:
10 :['-', '+', 'b', '/', 'b', 'a', 'a', 'b', 'b']:['*', 'a', '/', 'b', 'b', 'b', 'b', 'b', 'b']:['-', '*', '+', '/', 'b', 'b', 'a', 'a', 'b']:['+', 1, '+', '/', '/', 0, 2, 2, 2, 1, 2]:
11 :['+', '*', '-', 'b', 'b', 'b', 'b', 'a', 'b']:['*', '+', 'b', 'b', 'b', 'b', 'a', 'b', 'a']:['*', 'b', '-', '/', 'b', 'a', 'a', 'a', 'a']:['*', '-', '/', 0, '+', 1, 0, 0, 0, 0, 2]:
12 :['-', 'b', 'a', 'a', 'b', 'b', 'b', 'b', 'b']:['-', '-', '+', 'b', 'b', 'a', 'b', 'b', 'b']:['/', 'b', '-', '*', 'a', 'b', 'a', 'b', 'b']:['*', 2, '*', 1, '-', 2, 2, 0, 2, 1, 0]:
13 :['*', 'a', 'a', '+', 'b', 'a', 'a', 'a', 'a']:['*', '+', '*', '-', 'b', 'a', 'b', 'a', 'a']:['/', '-', 'b', 'b', 'a', 'a', 'b', 'b', 'a']:['+', '/', '+', 1, 2, 1, 0, 0, 2, 1, 1]:
14 :['-', '-', '*', '*', 'b', 'b', 'b', 'b', 'b']:['+', '*', 'a', 'b', 'a', 'a', 'b', 'a', 'a']:['*', '/', 'b', '+', 'a', 'b', 'a', 'b', 'a']:['*', 2, '-', '/', 2, 0, 2, 1, 2, 1, 0]:
15 :['/', '-', 'b', '+', 'b', 'b', 'b', 'a', 'a']:['*', '*', '*', '/', 'b', 'a', 'a', 'a', 'b']:['-', '-', '/', '*', 'a', 'b', 'a', 'b', 'a']:['-', 1, '/', '*', 0, 0, 2, 1, 2, 2, 0]:
16 :['+', '/', '/', '*', 'b', 'b', 'a', 'b', 'b']:['-', '/', 'a', 'a', 'b', 'a', 'a', 'b', 'b']:['/', '*', '*', 'b', 'b', 'a', 'b', 'a', 'a']:['-', '+', '+', '*', 0, 2, 2, 0, 2, 0, 0]:
17 :['/', '/', 'a', '/', 'b', 'a', 'a', 'b', 'b']:['/', '*', 'a', 'b', 'b', 'a', 'a', 'b', 'a']:['+', '+', '-', '-', 'a', 'b', 'b', 'a', 'b']:['*', 2, 0, '-', 0, 2, 2, 1, 0, 1, 2]:
18 :['*', 'a', 'b', 'b', 'b', 'b', 'a', 'b', 'b']:['*', '-', '*', '-', 'a', 'b', 'b', 'b', 'b']:['-', '+', '/', '-', 'a', 'a', 'b', 'b', 'a']:['*', 2, 0, '+', '-', 2, 1, 0, 2, 0, 1]:
19 :['/', 'b', '-', '/', 'b', 'b', 'b', 'a', 'b']:['/', 'b', '/', '*', 'b', 'a', 'a', 'b', 'b']:['*', '*', 'a', '-', 'b', 'a', 'a', 'a', 'b']:['*', '-', 0, 0, '-', 1, 0, 1, 2, 1, 0]:
为了方便演示,我将每个类整合到一个py文件上,GEP-4 初始化实现.py.
本文作者:九重!
本文链接:https://blog.csdn.net/weixin_43798572/article/details/122823927
关于博主:评论和私信会在第一时间回复。或者直接私信我。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【点赞】【收藏】一下。您的鼓励是博主的最大动力!