在Python的DEAP中,我怎样才能拥有一个具有多个基因的个体,例如"基因型"?

时间:2018-03-08 22:19:08

标签: python numpy genetic-algorithm evolutionary-algorithm deap

TLDR:

如何使用DEAP来演变基因型而不仅仅是基因,例如(Gene1, Gene2, ...){'gene1':..., 'gene2':...}

最小的例子是创建DEAP的OneMax示例的演变,使用基因型(np.ndarray(10), np.ndarray(42)),其中Genotype[0]仅与Genotype[0]配对, ...[1] ...[1] NeuronGene :: np.ndarray(n) NetworkGene :: np.ndarray((n, n)) ,整个基因型可用于评估适应度。

在Python的DEAP中,常见的用例是拥有一个"基因",例如一个列表,可以进行交配,变异和评估其适应性。

我的一般问题是,我想使用基因的异构列表/元组/字典,每个基因都有自己的类型,而交配等功能只能按类型定义。

具体来说,我有一个"神经网络"我想用

代表
  1. 神经元参数的一个基因

  2. 网络结构+参数的一个基因。

  3. 类型(借用类型语言'语法)可能是

    np.dtype([('a', int), ('b', float), ...])

    那些数组是structured numpy arrays,有各种键,例如:NeuronGene,所以在{'a':..., 'b':..., ...}的每个索引处,我都有一个类似字典的参数,其中包含键np.ndarray }。如果这使问题太复杂,我仍然希望看到如何获得通用Individual :: (NeuronGene, NetworkGene)的基因型。

    A"基因型"可能像mate

    正确的mate :: NeuronGene -> NeuronGene -> NeuronGene mate :: NetworkGene -> NetworkGene -> NetworkGene 函数可能被定义为:

    np.ndarray

    作为一个最小的例子,我试图复制DEAP的OneMax问题,但是使用了2个基因的基因型。所以有2个不同大小的n + m,每个都试图单独最大化它们的总和。即使阅读DEAP's docscodebase,我的代码也不值得发布。

    对于像这个最小例子这样的简单问题,确定你可以使用一个长度为(1D array, 2D array)的基因,但在我的实际情况中,我有一个eval的基因和突变/交配意味着该基因型中每个基因的不同之处。

    我应该提一下,我的eval :: Genotype -> Float # or eval :: Genotype -> (Float, Float, ...) 函数只是解析为一个单一的适应度函数,尽管我认为一个适当的一般答案可以优化多个。

    <style>
      Form input[type=button]:first-child {background: url(/image/btn1.png) no-repeat;}
      Form input[type=button]:nth-child(2) {background: url(/image/btn2.png) no-repeat;}
    </style>
    

1 个答案:

答案 0 :(得分:0)

我不确定我完全理解你需要什么,但这可能会有所帮助:

1)使用dict作为单独的容器,制作你的自定义initDict函数

2)编写您的自定义dict版本的交配和个人评估函数,这些函数对个人的不同键执行不同的操作

下面是创建随机数组的类似dict的个体并对其进行评估的示例。然后,您可以修改DEAP基本算法以进行交配,变异等,以便它们可以按照您的需要使用dicts。

from deap import base
from deap import creator
from deap import tools
import numpy as np

def initDict(container, func, dim):
    return container(zip(dim.keys(), map(lambda val: func(val), dim.values())))

def evalIndividual(individual):
    return [individual[key].sum() for key in individual.keys()]

toolbox = base.Toolbox()
creator.create("FitnessMax", base.Fitness, weights=(1.0,1.0))  # fitness
creator.create("Individual", dict, fitness=creator.FitnessMax)

#function for generation arrays of random values and random size in each dimension (min 2, max 10) but fixed number of dimensions by the dim argument
toolbox.register("attr_random", lambda dim: np.random.rand(*np.random.randint(2,10,dim)))
toolbox.register("individual", initDict, creator.Individual, toolbox.attr_random, dim = dict(neuron = 2, network = 3))
ind = toolbox.individual()
ind.fitness.values = evalIndividual(ind)
print(ind.fitness)