Python遗传算法框架DEAP-Operators and Algorithms

Before starting with complex algorithms, we will see some basics of DEAP. First, we will start by creating simple individuals (as seen in the Creating Types tutorial) and make them interact with each other using different operators. Afterwards, we will learn how to use the algorithms and other tools.
在开始复杂的算法以前,咱们将会看到一些基础的东西。首先,咱们开始建立简单的个体(以前的教程中介绍了)和让它们利用操做算子互相做用。而后,咱们将学习怎么使用算法和其余工具。html

A First Individual(第一个个体)

First import the required modules and register the different functions required to create individuals that are lists of floats with a minimizing two objectives fitness.
一开始导入须要模块和注册不一样的函数去建立个体(浮点数列表),求解的是一个最小化二目标适应度问题。算法

import random
 
from deap import base
from deap import creator
from deap import tools
 
IND_SIZE = 5
 
creator.create("FitnessMin", base.Fitness, weights=(-1.0, -1.0))
creator.create("Individual", list, fitness=creator.FitnessMin)
 
toolbox = base.Toolbox()
toolbox.register("attr_float", random.random)
toolbox.register("individual", tools.initRepeat, creator.Individual,
                 toolbox.attr_float, n=IND_SIZE)

The first individual can now be built by adding the appropriate line to the script.
第一个个体如今能用合适一行代码去建立添加了。spring

ind1 = toolbox.individual()

Printing the individual ind1 and checking if its fitness is valid will give something like this
打印出个体ind1,检查它的适应度是否有效:api

print ind1               # [0.86..., 0.27..., 0.70..., 0.03..., 0.87...]
print ind1.fitness.valid # False

The individual is printed as its base class representation (here a list) and the fitness is invalid because it contains no values.
这个个体打印出来了。这个适应度是无效的,由于没有值。app

Evaluation(重头戏来了,评价函数/适应度函数)

The evaluation is the most personal part of an evolutionary algorithm, it is the only part of the library that you must write yourself. A typical evaluation function takes one individual as argument and returns its fitness as a tuple. As shown in the in the core section, a fitness is a list of floating point values and has a property valid to know if this individual shall be re-evaluated. The fitness is set by setting the values to the associated tuple. For example, the following evaluates the previously created individual ind1 and assigns its fitness to the corresponding values.
评价函数部分是评价算法中最“我的”的部分,它是库中你必须本身写的一部分。一个典型的评价函数须要一个个体做为参数,而后返回这个个体的fitness(以tuple格式)。在核心部分所示,一个适应度值是一个浮点值的列表并有一个有效的属性来知道这个个体是否应当从新评估。这个适应度值是经过设置值和元祖关联。举个例子,下面的选择评价以前建立的个体ind1,同时,分配它的fitness给相应的值。
(⊙o⊙)…让我回忆起专业英语翻译文章的感受了,难以读懂。硬着头皮往下看吧。dom

def evaluate(individual):
    # Do some hard computing on the individual
    a = sum(individual)
    b = len(individual)
    return a, 1. / b
 
ind1.fitness.values = evaluate(ind1)
print ind1.fitness.valid    # True    原来有`fitness`是True!搜嘎
print ind1.fitness          # (2.73, 0.2)上面建立的个体IND_SIZE=5,因此这里是1/5=0.2

Dealing with single objective fitness is not different, the evaluation function must return a tuple because single-objective is treated as a special case of multi-objective.
与处理单目标适应度不一样,这里评价函数必须返回一个元祖由于单目标是做为多目标的一个特例而已。ide

Mutation(变异)

There is a variety of mutation operators in the deap.tools module. Each mutation has its own characteristics and may be applied to different types of individuals. Be careful to read the documentation of the selected operator in order to avoid undesirable behaviour.
deap.tools module模块那儿有不少变异操做算子。每一个变异算子有它本身的特征,能够应用到不一样类型的个体上。仔细阅读选择算子的文档,从而避免没法理解的行为。函数

The general rule for mutation operators is that they only mutate, this means that an independent copy must be made prior to mutating the individual if the original individual has to be kept or is a reference to another individual (see the selection operator).
变异算子的整体规则就是他们只是变异,这意味着一个独立的副本必须在变异个体操做以前,若是原始个体必需要保存或者是另外个体的参考(看选择算子)。工具

In order to apply a mutation (here a gaussian mutation) on the individual ind1, simply apply the desired function.
为了在个体ind1上施行变异(这里是高斯变异),简单应用了所需的函数。学习

mutant = toolbox.clone(ind1)
ind2, = tools.mutGaussian(mutant, mu=0.0, sigma=0.2, indpb=0.2)
del mutant.fitness.values

The fitness’ values are deleted because they’re not related to the individual anymore. As stated above, the mutation does mutate and only mutate an individual it is neither responsible of invalidating the fitness nor anything else. The following shows that ind2 and mutant are in fact the same individual.
适应度值被删除了,由于它们再也不和这个个体相关了(由于变异了嘛!!!)。如上面所述,这个变异算子只是变异而且只是变异一个个体,它也不对适应度的无效负责或者其它。下面展现了ind2,变异算子事实上一样的个体。(不是很明白这里)

print ind2 is mutant    # True
print mutant is ind1    # False

Crossover(交叉)

The second kind of operator that we will present is the crossover operator. There is a variety of crossover operators in the deap.tools module. Each crossover has its own characteristics and may be applied to different types of individuals. Be careful to read the documentation of the selected operator in order to avoid undesirable behaviour.
咱们将要展现的第二种操做算子是交叉算子。在deap.tools module模块中有不少交叉算子。每种交叉算子有它本身的特性,可能适用于不一样类型的个体。仔细阅读选择算子的文档从而避免没法理解的的行为。

The general rule for crossover operators is that they only mate individuals, this means that an independent copies must be made prior to mating the individuals if the original individuals have to be kept or are references to other individuals (see the selection operator).
交叉算子的整体规则是它们值负责交叉个体,这意味着在交叉个体以前需独立的副本,若是原始个体不得不被保存或者做为其余个体的参考(看选择算子)。

Lets apply a crossover operation to produce the two children that are cloned beforehand.
让咱们施行交叉算子来产生两个子孙(事先已经被“克隆”了)。

child1, child2 = [toolbox.clone(ind) for ind in (ind1, ind2)]
tools.cxBlend(child1, child2, 0.5)
del child1.fitness.values
del child2.fitness.values

Selection(选择)

Selection is made among a population by the selection operators that are available in the deap.tools module. The selection operator usually takes as first argument an iterable container of individuals and the number of individuals to select. It returns a list containing the references to the selected individuals. The selection is made as follow.
选择是经过选择算子在种群中操做的,它能够在deap.tools module模块中得到。这个选择算子操做一般第一个参数是个体们的可迭代容器,以及要选择个体的个数。它返回的是选择个体们的应用列表。选择算子操做示例以下:

selected = tools.selBest([child1, child2], 2)
print child1 in selected    # True

Usually duplication of the entire population will be made after selection or before variation.
一般在选择或者变异以后,会作整个种群的副本。

selected = toolbox.select(population, LAMBDA)
offspring = [toolbox.clone(ind) for ind in selected]

Using the Toolbox(使用工具箱)

The toolbox is intended to contain all the evolutionary tools, from the object initializers to the evaluation operator. It allows easy configuration of each algorithm. The toolbox has basically two methods, register() and unregister(), that are used to add or remove tools from the toolbox.
工具箱是来包含全部进化工具的,从对象的初始化到评价操做算子。它容许每种算法的配置。工具箱有两个基本的方法,register()unregister(),这个用来从工具箱中增长或者移除工具的。

This part of the tutorial will focus on registration of the evolutionary tools in the toolbox rather than the initialization tools. The usual names for the evolutionary tools are mate(), mutate(), evaluate() and select(), however, any name can be registered as long as it is unique. Here is how they are registered in the toolbox.
教程的这部分将会专一于工具箱中进化工具的注册而不是初始化工具。进化工具一般的名字是mate(),mutate(),evaluate(),select(),然而,任何名字都是能够被注册的,只要它是独一无二的。这里展现了它们是怎么被注册进工具箱的:

from deap import base
from deap import tools

toolbox = base.Toolbox()

def evaluateInd(individual):
    # Do some computation
    return result,

toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("evaluate", evaluateInd)

Using the toolbox for registering tools helps keeping the rest of the algorithms independent from the operator set. Using this scheme makes it very easy to locate and change any tool in the toolbox if needed.
使用工具箱注册工具备助于保持其他算法独立于操做符的集合。使用这种方案使得它很容易定位和改变工具箱中的任何工具。

Using the Tools(使用工具)

When building evolutionary algorithms the toolbox is used to contain the operators, which are called using their generic name. For example, here is a very simple generational evolutionary algorithm.
当创建进化算法时,工具箱是用来容纳这个操做算子的,就是被称为使用它们的通用名字。例如,这里是一个很是简单的进化算法。

for g in range(NGEN):
    # Select the next generation individuals
    offspring = toolbox.select(pop, len(pop))
    # Clone the selected individuals
    offspring = map(toolbox.clone, offspring)

    # Apply crossover on the offspring
    for child1, child2 in zip(offspring[::2], offspring[1::2]):
        if random.random() < CXPB:
            toolbox.mate(child1, child2)
            del child1.fitness.values
            del child2.fitness.values

    # Apply mutation on the offspring
    for mutant in offspring:
        if random.random() < MUTPB:
            toolbox.mutate(mutant)
            del mutant.fitness.values

    # Evaluate the individuals with an invalid fitness
    invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
    fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
    for ind, fit in zip(invalid_ind, fitnesses):
        ind.fitness.values = fit

    # The population is entirely replaced by the offspring
    pop[:] = offspring

This is a complete algorithm. It is generic enough to accept any kind of individual and any operator, as long as the operators are suitable for the chosen individual type. As shown in the last example, the usage of the toolbox allows to write algorithms that are as close as possible to pseudo code. Now it is up to you to write and experiment on your own.
这是一个完整的算法。它是足够通用的来接收各类个体和任何操做算子,只要操做算子是是适合选择的个体类型。正如最后一个例子所示,工具箱的使用容许写算法(和伪代码尽量相近)。如今取决于你本身写、实验你的算法。

Tool Decoration(工具装饰)

Tool decoration is a very powerful feature that helps to control very precise things during an evolution without changing anything in the algorithm or operators. A decorator is a wrapper that is called instead of a function. It is asked to make some initialization and termination work before and after the actual function is called.
工具装饰是一个很是强大的特性,在进化过程当中它有助于控制很是精确的东西而不须要改变算法或者算子的其余东西。一个装饰器被称为一个包装器而不是一个函数。它是在一些初始化和终止工做的时候被访问,在实际函数调用以前或者以后。

For example, in the case of a constrained domain, one can apply a decorator to the mutation and crossover in order to keep any individual from being out-of-bound. The following defines a decorator that checks if any attribute in the list is out-of-bound and clips it if this is the case. The decorator is defined using three functions in order to receive the min and max arguments. Whenever the mutation or crossover is called, bounds will be checked on the resulting individuals.
例如,在约束域的例子里,一个能对变异和交叉引用装饰器为了不个体出界,若是出界就去除它。装饰器使用三个函数来定义为了接受最小和最大的参数。变异或交叉操做不管何时被调用,都会对结果个体们进行范围检查。
╮(╯▽╰)╭无奈,不明白啊,加油

def checkBounds(min, max):
    def decorator(func):
        def wrapper(*args, **kargs):
            offspring = func(*args, **kargs)
            for child in offspring:
                for i in xrange(len(child)):
                    if child[i] > max:
                        child[i] = max
                    elif child[i] < min:
                        child[i] = min
            return offspring
        return wrapper
    return decorator

toolbox.register("mate", tools.cxBlend, alpha=0.2)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=2)

toolbox.decorate("mate", checkBounds(MIN, MAX))
toolbox.decorate("mutate", checkBounds(MIN, MAX))

This will work on crossover and mutation because both return a tuple of individuals. The mutation is often considered to return a single individual but again like for the evaluation, the single individual case is a special case of the multiple individual case.这将会做用在交叉和变异算子上由于二者都返回一个个体们的元祖。变异一般被认为返回一个单一个体可是却像评估算子同样,单一个体的例子是多目标的一个特殊例子。

相关文章
相关标签/搜索