如何用DEAP产生不同的随机结果?

时间:2013-12-15 01:43:16

标签: python algorithm random genetic-algorithm

我正在使用DEAP库来最大化度量,我注意到每当我重新启动算法(它应该创建一个二进制值的随机列表--1和0)时,它就会生成相同的初始值。

我开始怀疑并复制了他们的basic DEAP example here并重新运行算法:

import array, random
from deap import creator, base, tools, algorithms

creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", array.array, typecode='b', fitness=creator.FitnessMax)

toolbox = base.Toolbox()

toolbox.register("attr_bool", random.randint, 0, 1)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, 10)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

def evalOneMax(individual):
    return sum(individual),

toolbox.register("evaluate", evalOneMax)
toolbox.register("mate", tools.cxTwoPoints)
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
toolbox.register("select", tools.selTournament, tournsize=3)

population = toolbox.population(n=10)

NGEN=40
for gen in range(NGEN):
    offspring = algorithms.varAnd(population, toolbox, cxpb=0.5, mutpb=0.1)
    fits = toolbox.map(toolbox.evaluate, offspring)
    for fit, ind in zip(fits, offspring):
        ind.fitness.values = fit
    population = offspring

上面的代码就是他们的例子,但是人口和个人规模减少到10个。我运行算法5次,它产生了彼此的精确副本。我还添加了一个print语句来获得以下输出:

>python testGA.py
[1, 0, 1, 0, 1, 0, 1, 1, 1, 1]
Starting the Evolution Algorithm...
Evaluating Individual: [0, 1, 0, 1, 0, 1, 1, 1, 1, 0]
Evaluating Individual: [1, 1, 0, 1, 0, 1, 0, 1, 0, 0]
Evaluating Individual: [0, 0, 1, 0, 0, 1, 1, 0, 0, 1]
Evaluating Individual: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Evaluating Individual: [0, 1, 1, 0, 1, 0, 1, 1, 0, 1]
Evaluating Individual: [1, 0, 1, 1, 1, 0, 0, 1, 0, 0]
Evaluating Individual: [0, 1, 0, 0, 0, 1, 0, 0, 0, 1]
Evaluating Individual: [1, 1, 0, 1, 0, 1, 0, 1, 1, 1]
Evaluating Individual: [1, 1, 1, 1, 0, 0, 1, 0, 0, 0]
Evaluating Individual: [0, 0, 1, 1, 1, 1, 0, 1, 1, 1]

每次调用函数时都会生成此输出 - 按此顺序。它们完全相同。

我已经读过我不应该为random.randint函数播种,并且我通过编写一个基本脚本来测试它,该脚本只打印出10个随机整数的列表,范围为0到1.这个工作没问题,它只是当我通过DEAP提供它时似乎产生相同的值。

这是正常的吗?我怎样才能确保,当我运行算法时,每次都会得到不同的“个人”?

修改

很抱歉迟到的回复,这是我正在使用的完整资料来源:

import random, sys
from deap import creator, base, tools

class Max():

    def __init__(self):
        creator.create("FitnessMax", base.Fitness, weights=(1.0,))
        creator.create("Individual", list, fitness=creator.FitnessMax)

        INDIVIDUAL_SIZE = 10

        self.toolbox = base.Toolbox()
        self.toolbox.register("attr_bool", random.randint, 0, 1)
        self.toolbox.register("individual", tools.initRepeat, creator.Individual, self.toolbox.attr_bool, n=INDIVIDUAL_SIZE)
        self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual)

        self.toolbox.register("mate", tools.cxTwoPoints)
        self.toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
        self.toolbox.register("select", tools.selTournament, tournsize=3)
        self.toolbox.register("evaluate", self.evaluate)

        print self.main()


    def evaluate(self, individual):
        # Some debug code
        print 'Evaluating Individual: ' + str(individual)
        return sum(individual),

    def main(self):

        CXPB, MUTPB, NGEN = 0.5, 0.2, 40
        random.seed(64)
        pop = self.toolbox.population(n=10)

        print "Starting the Evolution Algorithm..."

        fitnesses = list(map(self.toolbox.evaluate, pop))
        for ind, fit in zip(pop, fitnesses):
            ind.fitness.values = fit

        # ----------------------------------------------------------
        # Killing the program here - just want to see the population created
        sys.exit()

        print "Evaluated %i individuals" % (len(pop))

        for g in range(NGEN):
            print "-- Generation %i --" % (g)

            # Select the next genereation individuals
            offspring = self.toolbox.select(pop, len(pop))

            # Clone the selected individuals
            offspring = list(map(self.toolbox.clone, offspring))

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

            for mutant in offspring:
                if random.random() < MUTPB:
                    self.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 = map(self.toolbox.evaluate, invalid_ind)
            for ind, fit in zip(invalid_ind, fitnesses):
                ind.fitness.values = fit

            print "\tEvaluated %i individuals" % (len(pop))

            pop[:] = offspring

            fits = [ind.fitness.values[0] for ind in pop]

            length = len(pop)
            mean = sum(fits) / length
            sum2 = sum(x*x for x in fits)
            std = abs(sum2 / length - mean**2)**0.5

            print "\tMin %s" % (min(fits))
            print "\tMax %s" % (max(fits))
            print "\tAvg %s" % (mean)
            print "\tStd %s" % (std)

class R_Test:
    def __init__(self):

        print str([random.randint(0, 1) for i in range(10)])


if __name__ == '__main__':
    #rt = R_Test()
    mx = Max()

R_Test类用于测试Python中的随机生成。我读here如果没有在Python中给出,动态调用种子,我想测试它。

我如何执行上述代码一直是这样的:

> python testGA.py
... the 10 outputs
> python testGA.py
... the exact same outputs
> python testGA.py
... the exact same outputs
> python testGA.py
... the exact same outputs
> python testGA.py
... the exact same outputs

显然,5次并不是一项艰苦的考验,但所有10个值连续5次相同的事实引发了一个红旗。

1 个答案:

答案 0 :(得分:6)

问题是您在main函数中为随机数生成器指定了种子。只需注释一行:random.seed(64),每次执行程序时都会得到不同的结果。

在DEAP示例文件中,设置了特定种子,因为我们还将这些示例用作集成测试。如果在框架基本代码中进行修改后,示例的输出是不同的,我们想知道。它还允许我们根据每个示例所需的时间进行调整,并为我们的用户提供大概估算。这些基准测试的结果可在http://deap.gel.ulaval.ca/speed/在线获取。