def step(self): offspring = [] while len(offspring) < self.offspring_size: # Selection parents = self.selection(self.population, self.selection_size) # Recombination if take_chances(self.p_recombination): progeny = self.recombination(*parents) else: progeny = [i.clone() for i in parents] # Mutation individuals_who_fit = min( len(progeny), self.offspring_size - len(offspring) ) progeny = [ self.mutation(individual, self.p_mutation) for individual in random.sample(progeny, individuals_who_fit) ] # Add progeny to the offspring offspring.extend(progeny) # Once offspring is generated, a replace step is performed self.replacement(self.population, offspring) # We store the best individual for further information if self.generation < len(self.best_individuals): self.best_individuals[self.generation] = self.population.best() else: self.best_individuals.append(self.population.best())
def __call__(self, individual, p): """ Changes the value of a random gene of the individual. The mutated chromosome is obtained by changing a random gene as seen in the next example: individual : aabbaaba alleles : (a, b, c, d) change pos : 7 ----------- mutated : aabdaabc :param individual: The individual to be mutated. :param p: The probability of mutation. """ indexes = random.sample( range(len(individual)), min(self.n or len(individual), len(individual)), ) clone = individual.clone() for i in indexes: if take_chances(probability=p): new_gene = self.alleles.get() while individual[i] == new_gene: new_gene = self.alleles.get() clone[i] = new_gene return clone
def __call__(self, individual, p): """ Changes the value of a random gene of the individual. The mutated chromosome is obtained by changing a random gene as seen in the next example: individual : aabbaaba alleles : (a, b, c, d) change pos : 7 ----------- mutated : aabdaabc :param individual: The individual to be mutated. :param p: The probability of mutation. """ clone = individual.clone() if take_chances(probability=p): # Set in a random position a different gene than before i = random.choice(range(len(individual))) new_gene = self.alleles.get() while individual[i] == new_gene: new_gene = self.alleles.get() # Set this gene in the cloned individual clone[i] = new_gene return clone else: return clone
def __call__(self, individual, p): """ Swaps the values of two positions of the list of values. When the individual is mutated, two random positions (pivots) are generated. Then, the values of those positions are swapped. For example: individual : 12345678 pivot : 3, 5 ----------- mutated : 12365478 :param individual: The individual to be mutated. :param p: The probability of mutation. :return: A new individual mutated with a probabiity of p or looking exactly to the one passed as parameter with a probability of 1-p. """ clone = individual.clone() if take_chances(probability=p): # Get two random diferent indexes indexes = range(len(individual)) i1, i2 = tuple(random.sample(indexes, 2)) # Swap the genes in the cloned individual clone[i1], clone[i2] = clone[i2], clone[i1] return clone else: return clone
def __call__(self, individual, p): """ Returns the same instance of the individual mutated. :param individual: The individual to mutate. :param p: The probability for a gene to mutate. :return: The same instance maybe mutated). """ for i, gene_value in enumerate(individual): if take_chances(probability=p): individual[i] = 1 - gene_value return individual
def random_derivation(self): """ Returns a tuple with the managed term according to limits and p. The minimum size of the returned tuple will be the lower limit specified in the init param "lower". After that, and with a maximum of "upper" terms, a new param will be added as long as random tests fall under the probability specified. """ terms = [self.value for _ in range(self.lower)] while len(terms) < self.upper and take_chances(self.p): terms.append(self.value) return tuple(terms)
def __call__(self, parent1, parent2): """ Offspring is obtained generating a random mask. This mask determines which genes of each of the progenitors are used on each of the the genes. For example: parents : aaaaaaaa, bbbbbbbb random mask : 00100110 ----------- children : aabaabba, bbabbaab :param parent1: One of the individuals from which generate the progeny. :param parent2: The other. :return: A list of two individuals, each a child containing some characteristics from their parents. """ child1, child2 = super().__call__(parent1, parent2) for i in range(len(parent1)): if take_chances(.5): child1[i], child2[i] = parent2[i], parent1[i] return child1, child2