Пример #1
0
def genealogy_plot(history: tools.support.History,
                   toolbox: base.Toolbox) -> np.ndarray:
    '''
    plotting function for genealogical history of the GA run.
    :param history: dict, dict with history
    :param toolbox: gp.toolbox, for using the appropriate eval
    :return: ndarray, 3-Channel RGB array from plot
    '''
    graph = networkx.DiGraph(history.genealogy_tree)
    graph = graph.reverse()  # Make the graph top-down

    fig, ax = plt.subplots(figsize=(8, 6), dpi=120)
    try:
        colors = [
            toolbox.evaluate(history.genealogy_history[i])[0] for i in graph
        ]
    except:  # catch all for failures
        colors = [i for i in range(history.genealogy_index)]

    positions = graphviz_layout(graph, prog="dot")
    networkx.draw(graph,
                  positions,
                  node_color=colors,
                  with_labels=True,
                  font_size1=10,
                  alpha=0.75,
                  ax=ax)

    plt.title('Evolution: Genealogy Tree', fontsize='xx-large')
    fig.canvas.draw()
    image = np.frombuffer(fig.canvas.tostring_rgb(), dtype='uint8')
    image = image.reshape(fig.canvas.get_width_height()[::-1] + (3, ))
    plt.close(fig)
    return image
Пример #2
0
def execute(toolbox: base.Toolbox, cases: int = 100) -> List[str]:
    population = toolbox.population(n=POPULATION_SIZE)
    hall_of_fame = tools.ParetoFront()

    stats = tools.Statistics(lambda i: i.fitness.values)
    stats.register("avg", numpy.mean, axis=0)
    stats.register("std", numpy.std, axis=0)
    stats.register("min", numpy.min, axis=0)
    stats.register("max", numpy.max, axis=0)

    logbook = tools.Logbook()
    logbook.header = "gen", "evals", "std", "min", "avg", "max", "best"

    # Evaluate every individuals
    for individual in population:
        individual.fitness.values = toolbox.evaluate(individual)

    hall_of_fame.update(population)
    record = stats.compile(population)
    logbook.record(gen=0, evals=len(population), **record)
    print(logbook.stream)

    generated_cases = list
    last_fitness = float('inf')
    current_fitness = None
    generation_count = 1
    while generation_count <= MAX_GENERATIONS and (
            last_fitness != current_fitness
            or current_fitness == float('inf')):
        last_fitness = current_fitness

        # Select the next generation individuals
        offspring = toolbox.select(population, floor(POPULATION_SIZE * 0.9))

        # Clone the selected individuals
        offspring = list(toolbox.map(toolbox.clone, offspring))

        # Add new individuals from the population
        offspring += toolbox.population(n=POPULATION_SIZE - len(offspring))

        # Apply crossover and mutation on the offspring
        for child1, child2 in zip(offspring[::2], offspring[1::2]):
            if not random() < MATE_RATIO:
                continue
            toolbox.mate(child1, child2)
            del child1.fitness.values
            del child2.fitness.values

        for mutant in offspring:
            if not random() < MUTATION_RATIO:
                continue
            toolbox.mutate(mutant)
            del mutant.fitness.values

        # Evaluate the individuals with an invalid fitness
        invalid_ind = [
            individual for individual in offspring
            if not individual.fitness.valid
        ]
        for individual in offspring:
            individual.fitness.values = toolbox.evaluate(individual)

        generated_cases = tools.selBest(population, k=cases)
        current_fitness = sum(
            toolbox.map(op.itemgetter(0),
                        toolbox.map(toolbox.evaluate, generated_cases)))
        best = choice(generated_cases)
        word = "".join(best)

        # Select the next generation population
        population = toolbox.select(population + offspring, POPULATION_SIZE)
        record = stats.compile(population)
        logbook.record(gen=generation_count,
                       evals=len(invalid_ind),
                       best=word,
                       **record)
        print(logbook.stream)

        generation_count += 1

    return [''.join(case) for case in generated_cases]