Exemplo n.º 1
0
def crossover_intermediate(population, alpha=None):
    """
    Generated children feature averages of the equivalent parent gene elements.
    """
    assert isinstance(population, Population)
    assert isinstance(population.individuals[0].gene[0], (bool, int, float))
    assert len(population) == 2, "this works with two parents, only."
    # TODO: How about a universal formula (for p > 2)?

    gene = []
    for gene_index in range(population.gene_size):
        features_parents = [parent.gene[gene_index]
                            for parent in population.individuals]

        if alpha is None:
            # calculate average feature
            feature = statistics.mean(features_parents)

            # cast back to original type
            feature = type(population.individuals[0].gene[0])(feature)
        else:
            # reweight according to alpha
            feature = sum([alpha * features_parents[0],
                           (1 - alpha) * features_parents[1]])

        print(feature)
        gene.append(feature)

    return Population.from_individuals(individuals=[Individual(gene=gene)])
Exemplo n.º 2
0
def crossover_n_point(population, n=1):
    assert isinstance(population, Population)

    # select crossover point
    valid_positions = range(1, population.gene_size-1)
    points = [random.choice(valid_positions) for _ in range(n)]

    # generate children from parents
    children = []

    # iterate over children
    for i in range(len(population)):
        gene_child = []

        # iterate over crossover points
        for i in range(-1, n):
            if i == -1:
                # part left of the first crossover point
                gene_child += population[0].gene[0:points[0]]
                continue

            key = i % population.gene_size - 1
            parent = population[key]

            try:
                gene_child += parent.gene[points[i]:points[i+1]]
            except IndexError:
                # this is the last point
                gene_child += parent.gene[points[i]:]

        child_individual = Individual(gene=gene_child)
        children.append(child_individual)

    return Population.from_individuals(children)
Exemplo n.º 3
0
def ea(SIGMA=SIGMA):
    # initialize
    world = World(fitness=fitness)
    world.population = IntListPopulation(length=MU, gene_size=GENE_SIZE)

    # iterate over generations
    for generation_count in range(MAX_GENERATIONS):

        # log this generation's population to stdout
        print("%s: %s" % (generation_count, world.population))

        # if we reached a sufficiently good solution, stop
        if min(world.scores) < MIN_FITNESS:
            break

        # select rho fittest individuals as parents
        parents = select(world=world, rho=RHO)

        # generate children by crossing over the parents
        children_original = []
        while len(children_original) < LAMBDA:
            children_original += crossover(population=parents)

        # mutate children
        children = [mutate(individual=individual, mu=0, sigma=SIGMA)
                    for individual in children_original]

        # self-adapt mutation strenght using Rechenberg's success rule
        SIGMA = rechenberg(children_original=children_original,
                           children_mutated=children, fitness=world.fitness,
                           a=A_RECHENBERG, sigma=SIGMA)

        if MODE == '+':
            # extend population with children
            world.population += Population.from_individuals(
                individuals=children)
        elif MODE == ',':
            # replace population with children
            world.population = Population.from_individuals(
                individuals=children)

        # select fittest mu individuals for next generation
        world.population = select(rho=MU, world=world)

    # log best individual
    print("Best individual is %s with a score of %s." %
          (select(world=world, rho=1)[0], min(world.scores)))
Exemplo n.º 4
0
def crossover_mode_bool(population):
    gene = []

    for i in range(len(population[0].gene)):
        base = sum([1 for parent in population if parent.gene[i-1]]) > \
            len(population) / 2
        gene.append(base)

    individual = Individual(gene=gene)

    return Population.from_individuals(individuals=[individual])
Exemplo n.º 5
0
def crossover_dominant(population):
    """
    Collects child gene from equivalent gene elements of a random parent.
    """
    assert isinstance(population, Population)

    gene = []
    for gene_index in range(population.gene_size):
        parent_index = random.choice(range(len(population)))
        gene.append(population[parent_index].gene[gene_index])

    return Population.from_individuals(individuals=[Individual(gene=gene)])