def __init__(self, genome, owner, seed=None, interactiveMode=True): """ Initializator of GSimpleGA """ if seed: random.seed(seed) if type(interactiveMode) != BooleanType: Util.raiseException( "Interactive Mode option must be True or False", TypeError) if not isinstance(genome, GenomeBase): Util.raiseException("The genome must be a GenomeBase subclass", TypeError) self.internalPop = GPopulation(genome) self.nGenerations = Consts.CDefGAGenerations self.pMutation = Consts.CDefGAMutationRate self.pCrossover = Consts.CDefGACrossoverRate self.nElitismReplacement = Consts.CDefGAElitismReplacement self.setPopulationSize(Consts.CDefGAPopulationSize) self.minimax = Consts.minimaxType["maximize"] self.elitism = True self.owner = owner ## added 12/15 by Peter Graf, so GA can evaluate constraints ## and, now (4/16), so we can save let the owner save the state # Adapters self.dbAdapter = None self.migrationAdapter = None self.time_init = None self.interactiveMode = interactiveMode self.interactiveGen = -1 self.GPMode = False self.selector = FunctionSlot("Selector") self.stepCallback = FunctionSlot("Generation Step Callback") self.terminationCriteria = FunctionSlot("Termination Criteria") self.selector.set(Consts.CDefGASelector) self.allSlots = [ self.selector, self.stepCallback, self.terminationCriteria ] self.internalParams = {} self.currentGeneration = 0 # GP Testing for classes in Consts.CDefGPGenomes: if isinstance(self.internalPop.oneSelfGenome, classes): self.setGPMode(True) break logging.debug("A GA Engine was created, nGenerations=%d", self.nGenerations)
def step(self): """ Just do one step in evolution, one generation """ genomeMom = None genomeDad = None newPop = GPopulation(self.internalPop) if (MPI.COMM_WORLD.Get_rank() == 0 ): ### assumes WE are on top of hierarchy! popsize = len(self.internalPop) numAdded = 0 maxTries = 1000 numTries = 0 crossover_empty = self.select( popID=self.currentGeneration).crossover.isEmpty() ###TODO: enforce constraints!### while numAdded < popsize: genomeMom = self.select(popID=self.currentGeneration) genomeDad = self.select(popID=self.currentGeneration) if not crossover_empty and self.pCrossover >= 1.0: for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=2): (sister, brother) = it else: if not crossover_empty and Util.randomFlipCoin( self.pCrossover): for it in genomeMom.crossover.applyFunctions( mom=genomeMom, dad=genomeDad, count=2): (sister, brother) = it else: sister = genomeMom.clone() brother = genomeDad.clone() # logging.debug("done cloning") sister.mutate(pmut=self.pMutation, ga_engine=self) brother.mutate(pmut=self.pMutation, ga_engine=self) if (numTries > maxTries or self.owner.eval_constraints(sister)): newPop.internalPop.append(sister) numAdded += 1 print "successfully added sister" if (numAdded < popsize and (numTries > maxTries or self.owner.eval_constraints(brother))): newPop.internalPop.append(brother) print "successfully added brother" numAdded += 1 numTries += 1 #end rank0 onlye # print "rank %d start eval pop" % MPI.COMM_WORLD.Get_rank() logging.debug("Evaluating the newly created population.") newPop.evaluate() # print "rank %d done eval pop" % MPI.COMM_WORLD.Get_rank() # if (MPI.COMM_WORLD.Get_rank() == 0): # print "after eval, new pop's positions are:" # for p in newPop: # print p.wt_positions if (MPI.COMM_WORLD.Get_rank() == 0 ): ### assumes WE are on top of hierarchy! if self.elitism: logging.debug("Doing elitism, %d" % self.nElitismReplacement) if self.getMinimax() == Consts.minimaxType["maximize"]: for i in xrange(self.nElitismReplacement): #re-evaluate before being sure this is the best # self.internalPop.bestRaw(i).evaluate() if self.internalPop.bestRaw(i).score > newPop.bestRaw( i).score: newPop[len(newPop) - 1 - i] = self.internalPop.bestRaw(i) elif self.getMinimax() == Consts.minimaxType["minimize"]: for i in xrange(self.nElitismReplacement): #re-evaluate before being sure this is the best # self.internalPop.bestRaw(i).evaluate() if self.internalPop.bestRaw(i).score < newPop.bestRaw( i).score: newPop[len(newPop) - 1 - i] = self.internalPop.bestRaw(i) self.internalPop = newPop if (MPI.COMM_WORLD.Get_rank() == 0 ): ### assumes WE are on top of hierarchy! self.internalPop.sort() # if (MPI.COMM_WORLD.Get_rank() == 0): # print "after sort, internal pop's positions are:" # for p in self.internalPop: # print p.wt_positions logging.debug("The generation %d was finished.", self.currentGeneration) self.currentGeneration += 1 if (MPI.COMM_WORLD.Get_rank() == 0 ): ### assumes WE are on top of hierarchy! self.saveState() return (self.currentGeneration == self.nGenerations)
def step(self): """ Just do one step in evolution, one generation """ genomeMom = None genomeDad = None newPop = GPopulation(self.internalPop) logging.debug("Population was cloned.") size_iterate = len(self.internalPop) # Odd population size if size_iterate % 2 != 0: size_iterate -= 1 crossover_empty = self.select(popID=self.currentGeneration).crossover.isEmpty() from utils import delog ############# delog.decache("mutate and check...") ################# for i in xrange(0, size_iterate, 2): genomeMom = self.select(popID=self.currentGeneration) genomeDad = self.select(popID=self.currentGeneration) if not crossover_empty and self.pCrossover >= 1.0: for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=2): (sister, brother) = it else: if not crossover_empty and Util.randomFlipCoin(self.pCrossover): for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=2): (sister, brother) = it else: sister = genomeMom.clone() brother = genomeDad.clone() sister.mutate(pmut=self.pMutation, ga_engine=self) brother.mutate(pmut=self.pMutation, ga_engine=self) newPop.internalPop.append(sister) newPop.internalPop.append(brother) delog.deprint_string("over.") if len(self.internalPop) % 2 != 0: genomeMom = self.select(popID=self.currentGeneration) genomeDad = self.select(popID=self.currentGeneration) if Util.randomFlipCoin(self.pCrossover): for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=1): (sister, brother) = it else: sister = random.choice([genomeMom, genomeDad]) sister = sister.clone() sister.mutate(pmut=self.pMutation, ga_engine=self) newPop.internalPop.append(sister) logging.debug("Evaluating the new created population.") newPop.evaluate() newPop.sort() #Niching methods- Petrowski's clearing self.clear() if self.elitism: logging.debug("Doing elitism.") if self.getMinimax() == Consts.minimaxType["maximize"]: # in ecoc, max value is expected. for i in xrange(self.nElitismReplacement): if self.internalPop.bestRaw(i).score > newPop.bestRaw(i).score: # check duplicate to avoid repeat indivadual duplicate = False for j in xrange(len(newPop)-self.nElitismReplacement, len(newPop)): if self.internalPop.bestRaw(i).score == newPop.bestRaw(j).score: duplicate = True break if duplicate: continue newPop[len(newPop)-1-i] = newPop[i] newPop[i] = self.internalPop.bestRaw(i) elif self.getMinimax() == Consts.minimaxType["minimize"]: for i in xrange(self.nElitismReplacement): if self.internalPop.bestRaw(i).score < newPop.bestRaw(i).score: newPop[len(newPop)-1-i] = self.internalPop.bestRaw(i) self.internalPop = newPop self.internalPop.sort() logging.debug("The generation %d was finished.", self.currentGeneration) self.currentGeneration += 1 return (self.currentGeneration == self.nGenerations)
def step(self): """ Just do one step in evolution, one generation """ genomeMom = None genomeDad = None newPop = GPopulation(self.internalPop) logging.debug("Population was cloned.") size_iterate = len(self.internalPop) # Odd population size if size_iterate % 2 != 0: size_iterate -= 1 crossover_empty = self.select( popID=self.currentGeneration).crossover.isEmpty() for i in xrange(0, size_iterate, 2): genomeMom = self.select(popID=self.currentGeneration) genomeDad = self.select(popID=self.currentGeneration) if not crossover_empty and self.pCrossover >= 1.0: for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=2): (sister, brother) = it else: if not crossover_empty and Util.randomFlipCoin( self.pCrossover): for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=2): (sister, brother) = it else: sister = genomeMom.clone() brother = genomeDad.clone() sister.mutate(pmut=self.pMutation, ga_engine=self) brother.mutate(pmut=self.pMutation, ga_engine=self) newPop.internalPop.append(sister) newPop.internalPop.append(brother) if len(self.internalPop) % 2 != 0: genomeMom = self.select(popID=self.currentGeneration) genomeDad = self.select(popID=self.currentGeneration) if Util.randomFlipCoin(self.pCrossover): for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=1): (sister, brother) = it else: sister = random.choice([genomeMom, genomeDad]) sister = sister.clone() sister.mutate(pmut=self.pMutation, ga_engine=self) newPop.internalPop.append(sister) logging.debug("Evaluating the new created population.") newPop.evaluate() if self.elitism: logging.debug("Doing elitism.") if self.getMinimax() == Consts.minimaxType["maximize"]: for i in xrange(self.nElitismReplacement): #re-evaluate before being sure this is the best self.internalPop.bestRaw(i).evaluate() if self.internalPop.bestRaw(i).score > newPop.bestRaw( i).score: newPop[len(newPop) - 1 - i] = self.internalPop.bestRaw(i) elif self.getMinimax() == Consts.minimaxType["minimize"]: for i in xrange(self.nElitismReplacement): #re-evaluate before being sure this is the best self.internalPop.bestRaw(i).evaluate() if self.internalPop.bestRaw(i).score < newPop.bestRaw( i).score: newPop[len(newPop) - 1 - i] = self.internalPop.bestRaw(i) self.internalPop = newPop self.internalPop.sort() logging.debug("The generation %d was finished.", self.currentGeneration) self.currentGeneration += 1 return (self.currentGeneration == self.nGenerations)
def step(self): """ Just do one step in evolution, one generation """ genomeMom = None genomeDad = None newPop = GPopulation(self.internalPop) logging.debug("Population was cloned.") size_iterate = len(self.internalPop) # Odd population size if size_iterate % 2 != 0: size_iterate -= 1 #Check on the crossover function by picking a random individual - is it empty? crossover_empty = self.select( popID=self.currentGeneration).crossover.isEmpty() for i in xrange(0, size_iterate, 2): #Ok, we select 2 parents using the selector (RouletteWheel, etc.) genomeMom = self.select(popID=self.currentGeneration) genomeDad = self.select(popID=self.currentGeneration) if not crossover_empty and self.pCrossover >= 1.0: #Crossover all of them for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=2): (sister, brother) = it else: #Filp a coin each time to determine if you should crossover if not crossover_empty and Util.randomFlipCoin( self.pCrossover): for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=2): (sister, brother) = it else: sister = genomeMom.clone() brother = genomeDad.clone() #And "pre" mutate them sister.premutate(pmut=self.pPreMutation, ga_engine=self) brother.premutate(pmut=self.pPreMutation, ga_engine=self) #Now each offspring is mutated sister.mutate(pmut=self.pMutation, ga_engine=self) brother.mutate(pmut=self.pMutation, ga_engine=self) newPop.internalPop.append(sister) newPop.internalPop.append(brother) if len(self.internalPop) % 2 != 0: #Odd-numbered population genomeMom = self.select(popID=self.currentGeneration) genomeDad = self.select(popID=self.currentGeneration) if Util.randomFlipCoin(self.pCrossover): for it in genomeMom.crossover.applyFunctions(mom=genomeMom, dad=genomeDad, count=1): (sister, brother) = it else: sister = random.choice([genomeMom, genomeDad]) sister = sister.clone() #Do the 2 mutations sister.premutate(pmut=self.pPreMutation, ga_engine=self) sister.mutate(pmut=self.pMutation, ga_engine=self) newPop.internalPop.append(sister) #---- Evaluate fitness ------ logging.debug("Evaluating the new created population.") newPop.evaluate() #Niching methods- Petrowski's clearing self.clear() if self.elitism: #Avoid too much elitism if self.nElitismReplacement >= len(self.internalPop): self.nElitismReplacement = len(self.internalPop) - 1 logging.debug("Doing elitism.") if self.getMinimax() == Consts.minimaxType["maximize"]: #Replace the n-th worst new ones with the nth best old ones for i in xrange(self.nElitismReplacement): if self.internalPop.bestRaw(i).score > newPop.bestRaw( i).score: newPop[len(newPop) - 1 - i] = self.internalPop.bestRaw(i) elif self.getMinimax() == Consts.minimaxType["minimize"]: for i in xrange(self.nElitismReplacement): if self.internalPop.bestRaw(i).score < newPop.bestRaw( i).score: newPop[len(newPop) - 1 - i] = self.internalPop.bestRaw(i) self.internalPop = newPop self.internalPop.sort() logging.debug("The generation %d was finished.", self.currentGeneration) self.currentGeneration += 1 return (self.currentGeneration >= self.nGenerations)