Exemplo n.º 1
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])
Exemplo n.º 2
0
 def test_summary_logger_can_accept_kwargs(self, tmpdir, simple_chromosomes, simple_evaluation_function):
     log_file = tmpdir.join('log.txt')
     logger = SummaryLogger(target=log_file, stdout=False)
     pop = Population(chromosomes=simple_chromosomes,
                      eval_function=simple_evaluation_function)
     pop.evaluate()
     # lets make a first simple log
     logger.log(pop, foo="bar", buzz="meh")
     with open(log_file, "r") as f:
         read_lines = f.readlines()
         assert len(read_lines) == 1
         first_line = read_lines[0]
         assert "bar" in first_line
         assert "meh" in first_line
         last_entry = first_line.split(",")
         assert len(last_entry) == 6
     # lets log another one
     logger.log(pop, buzz="moh")
     with open(log_file, "r") as f:
         read_lines = f.readlines()
         assert len(read_lines) == 2
         first_line = read_lines[-1]
         assert "moh" in first_line
         last_entry = first_line.split(",")
         assert len(last_entry) == 5
Exemplo n.º 3
0
    def test_evaluate_func(self, simple_chromosomes):
        def evaluation_function(x):
            return x * x

        pop = Population(simple_chromosomes, eval_function=evaluation_function)
        pop.evaluate()
        for individual in pop:
            assert evaluation_function(
                individual.chromosome) == individual.fitness
Exemplo n.º 4
0
 def test_current_worst(self, simple_chromosomes):
     for maximize, worst in ((False, max(simple_chromosomes)),
                             (True, min(simple_chromosomes))):
         pop = Population(chromosomes=simple_chromosomes,
                          eval_function=float,
                          maximize=maximize)
         assert pop.current_worst is None
         pop.evaluate()
         assert pop.current_worst.chromosome == worst
Exemplo n.º 5
0
    def test_mutate_func(self):
        def mutate_func(x):
            return -x

        population = Population([1] * 100, eval_function=lambda x: x)
        population.mutate(mutate_func)
        for chromosome in population.chromosomes:
            assert chromosome == -1
        assert len(population) == 100
Exemplo n.º 6
0
 def test_is_stratified(self, shuffled_chromosomes, n_groups):
     population = Population(shuffled_chromosomes,
                             eval_function=lambda x: x).evaluate()
     islands = population.group(group_stratified, n_groups=n_groups)
     # All islands should have the same total fitness
     assert len(
         set(
             sum(map(lambda i: i.fitness, island.individuals))
             for island in islands)) == 1
Exemplo n.º 7
0
 def test_summarylogger_can_write_to_stdout(self, capsys, simple_chromosomes, simple_evaluation_function):
     logger = SummaryLogger(target=None, stdout=True)
     pop = Population(chromosomes=range(10),
                      eval_function=lambda x: x)
     pop.evaluate()
     logger.log(pop)
     logger.log(pop)
     read_stdout = [line for line in capsys.readouterr().out.split('\n') if line != '']
     assert len(read_stdout) == 2
Exemplo n.º 8
0
    def test_unserializable_chromosome(self, tmpdir):
        directory = tmpdir.mkdir("ckpt")

        class UnSerializableChromosome:
            def __init__(self, x):
                self.x = x

        pop = Population([UnSerializableChromosome(i) for i in range(10)], lambda x: x.x)
        with raises(self.exception):
            pop.checkpoint(target=directory, method=self.method)
Exemplo n.º 9
0
 def test_baselogger_can_write_to_stdout(self, capsys, simple_chromosomes,
                                         simple_evaluation_function):
     pop = Population(chromosomes=simple_chromosomes,
                      eval_function=lambda x: x,
                      logger=BaseLogger(target=None, stdout=True))
     pop.log()
     read_stdout = [
         line for line in capsys.readouterr().out.split('\n') if line != ''
     ]
     assert len(read_stdout) == len(pop)
Exemplo n.º 10
0
 def test_is_nearly_stratified(self, shuffled_chromosomes, n_groups):
     population = Population(shuffled_chromosomes,
                             eval_function=lambda x: x).evaluate()
     islands = population.group(group_stratified, n_groups=n_groups)
     # All islands should have roughly the same total fitness
     sum_fitnesses = [
         sum(map(lambda i: i.fitness, island.individuals))
         for island in islands
     ]
     assert max(sum_fitnesses) - min(sum_fitnesses) < n_groups * len(
         islands[0])
Exemplo n.º 11
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
Exemplo n.º 12
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)
     pop2 = 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, 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])
Exemplo n.º 13
0
    def test_evaluate_func(self, simple_chromosomes):
        def evaluation_function(x):
            sleep(self.latency)
            return x * x

        pop = Population(simple_chromosomes, eval_function=evaluation_function)
        t0 = time()
        pop.evaluate()
        t1 = time()
        single_proc_time = t1 - t0
        for individual in pop:
            assert evaluation_function(
                individual.chromosome) == individual.fitness
        # with concurrency
        pop = Population(simple_chromosomes,
                         eval_function=evaluation_function,
                         concurrent_workers=self.cpus)
        t0 = time()
        pop.evaluate()
        t1 = time()
        multi_proc_time = t1 - t0
        for individual in pop:
            assert evaluation_function(
                individual.chromosome) == individual.fitness
        if self.cpus > 1:
            assert multi_proc_time < single_proc_time
Exemplo n.º 14
0
 def test_weights(self, simple_chromosomes, simple_evaluation_function):
     for maximize in (False, True):
         pop = Population(chromosomes=simple_chromosomes,
                          eval_function=simple_evaluation_function,
                          maximize=maximize)
         with raises(RuntimeError):
             assert min(pop._individual_weights) >= 0
         pop.evaluate()
         assert max(pop._individual_weights) == 1
         assert min(pop._individual_weights) == 0
         if maximize:
             assert pop._individual_weights[0] == 0
         else:
             assert pop._individual_weights[0] == 1
Exemplo n.º 15
0
 def test_survive_n_and_p_works(self, simple_evaluation_function):
     chromosomes = list(range(200))
     pop1 = Population(chromosomes=chromosomes,
                       eval_function=simple_evaluation_function)
     pop2 = Population(chromosomes=chromosomes,
                       eval_function=simple_evaluation_function)
     pop3 = Population(chromosomes=chromosomes,
                       eval_function=simple_evaluation_function)
     assert len(pop1.survive(fraction=0.5, n=200)) == 100
     assert len(pop2.survive(fraction=0.9, n=10)) == 10
     assert len(pop3.survive(fraction=0.5, n=190, luck=True)) == 100
Exemplo n.º 16
0
 def test_baselogger_can_accept_kwargs(self, tmpdir, simple_chromosomes, simple_evaluation_function):
     log_file = tmpdir.join('log.txt')
     logger = BaseLogger(target=log_file, stdout=False)
     pop = Population(chromosomes=simple_chromosomes, eval_function=simple_evaluation_function)
     pop.evaluate()
     # we should see that a file was created with an appropriate number of rows
     logger.log(pop, foo="bar")
     with open(log_file, "r") as f:
         assert len(f.readlines()) == len(simple_chromosomes)
         assert all(["bar" in line for line in f.readlines()])
     # we should see that a file was created with an appropriate number of rows
     logger.log(pop, foo="meh")
     with open(log_file, "r") as f:
         assert len(f.readlines()) == (2 * len(simple_chromosomes))
         assert all(['meh' in line for line in f.readlines()[-10:]])
Exemplo n.º 17
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
Exemplo n.º 18
0
 def test_baselogger_write_file_no_stdout(self, tmpdir, capsys, simple_chromosomes, simple_evaluation_function):
     log_file = tmpdir.join('log.txt')
     logger = BaseLogger(target=log_file, stdout=False)
     pop = Population(chromosomes=simple_chromosomes, eval_function=simple_evaluation_function)
     # we should see that a file was created with an appropriate number of rows
     pop.evaluate()
     logger.log(pop)
     with open(log_file, "r") as f:
         assert len(f.readlines()) == len(simple_chromosomes)
     # we should see that a file was created with an appropriate number of rows
     logger.log(pop)
     with open(log_file, "r") as f:
         assert len(f.readlines()) == (2 * len(simple_chromosomes))
     read_stdout = [line for line in capsys.readouterr().out.split('\n') if line != '']
     # there should be nothing printed
     assert len(read_stdout) == 0
Exemplo n.º 19
0
 def test_mutate_elitist(self):
     pop = Population([1, 1, 3],
                      eval_function=lambda x: x).evaluate().mutate(
                          lambda x: x + 1, elitist=True)
     for chromosome in pop.chromosomes:
         assert chromosome > 1
     assert len(pop) == 3
Exemplo n.º 20
0
 def test_summarylogger_write_file_mo_stdout(self, tmpdir, capsys):
     log_file = tmpdir.join('log.txt')
     logger = SummaryLogger(target=log_file, stdout=False)
     pop = Population(chromosomes=range(10), eval_function=lambda x: x)
     # we should see that a file was created with an appropriate number of rows
     pop.evaluate()
     logger.log(pop)
     with open(log_file, "r") as f:
         assert len(f.readlines()) == 1
     # we should see that a file was created with an appropriate number of rows
     logger.log(pop)
     with open(log_file, "r") as f:
         assert len(f.readlines()) == 2
     read_stdout = [line for line in capsys.readouterr().out.split('\n') if line != '']
     # there should be nothing printed
     assert len(read_stdout) == 0
Exemplo n.º 21
0
    def test_mutate_func_kwargs(self):
        def mutate_func(x, y=0):
            return x + y

        pop = Population([1] * 100,
                         eval_function=lambda x: x).mutate(mutate_func, y=16)
        for chromosome in pop.chromosomes:
            assert chromosome == 17
Exemplo n.º 22
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
Exemplo n.º 23
0
    def test_population_generate(self, simple_evaluation_function):
        def init_func():
            return 1

        pop = Population.generate(init_function=init_func,
                                  eval_function=simple_evaluation_function,
                                  size=200)
        assert len(pop) == 200
        assert pop.intended_size == 200
        assert pop.individuals[0].chromosome == 1
Exemplo n.º 24
0
 def test_mutate_probability(self):
     seed(0)
     pop = Population([1] * 100, eval_function=lambda x: x).mutate(
         lambda x: x + 1, probability=0.5).evaluate()
     assert min(individual.chromosome
                for individual in pop.individuals) == 1
     assert max(individual.chromosome
                for individual in pop.individuals) == 2
     assert pop.current_best.fitness == 2
     assert pop.documented_best.fitness == 2
     assert len(pop) == 100
Exemplo n.º 25
0
def run_travelling_salesman(population_size: int = 100,
                            n_iterations: int = 10,
                            random_seed: int = 0,
                            n_destinations: int = 50,
                            concurrent_workers: Optional[int] = None,
                            n_groups: int = 4,
                            silent: bool = False):
    seed(random_seed)
    # Generate some destinations
    destinations = [(random(), random()) for _ in range(n_destinations)]

    # Given a list of destination indexes, this is our cost function
    def evaluate(ordered_destinations: List[int]) -> float:
        total = 0
        for x, y in zip(ordered_destinations, ordered_destinations[1:]):
            coordinates_x = destinations[x]
            coordinates_y = destinations[y]
            total += sqrt((coordinates_x[0] - coordinates_y[1])**2 +
                          (coordinates_x[1] - coordinates_y[1])**2)
        return total

    # This generates a random solution
    def generate_solution() -> List[int]:
        indexes = list(range(n_destinations))
        shuffle(indexes)
        return indexes

    def print_function(population: Population):
        if population.generation % 5000 == 0 and not silent:
            print(
                f'{population.generation}: {population.documented_best.fitness:1.2f} / '
                f'{population.current_best.fitness:1.2f}')

    pop = Population.generate(generate_solution,
                              eval_function=evaluate,
                              maximize=False,
                              size=population_size * n_groups,
                              concurrent_workers=concurrent_workers)

    island_evo = (Evolution().survive(fraction=0.5).breed(
        parent_picker=pick_random,
        combiner=cycle_crossover).mutate(swap_elements, elitist=True))

    evo = (Evolution().evaluate(lazy=True).callback(print_function).repeat(
        evolution=island_evo,
        n=100,
        grouping_function=group_stratified,
        n_groups=n_groups))

    result = pop.evolve(evolution=evo, n=n_iterations)

    if not silent:
        print(f'Shortest route: {result.documented_best.chromosome}')
        print(f'Route length: {result.documented_best.fitness}')
Exemplo n.º 26
0
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}"
    )
Exemplo n.º 27
0
 def test_survive_n_works(self, simple_chromosomes,
                          simple_evaluation_function):
     pop1 = Population(chromosomes=simple_chromosomes,
                       eval_function=simple_evaluation_function)
     pop2 = Population(chromosomes=simple_chromosomes,
                       eval_function=simple_evaluation_function)
     pop3 = Population(chromosomes=simple_chromosomes,
                       eval_function=simple_evaluation_function)
     assert len(pop1) == len(simple_chromosomes)
     assert len(pop2.survive(n=50)) == 50
     assert len(pop3.survive(n=75, luck=True)) == 75
Exemplo n.º 28
0
 def test_survive_p_works(self, simple_chromosomes,
                          simple_evaluation_function):
     pop1 = Population(chromosomes=simple_chromosomes,
                       eval_function=simple_evaluation_function)
     pop2 = Population(chromosomes=simple_chromosomes,
                       eval_function=simple_evaluation_function)
     pop3 = Population(chromosomes=simple_chromosomes,
                       eval_function=simple_evaluation_function)
     assert len(pop1) == len(simple_chromosomes)
     assert len(pop2.survive(fraction=0.5)) == len(simple_chromosomes) * 0.5
     assert len(pop3.survive(fraction=0.1,
                             luck=True)) == len(simple_chromosomes) * 0.1
Exemplo n.º 29
0
 def test_breed_amount_works(self, simple_chromosomes,
                             simple_evaluation_function):
     pop1 = Population(chromosomes=simple_chromosomes,
                       eval_function=simple_evaluation_function)
     pop1.survive(n=50).breed(
         parent_picker=lambda population: choices(population, k=2),
         combiner=lambda mom, dad: (mom + dad) / 2)
     assert len(pop1) == len(simple_chromosomes)
     pop2 = Population(chromosomes=simple_chromosomes,
                       eval_function=simple_evaluation_function)
     pop2.survive(n=50).breed(
         parent_picker=lambda population: choices(population, k=2),
         combiner=lambda mom, dad: (mom + dad) / 2,
         population_size=400)
     assert len(pop2) == 400
     assert pop2.intended_size == 400
Exemplo n.º 30
0
 def test_documented_best(self):
     pop = Population(chromosomes=[100, 100, 100],
                      eval_function=lambda x: x * 2,
                      maximize=True)
     assert pop.documented_best is None
     pop.evaluate()
     assert pop.documented_best.fitness == pop.current_best.fitness
     pop.mutate(mutate_function=lambda x: x - 10, probability=1).evaluate()
     assert pop.documented_best.fitness - 20 == pop.current_best.fitness