Beispiel #1
0
def test_Optimizer_get_fitnesses_with_fitness_func_side_effects():
    """Fitness function modifying solution should not affect fitnesses.

    This could potentially be a problem when there are duplicate solutions.
    """
    # Fitness function is weighted summation of bits
    solution_size = random.randint(1, 50)
    weights = numpy.random.random(solution_size)

    def fitness_func(solution):
        for i, val in enumerate(solution):
            solution[i] *= 2
        return weights.dot(solution)

    # Test Optimizer._get_fitnesses
    problem = Problem(fitness_func)

    optimizer = optimize.Optimizer()

    # Use simple map of fitness function over solutions as oracle
    # Repeat to test cache
    for _ in range(100):
        # Create a random population, and compare values returned by _get_fitness to simple maps
        population = common.make_population(random.randint(1, 20),
                                            common.random_binary_solution,
                                            solution_size)

        solutions, fitnesses, finished = optimizer._get_fitnesses(
            problem, copy.deepcopy(population), pool=None)

        assert fitnesses == map(fitness_func, population)

        assert finished is False
Beispiel #2
0
def test_Optimizer_get_solution_key():
    # Hashable
    optimizer = optimize.Optimizer()
    optimizer._get_solution_key('1') == '1'

    # Dict
    # NOTE: This requires special treatment, otherwise,
    # tuple(dict) will return a tuple of the KEYS only
    optimizer = optimize.Optimizer()
    optimizer._get_solution_key({'a': '1'}) == tuple([('a', '1')])

    # Tupleable
    optimizer = optimize.Optimizer()
    optimizer._get_solution_key(['1']) == tuple(['1'])

    # Stringable
    optimizer = optimize.Optimizer()
    optimizer._get_solution_key([['1']]) == str([['1']])
Beispiel #3
0
def _check_get_fitnesses(fitness_func,
                         decode_func,
                         solution_size,
                         fitness_func_returns_finished=False,
                         optimizer=None,
                         n_processes=0,
                         **kwargs):
    """Assert that return values of Optimizer._get_fitnesses are correct."""
    problem = Problem(fitness_func, decode_function=decode_func)

    if optimizer is None:
        optimizer = optimize.Optimizer()

    if n_processes > 0:
        pool = multiprocessing.Pool(processes=n_processes)
    else:
        pool = None

    # Use simple map of fitness function over solutions as oracle
    # Repeat to test cache
    for _ in range(100):
        # Create a random population, and compare values returned by _get_fitness to simple maps
        population = common.make_population(random.randint(1, 20),
                                            common.random_binary_solution,
                                            solution_size)

        solutions, fitnesses, finished = optimizer._get_fitnesses(
            problem, copy.deepcopy(population), pool=pool, **kwargs)
        # NOTE: _get_fitnesses will return None for solutions in cache, this is expected and ok
        assert False not in [
            solution == expected for solution, expected in zip(
                solutions, map(decode_func, population))
            if solution is not None
        ]

        if fitness_func_returns_finished is False:
            assert fitnesses == map(fitness_func, map(decode_func, population))
        else:
            # Need to strip finished from fitness_func return values
            assert fitnesses == [
                fitness_finished[0] for fitness_finished in map(
                    fitness_func, map(decode_func, population))
            ]

        assert finished is False
Beispiel #4
0
def test_Optimizer_encoded_cache_correct():
    """Should map the correct key to fitness."""
    optimizer = optimize.Optimizer()

    def fitness_func(solution):
        return solution[0] + 0.5 * solution[1]

    problem = Problem(fitness_func)

    # Test cache
    optimizer._get_fitnesses(problem, [[0, 0], [0, 1], [1, 0], [1, 1]],
                             cache_encoded=True)
    assert optimizer._Optimizer__encoded_cache == {
        (0, 0): 0,
        (0, 1): 0.5,
        (1, 0): 1.0,
        (1, 1): 1.5
    }
Beispiel #5
0
def test_Optimizer_solution_cache_correct():
    """Should map the correct key to fitness."""
    optimizer = optimize.Optimizer()

    def fitness_func(solution):
        return solution[0] + 0.5 * solution[1]

    def decode_func(encoded_solution):
        return (-encoded_solution[0], -encoded_solution[1])

    problem = Problem(fitness_func, decode_function=decode_func)

    # Test cache
    optimizer._get_fitnesses(problem, [[0, 0], [0, 1], [1, 0], [1, 1]],
                             cache_solution=True)
    assert optimizer._Optimizer__solution_cache == {
        (0, 0): 0,
        (0, -1): -0.5,
        (-1, 0): -1.0,
        (-1, -1): -1.5
    }
Beispiel #6
0
def test_Optimizer_get_fitnesses_cache_encoded_False_cache_solution_True():
    """Fitnesses should correspond to solutions."""
    # Fitness function is weighted summation of bits
    solution_size = random.randint(1, 50)
    weights = numpy.random.random(solution_size)

    def fitness_func(solution):
        return weights.dot(solution)

    # Optimizer with disabled encoded cache
    optimizer = optimize.Optimizer()

    # Test Optimizer._get_fitnesses
    _check_get_fitnesses(fitness_func,
                         lambda x: x,
                         solution_size,
                         optimizer=optimizer,
                         cache_encoded=False,
                         cache_solution=True)

    # Check caches as expected
    assert optimizer._Optimizer__encoded_cache == {}
    assert optimizer._Optimizer__solution_cache != {}
Beispiel #7
0
def test_Optimizer_get_fitnesses_unhashable_solution():
    """Should not fail when solution cannot be hashed or cached."""
    # Fitness function is weighted summation of bits
    solution_size = random.randint(1, 50)
    weights = numpy.random.random(solution_size)

    def fitness_func(solution):
        return weights.dot(solution.list)

    class ListWrapper(object):
        def __init__(self, list_):
            self.list = list_

        def __eq__(self, other):
            return type(self) == type(other) and self.list == other.list

        def __hash__(self):
            raise NotImplementedError()

        def __str__(self):
            raise NotImplementedError()

    decode_weights = numpy.random.random(solution_size)

    def decode_func(encoded_solution):
        return ListWrapper(list(decode_weights * encoded_solution))

    optimizer = optimize.Optimizer()

    # Test Optimizer._get_fitnesses
    _check_get_fitnesses(fitness_func,
                         decode_func,
                         solution_size,
                         optimizer=optimizer,
                         cache_solution=True)

    assert optimizer._Optimizer__solution_cache == {}