def choose_mate(self, mates ): """ Choose a mate at "Random" based on a list of potential mates. The choice depends in the individuals desired_assortment (A). With probability A they choose a mate of the same phenotype as themselves, and with probability 1 - A they choose a random mate. Returns ======= A tuple, the first value being the integer index of the mate choosen and the second value being the mate itself. """ ##A list of phenotypic values, together with the index of the individual all_mates = list( enumerate(mates) ) if random.random() < self.desired_assortment: ##Then we choose a mate who is clonally related potential_mates = [ p for p in all_mates if p[1].phenotypic_value == self.phenotypic_value ] ##In the special case where there are no identical mates to choose from we'll just choose ##at random. if len(potential_mates) == 0: potential_mates = all_mates else: ##Choose a mate at random potential_mates = all_mates return random_choice( potential_mates )
def make_gamete(self, delta, mu_strat = 0.05, mu_assort = 0.1): """ Returns a gamete, i.e. a gene a and a gene m. Which genes are chossen depends firstly on whether crossover takes place, and also on whether the individual contains any meiotic distorter alleles. Needs also mu_strat and mu_assort. See Individual.mutate_gamete. """ ##Choose whether to crossover or not if random.random() < self.crossover: do_crossover = True ##We can already select the value of gamete a if we know ##Crossover will take place... gamete_a = random_choice( [self.a1, self.a2] ) else: do_crossover = False ##The probability of selecting m1 given gentic values of m1 and m2 p_select_m1 = 0.5*( 1 + ( 1 - self.m1 )*delta - (1 - self.m2 )*delta ) if random.random() < p_select_m1: gamete_m = self.m1 if not do_crossover: gamete_a = self.a1 else: gamete_m = self.m2 if not do_crossover: gamete_a = self.a2 gamete = gamete_a, gamete_m return self.mutate_gamete( gamete, mu_strat, mu_assort )
def new_generation(self, fitness_matrix, delta, mu_strat = 0.05, mu_assort = 0.1 ): """ Creates and returns a new population which is the outcome of one generation of selection. """ if self.pairs is None: self.pair_population() fitnesses = [ p.fitness( fitness_matrix ) for p in self.pairs ] parents = random_choice( self.pairs, p = fitnesses, size = self.total_individuals ) children = [ p.make_child(delta, mu_strat = mu_strat, mu_assort = mu_assort) for p in parents ] return Population( children )