예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
   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)
예제 #4
0
    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)
예제 #5
0
    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)