python - 使用 DEAP 的遗传算法中违反了界限
问题描述
我是使用 DEAP 的新手。我的任务是优化一个技术系统,该系统需要特定范围内的 int 和 float 值作为参数。
作为第一步,我根据 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
在运行此脚本期间,我发现 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')
在我的代码的前两行,希望能有所帮助
推荐阅读
- python - 如何正确传递路径变量?
- parallel-processing - Pytorch:如何在集群中的多台机器上运行代码
- ios - 如何隐藏快速可可豆饼饼图中的标签
- c# - 带有错误跟踪的 EF Core 批量插入
- python - “TypeError:列表索引必须是整数或切片,而不是浮点数”(在查找蒸发量时)
- javascript - React js在具有属性的数组中添加或删除状态对象
- javascript - 将多个图像从图库上传到休息方法导致某些图像未上传
- drake-r-package - Very long run times for drake, compared to when I run simply through R
- azure - 无法在 Azure 上为 App Insights 自定义指标创建警报
- postman - 查找 Postman 测试用例的创建日期