Exemple #1
0
 def test_two_populations_can_use_same_logger(self, tmpdir, capsys):
     log_file = tmpdir.join('log.txt')
     logger = SummaryLogger(target=log_file, stdout=True)
     pop1 = Population(chromosomes=list(range(10)),
                       eval_function=lambda x: x,
                       logger=logger)
     pop2 = Population(chromosomes=list(range(10)),
                       eval_function=lambda x: x,
                       logger=logger)
     evo = (Evolution().survive(fraction=0.5).breed(
         parent_picker=pick_random,
         combiner=lambda mom, dad: (mom + dad) + 1,
         n_parents=2).log(foo="dino"))
     _ = pop1.evolve(evolution=evo, n=5)
     _ = pop2.evolve(evolution=evo, n=5)
     # two evolutions have now been applied, lets check the output!
     with open(log_file, "r") as f:
         read_file = [item.replace("\n", "") for item in f.readlines()]
         # print(read_file)
         # size of the log should be appropriate
         assert len(read_file) == 10
         # dino needs to be in every single line
         assert all(['dino' in row for row in read_file])
     # check characteristics of stoud
     read_stdout = [
         line for line in capsys.readouterr().out.split('\n') if line != ''
     ]
     assert len(read_stdout) == 10
     assert all(['dino' in row for row in read_stdout])
Exemple #2
0
 def test_baselogger_works_via_evolution(self, tmpdir, capsys):
     log_file = tmpdir.join('log.txt')
     logger = BaseLogger(target=log_file, stdout=True)
     pop = Population(chromosomes=range(10),
                      eval_function=lambda x: x,
                      logger=logger)
     evo = (Evolution().survive(fraction=0.5).breed(
         parent_picker=pick_random,
         combiner=lambda mom, dad: (mom + dad) / 2 +
         (random.random() - 0.5),
         n_parents=2).log(foo='bar'))
     pop.evolve(evolution=evo, n=2)
     # check characteristics of the file
     with open(log_file, "r") as f:
         read_file = [item.replace("\n", "") for item in f.readlines()]
         # size of the log should be appropriate
         assert len(read_file) == 2 * len(pop)
         # bar needs to be in every single line
         assert all(['bar' in row for row in read_file])
     # check characteristics of stoud
     read_stdout = [
         line for line in capsys.readouterr().out.split('\n') if line != ''
     ]
     assert len(read_stdout) == 2 * len(pop)
     assert all(['bar' in row for row in read_stdout])
Exemple #3
0
    def test_simple_counter_works_every(self, simple_chromosomes,
                                        simple_evaluation_function):
        counter = PopCounter()

        pop = Population(chromosomes=simple_chromosomes,
                         eval_function=simple_evaluation_function)
        evo = (Evolution().mutate(lambda x: x).callback(
            lambda p: counter.add(p), every=2))

        pop.evolve(evolution=evo, n=10)
        assert counter.count == len(simple_chromosomes) * 5
        assert counter.sum == sum(simple_chromosomes) * 5
Exemple #4
0
 def test_every_mechanic_in_evolution_log(self, tmpdir, capsys):
     log_file = tmpdir.join('log.txt')
     logger = SummaryLogger(target=log_file, stdout=True)
     pop = Population(chromosomes=list(range(10)), eval_function=lambda x: x)
     evo = (Evolution()
            .survive(fraction=0.5)
            .breed(parent_picker=pick_random,
                   combiner=lambda mom, dad: (mom + dad) + 1,
                   n_parents=2)
            .evaluate()
            .callback(logger.log, every=2))
     pop.evolve(evolution=evo, n=100)
     with open(log_file, "r") as f:
         read_file = [item.replace("\n", "") for item in f.readlines()]
         assert len(read_file) == 50
     # check characteristics of stoud
     read_stdout = [line for line in capsys.readouterr().out.split('\n') if line != '']
     assert len(read_stdout) == 50
Exemple #5
0
    def test_repeat_step_grouped(self, n_groups, grouping_function):
        calls = []

        def callback(pop):
            calls.append(len(pop))

        sub_evo = (Evolution().survive(fraction=0.5).breed(
            parent_picker=pick_random,
            combiner=lambda x, y: x + y).callback(callback_function=callback))

        pop = Population([0 for _ in range(100)], lambda x: x)
        evo = (Evolution().evaluate(lazy=True).repeat(
            sub_evo, grouping_function=grouping_function, n_groups=n_groups))
        assert len(pop.evolve(evo, n=2)) == 100
        assert len(calls) == 2 * n_groups
def run_evolutionary(opt_value=1,
                     population_size=100,
                     n_parents=2,
                     num_iter=200,
                     survival=0.5,
                     noise=0.1,
                     seed=42):

    random.seed(seed)

    def init_func():
        return (random.random() - 0.5) * 20 + 10

    def eval_func(x, opt_value=opt_value):
        return -((x - opt_value)**2) + math.cos(x - opt_value)

    def random_parent_picker(pop, n_parents):
        return [random.choice(pop) for i in range(n_parents)]

    def mean_parents(*parents):
        return sum(parents) / len(parents)

    def add_noise(chromosome, sigma):
        return chromosome + (random.random() - 0.5) * sigma

    pop = Population(chromosomes=[init_func() for _ in range(population_size)],
                     eval_function=eval_func,
                     maximize=True).evaluate()

    evo = (Evolution().survive(fraction=survival).breed(
        parent_picker=random_parent_picker,
        combiner=mean_parents,
        n_parents=n_parents).mutate(mutate_function=add_noise,
                                    sigma=noise).evaluate())

    print("will start the evolutionary program, will log progress every step")
    for i in range(num_iter):
        pop = pop.evolve(evo).log()
    print(
        f"iteration:{i} best: {pop.current_best.fitness} worst: {pop.current_worst.fitness}"
    )
Exemple #7
0
        print(f"the best score i={self.i} => {best}")


if __name__ == "__main__":
    logger = MyLogger()
    random.seed(42)

    pop = Population(chromosomes=[random_start() for _ in range(200)],
                     eval_function=func_to_optimise,
                     maximize=True, concurrent_workers=2)

    evo1 = (Evolution()
            .survive(fraction=0.1)
            .breed(parent_picker=pick_random_parents, combiner=make_child)
            .mutate(mutate_function=add_noise, sigma=0.2)
            .evaluate()
            .callback(logger.log))

    evo2 = (Evolution()
            .survive(n=10)
            .breed(parent_picker=pick_random_parents, combiner=make_child)
            .mutate(mutate_function=add_noise, sigma=0.1)
            .evaluate()
            .callback(logger.log))

    evo3 = (Evolution()
            .repeat(evo1, n=20)
            .repeat(evo2, n=20))

    pop = pop.evolve(evo3, n=3)
Exemple #8
0
def run_evolutionary(num_towns=42, population_size=100, num_iter=200, seed=42):
    """
    Runs a simple evolutionary algorithm against a simple TSP problem.
    The goal is to explain the `evol` library, this is not an algorithm
    that should perform well.
    """

    # First we generate random towns as candidates with a seed
    random.seed(seed)
    coordinates = [(random.random(), random.random())
                   for i in range(num_towns)]

    # Next we define a few functions that we will need in order to create an algorithm.
    # Think of these functions as if they are lego blocks.
    def init_func(num_towns):
        """
        This function generates an individual  
        """
        order = list(range(num_towns))
        random.shuffle(order)
        return order

    def dist(t1, t2):
        """
        Calculates the distance between two towns. 
        """
        return math.sqrt((t1[0] - t2[0])**2 + (t1[1] - t2[1])**2)

    def eval_func(order):
        """
        Evaluates a candidate chromosome, which is a list that represents town orders.
        """
        return sum([
            dist(coordinates[order[i]], coordinates[order[i - 1]])
            for i, t in enumerate(order)
        ])

    def pick_random(parents):
        """
        This function selects two parents  
        """
        return random.choice(parents), random.choice(parents)

    def partition(lst, n_crossover):
        division = len(lst) / n_crossover
        return [
            lst[round(division * i):round(division * (i + 1))]
            for i in range(n_crossover)
        ]

    def crossover_ox(mom_order, dad_order, n_crossover):
        idx_split = partition(range(len(mom_order)), n_crossover=n_crossover)
        dad_idx = sum([list(d) for i, d in enumerate(idx_split) if i % 2 == 0],
                      [])
        path = [-1 for _ in range(len(mom_order))]
        for idx in dad_idx:
            path[idx] = dad_order[idx]
        cities_visited = {p for p in path if p != -1}
        for i, d in enumerate(path):
            if d == -1:
                city = [p for p in mom_order if p not in cities_visited][0]
                path[i] = city
                cities_visited.add(city)
        return path

    def random_flip(chromosome):
        result = chromosome[:]
        idx1, idx2 = random.choices(list(range(len(chromosome))), k=2)
        result[idx1], result[idx2] = result[idx2], result[idx1]
        return result

    pop = Population(
        chromosomes=[init_func(num_towns) for _ in range(population_size)],
        eval_function=eval_func,
        maximize=False).evaluate()

    evo = (Evolution().survive(fraction=0.1).breed(
        parent_picker=pick_random, combiner=crossover_ox,
        n_crossover=2).mutate(random_flip).evaluate())

    print("will start the evolutionary program")
    scores = []
    iterations = []
    for i in range(num_iter):
        print(
            f"iteration: {i} best score: {min([individual.fitness for individual in pop])}"
        )
        for indiviual in pop:
            scores.append(indiviual.fitness)
            iterations.append(i)
        pop = pop.evolve(evo)

    try:
        import matplotlib.pylab as plt
        plt.scatter(iterations, scores, s=1, alpha=0.3)
        plt.title("population fitness vs. iteration")
        plt.show()
    except ImportError:
        print("If you install matplotlib you will get a pretty plot.")
    return new


# We start by defining a population with candidates.
pop = Population(chromosomes=[random_start() for _ in range(5)],
                 eval_function=func_to_optimise,
                 maximize=False)

# We define a sequence of steps to change these candidates
evo1 = (
    Evolution().survive(fraction=0.2).breed(parent_picker=pick_random_parents,
                                            combiner=make_child)
    # .mutate(mutate_function=add_noise, sigma=1))
    .mutate(mutate_function=add_noise, sigma=1))

# We define another sequence of steps to change these candidates
evo2 = (
    Evolution().survive(n=1).breed(parent_picker=pick_random_parents,
                                   combiner=make_child)
    # .mutate(mutate_function=add_noise, sigma=0.2))
    .mutate(mutate_function=add_noise, sigma=0.1))

# We are combining two evolutions into a third one. You don't have to
# but this approach demonstrates the flexibility of the library.
evo3 = (Evolution().repeat(evo1, n=10).evaluate())

# In this step we are telling evol to apply the evolutions
# to the population of candidates.
pop = pop.evolve(evo3, n=10000)
print(f"the best score found: {max([i.fitness for i in pop])}")
Exemple #10
0
 def test_evolve(self, simple_evolution):
     # The initial population contains the optimal solution.
     pop = Population(list(range(100)), eval_function=lambda x: x**2, maximize=False)
     with MinimumProgress(window=10):
         pop = pop.evolve(simple_evolution, n=100)
     assert pop.generation == 10
Exemple #11
0
        combiner=mate,
        population_size=population_size).mutate(
            mutate_function=mutate_painting, rate=0.005,
            sigma=0.4).evaluate(lazy=False).callback(
                print_summary,
                img_template=image_template,
                checkpoint_path=checkpoint_path))

    shrink_step = (Evolution().survive(n=1).breed(
        parent_picker=pick_best,
        combiner=clone,
        population_size=population_size).mutate(
            mutate_function=shrink_painting).evaluate(lazy=False).callback(
                print_summary,
                img_template=image_template,
                checkpoint_path=checkpoint_path))

    # 250 points
    pop = pop.evolve(evo_step_1, n=999)
    pop = pop.evolve(genome_duplication, n=1)
    # 500 points
    pop = pop.evolve(evo_step_1, n=899)
    pop = pop.evolve(shrink_step, n=100)
    pop = pop.evolve(genome_duplication, n=1)
    # 800 points
    pop = pop.evolve(evo_step_2, n=900)
    pop = pop.evolve(shrink_step, n=100)
    pop = pop.evolve(evo_step_2, n=900)
    pop = pop.evolve(shrink_step, n=100)
    pop = pop.evolve(evo_step_3, n=1000)
Exemple #12
0
if __name__ == "__main__":

    checkpoint_path = "./geneticArt/"
    image_template = os.path.join(checkpoint_path, "drawing_%05d.png")
    targetImage = Image.open("./img/unicorn.png").convert('RGBA')
    #targetImage.show()

    #size = targetImage.size

    numPolygons = 150
    popSize: int = 200

    pop = Population(chromosomes=[
        DrawImage(numPolygons, targetImage, background_color=(255, 255, 255))
        for _ in range(popSize)
    ],
                     eval_function=score,
                     maximize=False,
                     concurrent_workers=6)

    evolution = (Evolution().survive(fraction=0.05).breed(
        parent_picker=selection, combiner=crossover,
        population_size=popSize).mutate(mutate_function=mutation,
                                        rate=0.05).evaluate(lazy=False).apply(
                                            final,
                                            img_template=image_template,
                                            checkpoint_path=checkpoint_path))

    pop = pop.evolve(evolution, n=2000)
Exemple #13
0
 def test_repeat_step(self):
     pop = Population([0 for i in range(100)], lambda x: x)
     evo = Evolution().repeat(Evolution().survive(fraction=0.9), n=10)
     # Check whether an Evolution inside another Evolution is actually applied
     assert len(pop.evolve(evo, n=2)) < 50