Beispiel #1
0
def run(target, cores, s=None):
    """ Genetic Hill Climbing Algorithm run here.
    Stores the image results in RESULTS
    directory, after every SAVE_PER_GEN
    generations .
    """

    RESULTS = "results"
    # Make RESULTS directory, if not exists.
    if not os.path.exists(RESULTS):
        os.mkdir(RESULTS)

    # Logs file, in RESULTS directory.
    f = open(os.path.join(RESULTS, "logs.txt"), "a")

    generation = 1
    INIT_GENES = 50
    parent = Chromosome(target.size, INIT_GENES)

    # Load Save file from function parameter.
    if s is not None:
        generation = parent.load(jsonpickle.decode(s))

    # First generation fitness.
    score = utils.fitness(parent.draw(), target)

    # Create thread pool for each core.
    p = multiprocessing.Pool(cores)

    # Frequency of saves and number of children
    # per generation of Genetic Hill Climbing Algorithm.
    SAVE_PER_GEN = 500
    CHILDS_PER_GEN = 50

    while True:

        f.write("Generation {0} Score {1}\n".format(
            generation, round(score, 5)))

        # Draw the image and save it.
        # Also save the logs.
        if generation % SAVE_PER_GEN == 0:
            print("Generation {0}\tScore {1}".format(
                generation, round(score, 5)))
            
            parent.draw().save(os.path.join(
                RESULTS, "{0}.png".format(generation)))

            save_file = open(os.path.join(
                RESULTS, "{0}.txt".format(generation)), "w")
            save_file.write(jsonpickle.encode(parent.save(generation)))
            save_file.close()

        generation += 1

        # Mutate the current parent.
        try:
            results = utils.group_mutate(parent, CHILDS_PER_GEN - 1, p, target)
        except KeyboardInterrupt:
            print("Exiting program... Bye!")
            p.close()
            return

        # Children for the next generation.
        # Includes the current parent in case
        # bad mutation.
        new_score, new_children = map(list, zip(*results))
        new_score.append(score)
        new_children.append(parent)

        # Choose the fittest child for next generation.
        fittest = min(zip(new_children, new_score), key=lambda x: x[1])
        parent, score = fittest