2013-12-15 1 views
2

메트릭을 최대화하기 위해 DEAP 라이브러리를 사용하고 있으며 알고리즘을 다시 시작할 때마다 (1과 0의 이진 값 목록을 생성해야 함) 같은 초기 값을 생성하는 것으로 나타났습니다.DEAP를 사용하여 다른 임의의 결과를 생성하는 방법은 무엇입니까?

나는 의심되었고, 자신의 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) 시간과 그것은 서로의 정확한 사본을 생산했다. - 순서에서이 출력 내가 함수를 호출 할 때마다 생성됩니다

>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 개의 랜덤 int의리스트를 출력하는 기본 스크립트를 작성하여 테스트했다. 내가 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 클래스는 파이썬에서 임의의 세대가 테스트하는 것입니다. 파이썬에서 시드가 동적으로 호출되면 here을 읽어서 이것을 테스트하고 싶습니다. 나는 위의 코드를 실행 한 방법

같은있다 :

> 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 번 행에 있는지 정확히 격렬한 테스트하지만, 사실 아니다 붉은 깃발을 들었다.

+0

소스에서'random.seed'에 대한 참조가없는 것 같습니다. – Blender

+0

'random.seed()'를 명시 적으로 호출하면 어떻게됩니까? 값이 전혀 변하지 않습니까? –

+3

나는 DEAP 개발자 중 한 명입니다. 당신이 관찰하고있는 것은 정상적이지 않지만, 당신이 제공 한 코드를 사용하여 그것을 재현 할 수는 없습니다. 당신이 사용했던 정확한 코드를 넣을 수 있습니까? – CmdNtrf

답변

6

문제는 사용자가 기본 함수에서 난수 생성기의 시드를 지정하는 것입니다. 단순히 회선을 random.seed(64)으로 주석 처리하면 프로그램을 실행할 때마다 결과가 달라집니다.

DEAP 예제 파일에서는 이러한 예제를 통합 테스트로 사용하기 때문에 특정 시드가 설정됩니다. 프레임 워크 기본 코드를 수정 한 후 예제의 출력이 다른 경우, 우리는 알고 싶습니다. 또한 각 예제에서 요구되는 시간을 벤치마킹하고 사용자에게 야구장을 제공 할 수 있습니다. 이 벤치 마크 결과는 http://deap.gel.ulaval.ca/speed/에서 온라인으로 볼 수 있습니다.

+0

이것은 그랬다. 나는 이것을 더 일찍 보지 못해 미안하다. 고맙습니다. – cshortt