예제 #1
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))
예제 #2
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
예제 #3
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])
예제 #4
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))