基因表达式编程(GEP)自学 第【4】天 Python 实现(代码)

目录

  • 基因表达式编程 GEP Python 代码实现【★★★★】
    • 1. 运行环境
      • 1.1. Python 需要的库
    • 2. Python实现生成数据
    • 3. Python 实现初始化
      • 3.1 Genome 类 定义函数、终结符
      • 3.2 初始突变参数、染色体
        • 3.2.1. Environment:
        • 3.2.2. Chromosome :
        • 3.2.1. Gene:
      • 3.3 打印染色体
    • 4. 初始化输出测试
    • 5. 代码实现整合:

基因表达式编程 GEP Python 代码实现【★★★★】

今天将用python实现GEP算法中,初始化操作:
生成样本数据、定义函数、参数初始化,生成初始种群

【PS:注意结合前边内容,本次也是首次开始用Python 的编程,如果对一些python库比较陌生的可以边学边看,对于Genome 类,开始可能不清楚为什么这样设置,也不用太纠结。重点在如何初始种群。】

基因表达式编程(GEP)自学 第【1】天 Python 实现
基因表达式编程(GEP)自学 第【2】天 Python 实现
基因表达式编程(GEP)自学 第【3】天 Python 实现

1. 运行环境

运行python是G在PyCharm 运行
基因表达式编程(GEP)自学 第【4】天 Python 实现(代码)_第1张图片

1.1. Python 需要的库

import random
import math
import numpy as np
import sympy

2. Python实现生成数据

为了方便之后边的测试,这里我将自动生成样本数据

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]])

3. Python 实现初始化

3.1 Genome 类 定义函数、终结符

在初始化前,我们要定义下函数、终结符:

  • PS:传统基因的连接,用的时连接基因而不是全用“+”
    进行连接,因此在定义下函数、终结符中,我将传统基因的终结符与连接基因的终结符分开。同时传统基因的函数集合、与连接基因的函数集合也设置不同的集合
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

3.2 初始突变参数、染色体

设计的思路:主要是分为Environment、Chromosome、Gene
简单理解Environment理解为种群;一个种群有多个Chromosome 染色体,而一个Chromosome里有多个Gene 基因。

3.2.1. Environment:

初始化部分:

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)]

3.2.2. Chromosome :

初始化部分

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

3.2.1. Gene:

初始化部分

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

3.3 打印染色体

为了更好的我们的观察:
我们在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()

4. 初始化输出测试

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]:

5. 代码实现整合:

为了方便演示,我将每个类整合到一个py文件上,GEP-4 初始化实现.py.

本文作者:九重!
本文链接:https://blog.csdn.net/weixin_43798572/article/details/122823927
关于博主:评论和私信会在第一时间回复。或者直接私信我。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【点赞】【收藏】一下。您的鼓励是博主的最大动力!

你可能感兴趣的:(GEP,python,开发语言,算法)