简体   繁体   English

使用 DEAP 的遗传算法中违反了界限

[英]bounds violated in genetic algorithm using DEAP

I am new using DEAP.我是使用 DEAP 的新手。 My task is to optimize a technical system, which needs parameters as int and float values in a specific range.我的任务是优化一个技术系统,该系统需要特定范围内的 int 和 float 值作为参数。

As a first step I wrote a small script based on the DEAP documentation .作为第一步,我根据DEAP 文档编写了一个小脚本。

import random

from deap import base
from deap import creator
from deap import tools

CXPB, MUTPB = 0.2, 0.2
IND_SIZE = 1
POP_SIZE = 10
GEN_SIZE = 50
MIN_1, MAX_1 = 7.5, 8.5 
MIN_2, MAX_2 = 20, 60 

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.uniform, MIN_1, MAX_1)
toolbox.register("attr_int"  , random.randint, MIN_2, MAX_2)
toolbox.register("individual", tools.initCycle, creator.Individual,(toolbox.attr_int,toolbox.attr_float), IND_SIZE)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

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

def evaluate(individual):
    print ('evaluate:',individual)
    a = sum(individual)
    b = len(individual)
    return a, 1. / b
toolbox.register("evaluate", evaluate)

pop = toolbox.population(n=POP_SIZE)

for g in range(GEN_SIZE):
    print ('generation',g)
    # 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

During running this script I found, that the values of attr_float and attr_int are violating the bounds given with MIN_1, MIN_2, MAX_1 and MAX_2 during the generations.在运行此脚本期间,我发现 attr_float 和 attr_int 的值在世代中违反了 MIN_1、MIN_2、MAX_1 和 MAX_2 给出的界限。 Also the type of attr_int is changing after some generations attr_int 的类型也在几代之后发生变化

('generation', 0)
('evaluate:', [20, 8.307457724269371])
('evaluate:', [40, 8.035611879681108])
('evaluate:', [31, 8.331020742869226])
('evaluate:', [50, 8.370955173904012])
('evaluate:', [29, 8.427249762963857])
('evaluate:', [31, 8.331020742869226])
('evaluate:', [21, 7.6194437005665065])
('evaluate:', [24, 8.465103759419549])
('evaluate:', [21, 7.6194437005665065])
('evaluate:', [58, 8.367292359534245])
('generation', 1)
('evaluate:', [21, 7.6194437005665065])
('evaluate:', [29, 8.427249762963857])
('evaluate:', [29, 8.427249762963857])
('evaluate:', [21, 8.465103759419549])
('evaluate:', [24, 7.6194437005665065])
('generation', 2)
('evaluate:', [20, 8.396172876010239])
('evaluate:', [21, 8.465103759419549])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [21, 9.858264850764389])
('generation', 3)
('evaluate:', [21, 8.465103759419549])
('generation', 4)
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('generation', 5)
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('generation', 6)
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20.078343870132688, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('generation', 7)
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.402212748253602])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('generation', 8)
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 8.307457724269371])
('evaluate:', [20, 7.615346845706964])
('generation', 9)
('evaluate:', [20, 8.307457724269371])
('evaluate:', [18.96281744779058, 7.615346845706964])
    
[...]

('generation', 49)
('evaluate:', [17.61774546537507, 2.7252396993750345])
('evaluate:', [17.61774546537507, 2.7252396993750345])
('evaluate:', [17.70293390305071, 2.7252396993750345])
('evaluate:', [17.42737560814011, 0.3317893475658673])

As far as I understand these bounds are only used for creating the initial population.据我了解,这些界限仅用于创建初始人口。 How can I preserve the bounds and the type of the parameter?如何保留参数的边界和类型?

I found the reason.我找到了原因。

I run the code in spyder and in the ipython enviroment holds values of earlier runs, even if they are not used in the current run.我在 spyder 中运行代码,在 ipython 环境中保存早期运行的值,即使它们在当前运行中没有使用。

I had to click on "remove all variables" in the ipython console to get rid of this effect.我必须在 ipython 控制台中单击“删除所有变量”才能摆脱这种影响。

I now added我现在添加了

from IPython import get_ipython
get_ipython().magic('reset -sf')

in the first two lines of my code, which hopefully helps在我的代码的前两行,希望能有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM