def create_population(self, population_size: int, individual_size: int, gene_factory: GeneFactory, mutation_rate=0.01): """ Creates a new population for the engine. The new population is then sorted according to the individual's fitness Args: mutation_rate: population_size: The number of individuals of the population. individual_size: The number of genes of each member. gene_factory: The factory to create the genes of each individual """ self.__population = Individual.create(population_size, individual_size, gene_factory, mutation_rate, *self.__factory_generator_args) for member in self.__population: member.compute_fitness_using(self.__fitness_function, *self.__fitness_function_args) self.__population.sort() self.__fittest = self.__population[-1]
def test_creation_with_characters(str_gene_factory: GeneFactory[str]): individuals = Individual.create(number_of_individuals=100, number_of_genes=10, gene_factory=str_gene_factory) assert len(individuals) == 100 for individual in individuals: assert len(individual.genes) == 10 for gene in individual.genes: assert gene in string.ascii_lowercase
def test_mutation(): gene_factory = GeneFactory[str]() gene_factory.generator = lambda: Random(8000).choice(string.ascii_lowercase) individual = Individual() individual.random_generator = Random(8000) individual.genes = "abcd" individual.gene_factory = gene_factory individual.mutation_rate = 0.5 mutated_i = individual.mutate() assert mutated_i.genes == list("sbsd")
def test_word_guess(str_gene_factory: GeneFactory[str]): individuals = Individual.create(number_of_individuals=100000, number_of_genes=3, gene_factory=str_gene_factory) def fitness_function(word: List[str]) -> float: return sum([1 if word[i] == "cat"[i] else 0 for i in range(0, 3)]) fittest_individual = individuals[0] for individual in individuals: individual.compute_fitness_using(fitness_function) if individual.fitness > fittest_individual.fitness: fittest_individual = individual assert fittest_individual.fitness == 3
def couple() -> Tuple[Individual, Individual]: c = (Individual(), Individual()) c[0].genes = "abcd" c[1].genes = "defg" return c
def mutate(self, individual: Individual, *args) -> Individual: """Mutates an individual and returns the result of the mutation.""" individual.random_generator = self.random_generator return individual.mutate(*args)
def crossover(self, partner_a: Individual, partner_b: Individual, *args) -> Individual: """Performs a crossover between two individuals and returns the offspring.""" partner_a.random_generator = self._random_generator return partner_a.crossover(partner_b, *args)