Exemple #1
0
    def fitness(self, net, proc, id_for_printing=-1):
        total_weights = net.num_edges()
        total_delays = net.num_edges()
        total_thresholds = net.num_nodes()
        dec = [8] * total_weights + [4] * total_delays + [7] * total_thresholds
        leap_decoder = BinaryToIntDecoder(*dec)

        problem = NetworkProblem(net, proc, self)
        genome_len = 8 * total_weights + 4 * total_delays + 7 * total_thresholds
        parents = Individual.create_population(
            10,
            initialize=create_binary_sequence(genome_len),
            decoder=leap_decoder,
            problem=problem)
        parents = Individual.evaluate_population(parents)
        max_generation = 10
        #stdout_probe = probe.FitnessStatsCSVProbe(context, stream=sys.stdout)

        generation_counter = util.inc_generation(context=context)

        while generation_counter.generation() < max_generation:
            offspring = pipe(
                parents, ops.tournament_selection, ops.clone,
                mutate_bitflip, ops.uniform_crossover, ops.evaluate,
                ops.pool(size=len(parents)))  #,  # accumulate offspring
            #stdout_probe)

            parents = offspring
            generation_counter()  # increment to the next generation

        best = probe.best_of_gen(parents).decode()
        set_weights(best, net)
        return self.get_fitness_score(net, proc, id_for_printing)
Exemple #2
0
def test_segmented_copy():
    original = Individual([[0, 0], [1, 1]])
    mutated = next(copy_segment(iter([original]), probability=1.0,
                                append=True))

    possible_outcomes = [
        [[0, 0], [1, 1], [0, 0]],
        [[0, 0], [1, 1], [1, 1]],
    ]

    assert mutated.genome in possible_outcomes

    possible_outcomes = [
        [[0, 0], [0, 0], [1, 1]],
        [[0, 0], [1, 1], [0, 0]],
        [[1, 1], [0, 0], [1, 1]],
        [[0, 0], [1, 1], [1, 1]],
    ]

    # TODO: it would be better to build a histogram of expected outcomes and
    # do the chi square test
    for i in range(20):
        original = Individual([[0, 0], [1, 1]])
        mutated = next(
            copy_segment(iter([original]), probability=1.0, append=False))

        assert mutated.genome in possible_outcomes
Exemple #3
0
def collect_two_gene_mutation_counts(mutator, N: int):
    """Helper to collect the distribution of results when we
    apply mutation to two small individuals."""
    # Set up arrays to collect the values of 4 different loci after mutation
    ind0_gene0_values = []
    ind0_gene1_values = []
    ind1_gene0_values = []
    ind1_gene1_values = []

    for _ in range(N):
        # Set up two parents with fixed genomes, two genes each
        ind1 = Individual(np.array([0, 0]))
        ind2 = Individual(np.array([1, 1]))
        population = iter([ind1, ind2])

        # Mutate the parents
        result = mutator(population)
        result = list(result)  # Pulse the iterator

        # Collect the values of each of the genes after mutation
        ind0_gene0_values.append(result[0].genome[0])
        ind0_gene1_values.append(result[0].genome[1])
        ind1_gene0_values.append(result[1].genome[0])
        ind1_gene1_values.append(result[1].genome[1])

    # Count the number of times that each gene value occurs at each locus
    ind0_gene0_counts = Counter(ind0_gene0_values)
    ind0_gene1_counts = Counter(ind0_gene1_values)
    ind1_gene0_counts = Counter(ind1_gene0_values)
    ind1_gene1_counts = Counter(ind1_gene1_values)

    return [ [ ind0_gene0_counts, ind0_gene1_counts ],
             [ ind1_gene0_counts, ind1_gene1_counts ] ]
Exemple #4
0
def test_koza_maximization():
    """
        Tests the koza_parsimony() function for maximization problems
    """
    problem = SpheroidProblem(maximize=True)

    pop = []

    # We set up three individuals in ascending order of fitness of
    # [0, 1, 2]
    pop.append(Individual(np.array([0]), problem=problem))
    pop.append(Individual(np.array([1]), problem=problem))
    pop.append(Individual(np.array([0, 0, 1, 1]), problem=problem))

    pop = Individual.evaluate_population(pop)

    # Now truncate down to the "best" that should be the third one
    best = ops.truncation_selection(pop, size=1)
    assert np.all(best[0].genome == [0, 0, 1, 1])

    # This is just to look at the influence of the parsimony pressure on
    # the order of the individual.  You should observe that the order is now
    # ([0,0,1,1], [0], [1]) because now their biased fitnesses are respectively
    # (-2, -1, 0)
    pop.sort(key=koza_parsimony(penalty=1))

    # Ok, now we want to turn on parsimony pressure, which should knock the
    # really really really long genome out of the running for "best"
    best = ops.truncation_selection(pop, size=1, key=koza_parsimony(penalty=1))

    assert np.all(best[0].genome == [1])
Exemple #5
0
def test_n_ary_crossover_bad_crossover_points():
    """ Test assertions for having more crossover points than genome length """
    pop = [Individual(np.array([0, 0])), Individual(np.array([1, 1]))]

    i = ops.naive_cyclic_selection(pop)

    with pytest.raises(RuntimeError):
        new_pop = list(
            itertools.islice(ops.n_ary_crossover(i, num_points=3), 2))
Exemple #6
0
def test_mutate_randint1():
    """If you send me two individuals with two genes each and keep the 
    default mutation rate, then on average, each gene has a probability 
    of 0.5 of being mutated."""

    N = 1000  # We'll sample 1,000 independent genomes

    # Set up arrays to collect the values of 4 different loci after mutation
    ind0_gene0_values = []
    ind0_gene1_values = []
    ind1_gene0_values = []
    ind1_gene1_values = []

    for _ in range(N):
        # Set up two parents with fixed genomes, two genes each
        ind1 = Individual([0, 0])
        ind2 = Individual([1, 1])
        population = iter([ind1, ind2])

        # Mutate the parents
        result = ops.mutate_randint(population, bounds=[(0, 1), (0, 1)])
        result = list(result)  # Pulse the iterator

        # Collect the values of each of the genes after mutation
        ind0_gene0_values.append(result[0].genome[0])
        ind0_gene1_values.append(result[0].genome[1])
        ind1_gene0_values.append(result[1].genome[0])
        ind1_gene1_values.append(result[1].genome[1])

    # Count the number of times that each gene value occurs at each locus
    ind0_gene0_counts = Counter(ind0_gene0_values)
    ind0_gene1_counts = Counter(ind0_gene1_values)
    ind1_gene0_counts = Counter(ind1_gene0_values)
    ind1_gene1_counts = Counter(ind1_gene1_values)

    # Expected distribution of mutations.
    # We arrive at this by the following reasoning: each gene has a 1/L = 0.5
    # chance of not being mutated, in which case it keeps it original value.
    # Otherwise, it's value is sampled uniformly from the set {0, 1}.
    expected_ind0_gene0 = {0: 0.5 * N + 0.25 * N, 1: 0.25 * N}
    expected_ind0_gene1 = expected_ind0_gene0
    expected_ind1_gene0 = {0: 0.25 * N, 1: 0.5 * N + 0.25 * N}
    expected_ind1_gene1 = expected_ind1_gene0

    # Use a chi2 test to see if the observed gene-value counts are
    # differ significantly from the expected distributions.
    p = 0.001
    assert (stat.stochastic_equals(expected_ind0_gene0, ind0_gene0_counts,
                                   p=p))
    assert (stat.stochastic_equals(expected_ind0_gene1, ind0_gene1_counts,
                                   p=p))
    assert (stat.stochastic_equals(expected_ind1_gene0, ind1_gene0_counts,
                                   p=p))
    assert (stat.stochastic_equals(expected_ind1_gene1, ind1_gene1_counts,
                                   p=p))
Exemple #7
0
def test_mutate_binomial_err1():
    """If we fail to provide either expected_num_mutations or a probability parameter,
    an exception should occur when the operator is used."""

    mutator = intrep_ops.mutate_binomial(std=1, bounds=[(0, 1), (0, 1)])
    ind1 = Individual(np.array([0, 0]))
    ind2 = Individual(np.array([1, 1]))
    population = iter([ind1, ind2])
    result = mutator(population)

    with pytest.raises(ValueError):
        # Pulse the iterator so mutation gets executed
        result = list(result)
Exemple #8
0
def test_tournament_selection():
    """ This simple binary tournament_selection selection """
    # Make a population where binary tournament_selection has an obvious reproducible choice
    pop = [
        Individual([0, 0, 0], decoder=IdentityDecoder(), problem=MaxOnes()),
        Individual([1, 1, 1], decoder=IdentityDecoder(), problem=MaxOnes())
    ]

    # We first need to evaluate all the individuals so that truncation selection has fitnesses to compare
    pop = Individual.evaluate_population(pop)

    best = next(ops.tournament_selection(pop))
    pass
Exemple #9
0
def spheroid_sample():
    """A uniform sample of individuals on the spheroid function."""
    DIMENSIONS = 10
    N_SAMPLES = 50*DIMENSIONS
    problem = problems.SpheroidProblem()

    representation = Representation(
        initialize=initializers.create_real_vector(bounds=[(-5.12, 5.12)]*DIMENSIONS)
    )

    initial_sample = representation.create_population(N_SAMPLES, problem)
    Individual.evaluate_population(initial_sample)

    return problem, representation, initial_sample
Exemple #10
0
def test_n_ary_crossover_probability2():
    """If we perform uniform crossover with a probabilty of 1.0, then we should see genes swapped
    by default with probability 0.2."""
    N = 5000
    observed_dist = {
        'Unmodified': 0,
        'Only left swapped': 0,
        'Only right swapped': 0,
        'Both swapped': 0
    }

    # Run crossover N times on a fixed pair of two-gene individuals
    for i in range(N):

        pop = [Individual(np.array([0, 0])), Individual(np.array([1, 1]))]
        i = ops.naive_cyclic_selection(pop)
        new_pop = list(
            itertools.islice(ops.uniform_crossover(i, p_xover=1.0), 2))

        # There are four possible outcomes, which we will count the occurence of
        if np.all(new_pop[0].genome == [0, 0]) and np.all(
                new_pop[1].genome == [1, 1]):
            observed_dist['Unmodified'] += 1
        elif np.all(new_pop[0].genome == [1, 0]) and np.all(
                new_pop[1].genome == [0, 1]):
            observed_dist['Only left swapped'] += 1
        elif np.all(new_pop[0].genome == [0, 1]) and np.all(
                new_pop[1].genome == [1, 0]):
            observed_dist['Only right swapped'] += 1
        elif np.all(new_pop[0].genome == [1, 1]) and np.all(
                new_pop[1].genome == [0, 0]):
            observed_dist['Both swapped'] += 1
        else:
            assert (False)

    assert (N == sum(observed_dist.values()))

    p = 0.01
    p_swap = 0.2
    # This is the count we expect to see of each combination
    # Each locus swaps with p_swap.
    expected_dist = {
        'Unmodified': int((1 - p_swap) * (1 - p_swap) * N),
        'Only left swapped': int(p_swap * (1 - p_swap) * N),
        'Only right swapped': int((1 - p_swap) * p_swap * N),
        'Both swapped': int(p_swap**2 * N)
    }

    # Use a χ-squared test to see if our experiment matches what we expect
    assert (stat.stochastic_equals(expected_dist, observed_dist, p=p))
Exemple #11
0
def test_n_ary_crossover():
    """If we crossover two individuals with two bits each, the children should either be swapped copies of their parents,
    or they should exchange the second bit and keep the first bit unmodified."""
    pop = [Individual(np.array([0, 0])), Individual(np.array([1, 1]))]

    i = ops.naive_cyclic_selection(pop)

    new_pop = list(itertools.islice(ops.n_ary_crossover(i, num_points=1), 2))

    # Given that there are only two genes, one [0,0] and the other [1,1] and a single crossover point, and that the
    # only two valid crossover points are 0 or 1, then there are two possible valid states for offspring with single
    # point crossover.
    assert np.all(pop[0].genome == [1, 1]) or np.all(pop[0].genome == [0, 1])
    assert np.all(pop[1].genome == [0, 0]) or np.all(pop[1].genome == [1, 0])
Exemple #12
0
def test_mutate_randint6():
    """If we provide a value for both expected_num_mutations and the probability parameter,
    an exception should occur when the operator is used."""

    mutator = intrep_ops.mutate_randint(bounds=[(0, 1), (0, 1)],
                                        expected_num_mutations=1,
                                        probability=0.1)
    ind1 = Individual(np.array([0, 0]))
    ind2 = Individual(np.array([1, 1]))
    population = iter([ind1, ind2])
    result = mutator(population)

    with pytest.raises(ValueError):
        # Pulse the iterator so mutation gets executed
        result = list(result)
Exemple #13
0
def test_simple_evaluate():
    # Let's try evaluating a single individual
    pop = [Individual(np.array([1, 1]), problem=MaxOnes())]

    evaluated_individual = next(ops.evaluate(iter(pop)))

    assert evaluated_individual.fitness == 2
Exemple #14
0
def test_simple_evaluate():
    # Let's try evaluating a single individual
    pop = [Individual([1, 1], decoder=IdentityDecoder(), problem=MaxOnes())]

    evaluated_individual = next(ops.evaluate(iter(pop)))

    assert evaluated_individual.fitness == 2
Exemple #15
0
def test_mutate_randint2():
    """If we set the expected number of mutations to 2 when our genomes have
     only 2 genes, then each gene is always mutated, meaning individuals are
     completely resampled from a uniform distribution."""

    N = 1000  # We'll sample 1,000 independent genomes

    # Set up arrays to collect the values of 4 different loci after mutation
    ind0_gene0_values = []
    ind0_gene1_values = []
    ind1_gene0_values = []
    ind1_gene1_values = []

    for _ in range(N):
        # Set up two parents with fixed genomes, two genes each
        ind1 = Individual([0, 0])
        ind2 = Individual([1, 1])
        population = iter([ind1, ind2])

        # Mutate the parents
        result = ops.mutate_randint(population,
                                    bounds=[(0, 1), (0, 1)],
                                    expected_num_mutations=2)
        result = list(result)  # Pulse the iterator

        # Collect the values of each of the genes after mutation
        ind0_gene0_values.append(result[0].genome[0])
        ind0_gene1_values.append(result[0].genome[1])
        ind1_gene0_values.append(result[1].genome[0])
        ind1_gene1_values.append(result[1].genome[1])

    # Count the number of times that each gene value occurs at each locus
    ind0_gene0_counts = Counter(ind0_gene0_values)
    ind0_gene1_counts = Counter(ind0_gene1_values)
    ind1_gene0_counts = Counter(ind1_gene0_values)
    ind1_gene1_counts = Counter(ind1_gene1_values)

    # Expected distribution of mutations.
    # We arrive at this by the following reasoning: since we only have
    # two genes, our mutation probability is 2/L = 1.0.  So all four genes
    # should be sampled uniformly from the set {0, 1}.
    expected = {0: 0.5 * N, 1: 0.5 * N}
    p = 0.001
    assert (stat.stochastic_equals(expected, ind0_gene0_counts, p=p))
    assert (stat.stochastic_equals(expected, ind0_gene1_counts, p=p))
    assert (stat.stochastic_equals(expected, ind1_gene0_counts, p=p))
    assert (stat.stochastic_equals(expected, ind1_gene1_counts, p=p))
Exemple #16
0
def test_uniform_crossover():
    pop = [Individual(np.array([0, 0])), Individual(np.array([1, 1]))]

    # We need a cyclic generator because there are only two individuals in the population, and once the first two
    # are selected for uniform crossover, the next two parents are selected and crossed over.  The cyclic iterator
    # ensures we just select the same two individuals again even though the yield statements in the uniform
    # crossover operator are not invoked again.
    i = ops.naive_cyclic_selection(pop)

    # Do swap with 100% certainty, which will cause the two individuals' genomes to exchange values
    new_pop = list(itertools.islice(ops.uniform_crossover(i, p_swap=1.0), 2))
    assert np.all(new_pop[0].genome == [1, 1])
    assert np.all(new_pop[1].genome == [0, 0])

    # Note because we didn't clone the selected individuals, *the original population was changed*.
    assert np.all(pop[0].genome == [1, 1])
    assert np.all(pop[1].genome == [0, 0])
Exemple #17
0
def test_multiple_evaluations():
    # Let's try evaluating a single individual
    pop = [
        Individual(np.array([0, 0]), problem=MaxOnes()),
        Individual(np.array([0, 1]), problem=MaxOnes()),
        Individual(np.array([1, 0]), problem=MaxOnes()),
        Individual(np.array([1, 1]), problem=MaxOnes())
    ]

    evaluated_individuals = Individual.evaluate_population(pop)

    # Since this is the MAX ONES problem, we just count the ones ahead of
    # time, and ensure that the actual fitnesses match up.
    expected_fitnesses = [0, 1, 1, 2]

    for individual, fitness in zip(evaluated_individuals, expected_fitnesses):
        assert individual.fitness == fitness
Exemple #18
0
def test_apply_mutation():
    """Applying segment-wise mutation operators with expected_num_mutations=len(genome) should
    result in every gene of every segment being mutated."""
    mutation_op = apply_mutation(mutator=genome_mutate_bitflip,
                                 expected_num_mutations=4)
    original = Individual([np.array([0, 0]), np.array([1, 1])])
    mutated = next(mutation_op(iter([original])))

    assert np.all(mutated.genome[0] == [1, 1]) \
        and np.all(mutated.genome[1] == [0, 0])
Exemple #19
0
def test_koza_minimization():
    """
        Tests the koza_parsimony() function for _minimization_ problems.
    """
    problem = SpheroidProblem(maximize=False)

    pop = []

    # First individual has a fitness of three but len(genome) of 4
    pop.append(Individual(np.array([0, 1, 1, 1]), problem=problem))

    # Second has a fitness of 4, but len(genome) of 1
    pop.append(Individual(np.array([2]), problem=problem))

    pop = Individual.evaluate_population(pop)

    best = ops.truncation_selection(pop, size=1, key=koza_parsimony(penalty=1))

    assert np.all(best[0].genome == [2])
Exemple #20
0
def test_truncation_selection():
    """ Basic truncation selection test"""
    pop = [
        Individual([0, 0, 0], decoder=IdentityDecoder(), problem=MaxOnes()),
        Individual([0, 0, 1], decoder=IdentityDecoder(), problem=MaxOnes()),
        Individual([1, 1, 0], decoder=IdentityDecoder(), problem=MaxOnes()),
        Individual([1, 1, 1], decoder=IdentityDecoder(), problem=MaxOnes())
    ]

    # We first need to evaluate all the individuals so that truncation selection has fitnesses to compare
    pop = Individual.evaluate_population(pop)

    truncated = ops.truncation_selection(pop, 2)

    assert len(truncated) == 2

    # Just to make sure, check that the two best individuals from the original population are in the selected population
    assert pop[2] in truncated
    assert pop[3] in truncated
Exemple #21
0
    def _compute_deltas(self):
        """Sample additional points by create a convex combination of random
        pairs of individuals in the original design.

        Returns a list of :math:`\\delta` values, calculated as :math:`\\delta = f(p) - \\text{comb}(f(x), f(y))`,
        where :math:`p` is the individual
        resulting from the complex combination of the pair, a :math:`\\text{comb}(f(x), f(y))` is the
        complex combination of the *objective values* for each pair.
        """
        pairs = []
        combinations = []
        deltas = []
        for _ in range(self.num_convexity_tests):
            # Choose two individuals from the initial experiment design without replacement
            # (so the same individual is not chosen twice)
            x, y = np.random.choice(self.design_individuals,
                                    size=2,
                                    replace=False)
            pairs.append((x, y))

            # Find the convex combination of the original fitnesses
            a = np.random.uniform(0, 1)
            b = 1.0 - a
            f = a * x.fitness + b * y.fitness

            # Sample another point by taking the same convex combination of x and y
            x_genome = x.genome
            y_genome = y.genome
            p_genome = a * x_genome + b * y_genome

            # Evalute the new point's fitness
            p = Individual(p_genome,
                           problem=self.problem,
                           decoder=self.representation.decoder
                           )  # Need a decoder; can't assume IdentityDecoder
            p.evaluate()
            combinations.append((f, p))

            delta = p.fitness - f
            deltas.append(delta)

        return pairs, combinations, deltas
Exemple #22
0
def test_n_ary_crossover_probability():
    """If we perform crossover with a probabilty of 0.5, then the individuals will be unmodified 50% of the time."""
    N = 1000
    unmodified_count = 0

    for i in range(N):

        pop = [Individual([0, 0]), Individual([1, 1])]
        i = ops.naive_cyclic_selection(pop)
        new_pop = list(itertools.islice(ops.n_ary_crossover(i, p=0.5), 2))

        if new_pop[0].genome == [0, 0] and new_pop[1].genome == [1, 1]:
            unmodified_count += 1

    p = 0.01
    observed_dist = {
        'Unmodified': unmodified_count,
        'Modified': N - unmodified_count
    }
    assert (stat.equals_uniform(observed_dist, p=p))
Exemple #23
0
def test_naive_cyclic_selection():
    """ Test of the naive deterministic cyclic selection """
    pop = [
        Individual([0, 0], decoder=IdentityDecoder(), problem=MaxOnes()),
        Individual([0, 1], decoder=IdentityDecoder(), problem=MaxOnes())
    ]

    # This selection operator will deterministically cycle through the
    # given population
    selector = ops.naive_cyclic_selection(pop)

    selected = next(selector)
    assert selected.genome == [0, 0]

    selected = next(selector)
    assert selected.genome == [0, 1]

    # And now we cycle back to the first individual
    selected = next(selector)
    assert selected.genome == [0, 0]
Exemple #24
0
def test_lexical_minimization():
    """
        Tests lexical_parsimony() for minimization problems
    """
    problem = SpheroidProblem(maximize=False)

    pop = []

    # fitness=4, len(genome)=1
    pop.append(Individual(np.array([2]), problem=problem))

    # fitness=4, len(genome)=4
    pop.append(Individual(np.array([1, 1, 1, 1]), problem=problem))

    pop = Individual.evaluate_population(pop)

    best = ops.truncation_selection(pop, size=1, key=lexical_parsimony)

    # prefers the shorter of the genomes with equivalent fitness
    assert np.all(best[0].genome == [2])
Exemple #25
0
def test_segmented_crossover():
    """ test that k-ary crossover works as expected for fixed and variable
        length segments
    """
    a = Individual([[0, 0], [1, 1]])
    b = Individual([[1, 1], [0, 0]])

    result = n_ary_crossover(iter([a, b]))
    c = next(result)
    d = next(result)

    possible_outcomes = [[[0, 0], [1, 1]], [[1, 1], [0, 0]], [[0, 0], [0, 0]],
                         [[1, 1], [1, 1]]]

    assert c.genome in possible_outcomes and d.genome in possible_outcomes

    # Now for genomes of different lengths
    # TODO I need to *carefully* review the possible crossover possibilities
    possible_outcomes = [
        [],
        [[0, 0]],
        [[1, 1]],
        [[2, 2]],
        [[0, 0], [1, 1]],
        [[1, 1], [2, 2]],
        [[2, 2], [1, 1]],
        [[2, 2], [0, 0], [1, 1]],
        [[0, 0], [2, 2], [1, 1]],
        [[0, 0], [1, 1], [2, 2]],
    ]

    for _ in range(20):
        a = Individual([[0, 0], [1, 1]])
        b = Individual([[2, 2]])

        result = n_ary_crossover(iter([a, b]))
        c = next(result)
        d = next(result)

        assert c.genome in possible_outcomes
        assert d.genome in possible_outcomes
Exemple #26
0
def test_lexical_maximization():
    """
        Tests the lexical_parsimony() for maximization problems
    """
    problem = MaxOnes()

    # fitness=3, len(genome)=6
    pop = [Individual(np.array([0, 0, 0, 1, 1, 1]), problem=problem)]

    # fitness=2, len(genome)=2
    pop.append(Individual(np.array([1, 1]), problem=problem))

    # fitness=3, len(genome)=3
    pop.append(Individual(np.array([1, 1, 1]), problem=problem))

    pop = Individual.evaluate_population(pop)

    best = ops.truncation_selection(pop, size=1, key=lexical_parsimony)

    # prefers the shorter of the 3 genomes
    assert np.all(best[0].genome == [1, 1, 1])
Exemple #27
0
def test_cgp_mutate1(test_2layer_circuit):
    genome, _, decoder = test_2layer_circuit

    N = 1000
    mutator = cgp.cgp_mutate(decoder)
    parents = (Individual(genome[:]) for _ in range(N)
               )  # Copying the parent N times, since mutation is destructive
    offspring = list(mutator(parents))

    observed = {}
    observed[0] = Counter([ind.genome[0] for ind in offspring])
    observed[1] = Counter([ind.genome[1] for ind in offspring])
    observed[2] = Counter([ind.genome[2] for ind in offspring])
    observed[3] = Counter([ind.genome[3] for ind in offspring])
    observed[4] = Counter([ind.genome[4] for ind in offspring])
    observed[5] = Counter([ind.genome[5] for ind in offspring])
    observed[6] = Counter([ind.genome[6] for ind in offspring])

    expected = {}
    # Genes 0, 3, 6, and 9 specify primitives.  Since we only have one
    # primitive, this gene will not change.
    expected[0] = {0: N}
    expected[3] = {0: N}
    expected[6] = {0: N}
    expected[9] = {0: N}

    # We expect the mutation chance to be 1/L
    p_mut = 1 / len(genome)
    p_stay = 1 - p_mut

    # Genes 1 and 2 may be mutated to one of the input nodes,
    # with probability 1/L and uniform sampling
    expected[1] = {
        0: floor((p_stay + p_mut * 0.5) * N),
        1: ceil(p_mut * 0.5 * N)
    }
    expected[2] = {
        0: floor(p_mut * 0.5 * N),
        1: ceil((p_stay + p_mut * 0.5) * N)
    }
    expected[4] = {
        0: floor(p_mut * 0.5 * N),
        1: ceil((p_stay + p_mut * 0.5) * N)
    }
    expected[5] = {
        0: floor((p_stay + p_mut * 0.5) * N),
        1: ceil(p_mut * 0.5 * N)
    }

    p = 0.001
    for i in range(7):
        print(f"Gene {i}, expected={expected[i]}, observed={observed[i]}")
        assert (stat.stochastic_equals(expected[i], observed[i], p=p))
Exemple #28
0
def test_mutate_randint_pipe():
    """  This tests pipeline integration
    """
    ind1 = Individual(np.array([0, 0, 0]))
    ind2 = Individual(np.array([1, 1, 1]))
    population = iter([ind1, ind2])

    bounds = [(-100, 100), (0, 25), (-10, 10)]

    # Test that mutate_randint can be plugged into a pipeline since we
    # were experiencing an error when trying to do this.  The error turned out
    # to be that `bounds=` wasn't included in the call, which meant that python
    # tried to immediately invoke the `mutate_randint` instead of delaying
    # execution per the pipeline calls.
    results = toolz.pipe(population,
                         leap_ec.ops.clone,
                         intrep_ops.mutate_randint(bounds=bounds, expected_num_mutations=1),
                         # intrep_ops.mutate_randint(bounds), INCORRECT USAGE
                         leap_ec.ops.pool(size=2))

    assert len(results)
Exemple #29
0
def _build_test_pop():
    """Construct a synthetic population for illustrating example operations."""
    pop = [
        Individual([1, 0, 1, 1, 0], IdentityDecoder(), MaxOnes()),
        Individual([0, 0, 1, 0, 0], IdentityDecoder(), MaxOnes()),
        Individual([0, 1, 1, 1, 1], IdentityDecoder(), MaxOnes()),
        Individual([1, 0, 0, 0, 1], IdentityDecoder(), MaxOnes())
    ]
    pop = Individual.evaluate_population(pop)

    # Assign distinct values to an attribute on each individual
    attrs = [('foo', ['GREEN', 15, 'BLUE', 72.81]),
             ('bar', ['Colorless', 'green', 'ideas', 'sleep']),
             ('baz', [['a', 'b', 'c'], [1, 2, 3], [None, None, None],
                      [0.1, 0.2, 0.3]])]

    for attr, vals in attrs:
        for (ind, val) in zip(pop, vals):
            ind.__dict__[attr] = val

    return pop
Exemple #30
0
def test_uniform_crossover_probability1():
    """If we perform uniform rossover with a probabilty of 0.0, then the individuals will always be unmodified.
    
    This test calls the crossover opererator, which is stochastic, but we haven't marked it as part of the 
    stochastic test suite because there is no chance of a false failure (i.e. a test that fails even when
    there is no fault in the code) in this case."""
    N = 20
    unmodified_count = 0

    for i in range(N):

        pop = [Individual(np.array([0, 0])), Individual(np.array([1, 1]))]
        i = ops.naive_cyclic_selection(pop)
        new_pop = list(
            itertools.islice(ops.uniform_crossover(i, p_xover=0.0), 2))

        if np.all(new_pop[0].genome == [0, 0]) and np.all(
                new_pop[1].genome == [1, 1]):
            unmodified_count += 1

    assert (unmodified_count == N)