使用 DEAP 的遗传算法违反边界

bounds violated in genetic algorithm using DEAP

我是 DEAP 的新手。 我的任务是优化一个技术系统,它需要在特定范围内的参数作为int和float值。

作为第一步,我基于 DEAP documentation.

编写了一个小脚本
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

在 运行 这个脚本中,我发现 attr_float 和 attr_int 的值违反了 MIN_1、MIN_2、MAX_1 和 MAX_2 几代人。 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])

据我了解,这些界限仅用于创建初始种群。 如何保留参数的边界和类型?

找到原因了

我 运行 spyder 和 ipython 环境中的代码保留了早期 运行 的值,即使它们未在当前 运行 中使用。

我必须在 ipython 控制台中单击“删除所有变量”才能消除这种影响。

我现在添加了

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

在我的代码的前两行中,希望对您有所帮助