aimclub / GOLEM

Graph Optimiser for Learning and Evolution of Models
https://thegolem.readthedocs.io
BSD 3-Clause "New" or "Revised" License
63 stars 7 forks source link

Fix molecules integration test #144

Closed gkirgizov closed 1 year ago

gkirgizov commented 1 year ago

Sometimes test fails with error:

test\integration\test_molecule_search.py:8 (test_molecule_search_example[norm_log_p-normalized_logp])
metric_name = 'norm_log_p'
metric = <function normalized_logp at 0x000001841ACDE5E0>

    @pytest.mark.parametrize('metric_name, metric', [['norm_log_p', normalized_logp]])
    def test_molecule_search_example(metric_name, metric):
        initial_molecule = get_methane()
        optimizer, objective = molecule_search_setup(num_iterations=10,
                                                     metrics=[metric_name],
                                                     initial_molecules=[initial_molecule])
>       found_graphs = optimizer.optimise(objective)

test_molecule_search.py:15: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\golem\core\optimisers\populational_optimizer.py:97: in optimise
    new_population = self._evolve_population(evaluator)
..\..\golem\core\optimisers\genetic\gp_optimizer.py:112: in _evolve_population
    new_population = self.reproducer.reproduce(individuals_to_select, evaluator)
..\..\golem\core\optimisers\genetic\operators\reproduction.py:104: in reproduce
    partial_next_population = self.reproduce_uncontrolled(population, evaluator, residual_size)
..\..\golem\core\optimisers\genetic\operators\reproduction.py:79: in reproduce_uncontrolled
    selected_individuals = self.selection(population, pop_size)
..\..\golem\core\optimisers\genetic\operators\selection.py:26: in __call__
    return self._selection_by_type(selection_type)(population, pop_size)
..\..\golem\core\optimisers\genetic\operators\selection.py:56: in wrapper
    return func(individuals, pop_size, *args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

individuals = [<Individual 6e4d4563-3c0d-4b4d-a200-783d8213ac4c | fitness: -6.7642 | native_generation: 3 | graph: {'depth': 1, 'len...f5d-85e3-9d500c4c32ea | fitness: -6.2296 | native_generation: 3 | graph: {'depth': 1, 'length': 1, 'nodes': [C]}>, ...]
pop_size = 26

    @default_selection_behaviour
    def spea2_selection(individuals: PopulationT, pop_size: int) -> PopulationT:
        """
        Apply SPEA-II selection operator on the *individuals*. Usually, the
        size of *individuals* will be larger than *n* because any individual
        present in *individuals* will appear in the returned list at most once.
        Having the size of *individuals* equals to *n* will have no effect other
        than sorting the population according to a strength Pareto scheme. The
        list returned contains references to the input *individuals*.

        :param individuals: A list of individuals to select from.
        :returns: A list of selected individuals
        """
        inds_len = len(individuals)
        fitness_len = len(individuals[0].fitness.values)
        inds_len_sqrt = math.sqrt(inds_len)
        strength_fits = [0] * inds_len
        fits = [0] * inds_len
        dominating_inds = [list() for _ in range(inds_len)]

        for i, ind_i in enumerate(individuals):
            for j, ind_j in enumerate(individuals[i + 1:], i + 1):
                if ind_i.fitness.dominates(ind_j.fitness):
                    strength_fits[i] += 1
                    dominating_inds[j].append(i)
                elif ind_j.fitness.dominates(ind_i.fitness):
                    strength_fits[j] += 1
                    dominating_inds[i].append(j)

        for i in range(inds_len):
            for j in dominating_inds[i]:
                fits[i] += strength_fits[j]

        # Choose all non-dominated individuals
        chosen_indices = [i for i in range(inds_len) if fits[i] < 1]

        if len(chosen_indices) < pop_size:  # The archive is too small
            for i in range(inds_len):
                distances = [0.0] * inds_len
                for j in range(i + 1, inds_len):
                    dist = 0.0
                    for idx in range(fitness_len):
                        val = \
>                           individuals[i].fitness.values[idx] - \
                            individuals[j].fitness.values[idx]
E                       TypeError: unsupported operand type(s) for -: 'float' and 'NoneType'

..\..\golem\core\optimisers\genetic\operators\selection.py:133: TypeError
gkirgizov commented 1 year ago

Fixed by #145