Source code for edo.population

""" Functions for the creation and updating of a population. """

from .individual import create_individual
from .operators import crossover, mutation


[docs]def create_initial_population( row_limits, col_limits, families, weights, random_states ): """Create an initial population for the genetic algorithm based on the given parameters. Parameters ---------- size : int The number of individuals in the population. row_limits : list Limits on the number of rows a dataset can have. col_limits : list Limits on the number of columns a dataset can have. families : list A list of ``edo.Family`` instances that handle the column distribution classes. weights : list Relative weights with which to sample from ``families``. If ``None``, sampling is done uniformly. random_states : dict A mapping of the index of the population to a ``numpy.random.RandomState`` instance that is to be assigned to the individual at that index in the population. Returns ------- population : list A population of newly created individuals. """ population = [ create_individual(row_limits, col_limits, families, weights, state) for _, state in random_states.items() ] return population
[docs]def create_new_population( parents, population, crossover_prob, mutation_prob, row_limits, col_limits, families, weights, random_states, ): """Given a set of potential parents to be carried into the next generation, create offspring from pairs within that set until there are enough individuals. Parameters ---------- parents : list A list of `edo.individual.Individual` instances used to create new offspring. population : list The current population. crossover_prob : float The probability with which to sample dimensions from the first parent over the second during crossover. mutation_prob : float The probability with which to mutate a component of a newly created individual. row_limits : list Limits on the number of rows a dataset can have. col_limits : list Limits on the number of columns a dataset can have. families : list The ``edo.Family`` instances from which to draw distribution instances. weights : list Weights used to sample elements from ``families``. random_states : dict The PRNGs assigned to each individual in the population. """ parent_idxs = [population.index(parent) for parent in parents] available_states = [ state for i, state in random_states.items() if i not in parent_idxs ] new_population = parents for state in available_states: parent1_idx, parent2_idx = state.choice(len(parents), size=2) parents_ = parents[parent1_idx], parents[parent2_idx] offspring = crossover( *parents_, col_limits, families, state, crossover_prob ) mutant = mutation( offspring, mutation_prob, row_limits, col_limits, families, weights ) for col, meta in zip(*mutant): mutant.dataframe[col] = mutant.dataframe[col].astype(meta.dtype) new_population.append(mutant) return new_population