Example #1
0
    def _mutation(self, space):
        """Mutates a number of individuals pre-selected through a tournament procedure.

        Args:
            space (TreeSpace): A TreeSpace object.

        """

        # Calculates a list of current trees' fitness
        fitness = [agent.fit for agent in space.agents]

        # Number of individuals to be mutated
        n_individuals = int(space.n_trees * self.p_mutation)

        # Gathers a list of selected individuals to be replaced
        selected = g.tournament_selection(fitness, n_individuals)

        # For every selected individual
        for s in selected:
            # Gathers individual number of nodes
            n_nodes = space.trees[s].n_nodes

            # Checks if the tree has more than one node
            if n_nodes > 1:
                # Prunes the amount of maximum nodes
                max_nodes = self._prune_nodes(n_nodes)

                # Mutatets the individual
                space.trees[s] = self._mutate(space, space.trees[s], max_nodes)

            # If there is only one node
            else:
                # Re-create it with a random tree
                space.trees[s] = space.grow(space.min_depth, space.max_depth)
Example #2
0
    def _reproduction(self, space):
        """Reproducts a number of individuals pre-selected through a tournament procedure.

        Args:
            space (TreeSpace): A TreeSpace object.

        """

        # Calculates a list of current trees' fitness
        fitness = [agent.fit for agent in space.agents]

        # Number of individuals to be reproducted
        n_individuals = int(space.n_trees * self.p_reproduction)

        # Gathers a list of selected individuals to be replaced
        selected = g.tournament_selection(fitness, n_individuals)

        # For every selected individual
        for s in selected:
            # Gathers the worst individual index
            worst = np.argmax(fitness)

            # Replace the individual by performing a deep copy on selected tree
            space.trees[worst] = copy.deepcopy(space.trees[s])

            # We also need to copy the agent
            space.agents[worst] = copy.deepcopy(space.agents[s])

            # Replaces the worst individual fitness with a minimum value
            fitness[worst] = 0
Example #3
0
    def _parasitism_phase(
        self,
        space: Space,
        n_crows: int,
        n_cuckoos: int,
        iteration: int,
        n_iterations: int,
    ):
        """Performs the parasitism phase using the current number of cuckoos.

        Args:
            space: Space containing agents and update-related information.
            n_crows: Number of crows.
            n_cuckoos: Number of cuckoos.
            iteration: Current iteration.
            n_iterations: Maximum number of iterations.

        """

        # Gathers the cuckoos
        cuckoos = space.agents[n_crows:n_crows + n_cuckoos]

        # Calculates a list of cuckoos' fitness
        fitness = [cuckoo.fit for cuckoo in cuckoos]

        # Calculates the probability of selection
        p = iteration / n_iterations

        # Iterates through all cuckoos
        for cuckoo in cuckoos:
            # Selects a cuckoo through tournament selection
            s = g.tournament_selection(fitness, 1)[0]

            # Selects two random agents from the space
            i = r.generate_integer_random_number(high=space.n_agents)
            j = r.generate_integer_random_number(high=space.n_agents,
                                                 exclude_value=i)

            # Creates a bernoulli distribution to preserve or not variables (eq. 12)
            k = d.generate_bernoulli_distribution(1 - p, cuckoo.n_variables)
            k = np.expand_dims(k, -1)

            # Calculates the gaussian-based step distribution (eq. 11)
            rand = r.generate_uniform_random_number()
            S_g = (space.agents[i].position - space.agents[j].position) * rand

            # Updates the cuckoo's position and clips its limits (eq. 10)
            cuckoo.position = space.agents[s].position + S_g * k
            cuckoo.clip_by_bound()
Example #4
0
    def _moving_safe_place(self, prides: List[Lion]) -> None:
        """Move prides to safe locations (s. 2.2.3).

        Args:
            prides: List of prides holding their corresponding lions.

        """

        # Iterates through all prides
        for pride in prides:
            # Calculates the number of improved lions (eq. 7)
            n_improved = np.sum(
                [1 for agent in pride if agent.fit < agent.p_fit])

            # Calculates the fitness of lions (eq. 8)
            fitnesses = [agent.fit for agent in pride]

            # Calculates the size of tournament (eq. 9)
            tournament_size = np.maximum(2, int(np.ceil(n_improved / 2)))

            # Iterates through all agents in pride
            for agent in pride:
                # If agent is female and belongs to group 0
                if agent.group == 0 and agent.female:
                    # Gathers the winning lion from tournament selection
                    w = g.tournament_selection(fitnesses, 1,
                                               tournament_size)[0]

                    # Calculates the distance between agent and winner
                    distance = g.euclidean_distance(agent.position,
                                                    pride[w].position)

                    # Generates random numbers
                    rand = r.generate_uniform_random_number()
                    u = r.generate_uniform_random_number(-1, 1)
                    theta = r.generate_uniform_random_number(
                        -np.pi / 6, np.pi / 6)

                    # Calculates both `R1` and `R2` vectors
                    R1 = pride[w].position - agent.position
                    R2 = np.random.randn(*R1.T.shape)
                    R2 = R2.T - R2.dot(R1) * R1 / (np.linalg.norm(R1)**2 +
                                                   c.EPSILON)

                    # Updates agent's position (eq. 6)
                    agent.position += (2 * distance * rand * R1 +
                                       u * np.tan(theta) * distance * R2)
Example #5
0
    def _crossover(self, space):
        """Crossover a number of individuals pre-selected through a tournament procedure.

        Args:
            space (TreeSpace): A TreeSpace object.
            agents (list): Current iteration agents.
            trees (list): Current iteration trees.

        """

        # Calculates a list of current trees' fitness
        fitness = [agent.fit for agent in space.agents]

        # Number of individuals to be crossovered
        n_individuals = int(space.n_trees * self.p_crossover)

        # Checks if `n_individuals` is an odd number
        if n_individuals % 2 != 0:
            # If it is, increase it by one
            n_individuals += 1

        # Gathers a list of selected individuals to be replaced
        selected = g.tournament_selection(fitness, n_individuals)

        # For every pair in selected individuals
        for s in g.pairwise(selected):
            # Calculates the amount of father nodes
            father_nodes = space.trees[s[0]].n_nodes

            # Calculate the amount of mother nodes
            mother_nodes = space.trees[s[1]].n_nodes

            # Checks if both trees have more than one node
            if (father_nodes > 1) and (mother_nodes > 1):
                # Prunning father nodes
                max_f_nodes = self._prune_nodes(father_nodes)

                # Prunning mother nodes
                max_m_nodes = self._prune_nodes(mother_nodes)

                # Apply the crossover operation
                space.trees[s[0]], space.trees[s[1]] = self._cross(
                    space.trees[s[0]], space.trees[s[1]], max_f_nodes,
                    max_m_nodes)
Example #6
0
def test_tournament_selection():
    fitness = [1, 2, 3, 4]

    selected = general.tournament_selection(fitness, 2)

    assert len(selected) == 2
Example #7
0
import opytimizer.math.general as g

# Creates a list for pairwising
individuals = [1, 2, 3, 4]

# Creates pairwise from list
for pair in g.n_wise(individuals, 2):
    # Outputting pairs
    print(f"Pair: {pair}")

# Performs a tournmanet selection over list
selected = g.tournament_selection(individuals, 2)

# Outputting selected individuals
print(f"Selected: {selected}")