Package Bio :: Package GA :: Package Selection :: Module Diversity
[hide private]
[frames] | no frames]

Source Code for Module Bio.GA.Selection.Diversity

  1  # This code is part of the Biopython distribution and governed by its 
  2  # license.  Please see the LICENSE file that should have been included 
  3  # as part of this package. 
  4  # 
  5   
  6  """Select individuals into a new population trying to maintain diversity. 
  7   
  8  This selection mechanism seeks to try and get both high fitness levels 
  9  and high diversity levels in the population. 
 10  """ 
 11  # standard modules 
 12  import random 
 13  import math 
 14   
 15  # biopython 
 16  from Bio.Seq import MutableSeq 
 17   
 18  # local modules 
 19  from .Abstract import AbstractSelection 
 20  from .Tournament import TournamentSelection 
 21   
 22   
23 -class DiversitySelection(AbstractSelection):
24 """Implement diversity selection. 25 26 Diversity selection is performed by trying to select individuals 27 from the population that aren't already in the new_population. A group 28 of selected individuals is then subjected to selection using 29 a passed selection routine. 30 31 If new individuals can not be selected, new individuals will be 32 randomly generated and inserted into the population. 33 """
34 - def __init__(self, internal_selector, genome_generator):
35 """Initialize a diversity selector. 36 37 Arguments: 38 39 o internal_selector - A selection object that will be used to select 40 individuals based on fitness, perform crossover, mutation and repair. 41 42 o genome_generator - A function that, when called, will return a 43 genome to be used for a new organism. The genome returned must 44 be a MutableSeq() object. 45 """ 46 self._internal_selector = internal_selector 47 self._genome_generator = genome_generator 48 49 self.sub_pop_percent = .1 50 self.random_tries = 10
51
52 - def _get_new_organism(self, new_pop, old_pop):
53 """Get a new organism from old_pop that isn't in new_pop. 54 55 This attempts to select an organism from old_pop that isn't in 56 new_pop. If we can't do this in the number of tries specified 57 by the class attribute random_tries, we generate a new random 58 organism and return that. 59 """ 60 # try to pick an organism that isn't in the population 61 new_org = None 62 num_tries = 0 63 while new_org is None and num_tries < self.random_tries: 64 chance_org = random.choice(old_pop) 65 66 if chance_org not in new_pop: 67 new_org = chance_org 68 69 num_tries += 1 70 71 # if we don't get an organism, generate a random one 72 if new_org is None: 73 new_org = old_pop[0].copy() 74 random_genome = self._genome_generator() 75 new_org.genome = random_genome 76 new_org.recalculate_fitness() 77 78 return new_org
79
80 - def select(self, population):
81 """Perform selection on the current population, encouraging diversity. 82 """ 83 new_population = [] 84 85 while len(new_population) < len(population): 86 # generate a sub population 87 sub_pop_size = int(math.ceil(len(population) * 88 self.sub_pop_percent)) 89 sub_pop = [] 90 for individual in range(sub_pop_size): 91 new_org = self._get_new_organism(new_population, population) 92 sub_pop.append(new_org) 93 94 # put the new sub population through selection, mutation 95 # and all of that good stuff 96 new_sub_pop = self._internal_selector.select(sub_pop) 97 98 new_population.extend(new_sub_pop) 99 100 # return the new population, which should have the same number 101 # of individuals we started with. 102 return new_population[:len(population)]
103