Beispiel #1
0
    def _roulette_selection(self, n_agents, fitness):
        """Performs a roulette selection on the population.

        Args:
            n_agents (int): Number of agents allowed in the space.
            fitness (list): A fitness list of every agent.

        Returns:
            The selected indexes of the population

        """

        # Calculates the number of selected individuals
        n_individuals = int(n_agents * self.p_selection)

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

        # Calculates the total fitness
        total_fitness = np.sum(fitness)

        # Calculates the probability of each fitness
        probs = [fit / total_fitness for fit in fitness]

        # Performs the selection process
        selected = d.generate_choice_distribution(n_agents, probs,
                                                  n_individuals)

        return selected
Beispiel #2
0
    def update(self, space: Space, function: Function) -> None:
        """Wraps Differential Evolution over all agents and variables (eq. 1-4).

        Args:
            space: Space containing agents and update-related information.
            function: A Function object that will be used as the objective function.

        """

        # Iterates through all agents
        for i, agent in enumerate(space.agents):
            # Randomly picks three distinct other agents, not including current one
            C = d.generate_choice_distribution(np.setdiff1d(
                range(0, len(space.agents)), i),
                                               size=3)

            # Mutates the current agent
            a = self._mutate_agent(agent, space.agents[C[0]],
                                   space.agents[C[1]], space.agents[C[2]])

            # Checks agent's limits
            a.clip_by_bound()

            # Calculates the fitness for the temporary position
            a.fit = function(a.position)

            # If new fitness is better than agent's fitness
            if a.fit < agent.fit:
                # Copies its position and fitness to the agent
                agent.position = copy.deepcopy(a.position)
                agent.fit = copy.deepcopy(a.fit)
Beispiel #3
0
    def _update(self, agents, function):
        """Method that wraps selection and mutation updates over all
        agents and variables (eq. 1-4).

        Args:
            agents (list): List of agents.
            function (Function): A Function object that will be used as the objective function.

        """

        # Iterate through all agents
        for i, agent in enumerate(agents):
            # Randomly picks three distinct other agents, not including current one
            C = d.generate_choice_distribution(np.setdiff1d(range(0, len(agents)), i), size=3)

            # Mutates the current agent
            a = self._mutate_agent(agent, agents[C[0]], agents[C[1]], agents[C[2]])

            # Check agent limits
            a.clip_limits()

            # Calculates the fitness for the temporary position
            a.fit = function(a.position)

            # If new fitness is better than agent's fitness
            if a.fit < agent.fit:
                # Copy its position to the agent
                agent.position = copy.deepcopy(a.position)

                # And also copy its fitness
                agent.fit = copy.deepcopy(a.fit)
Beispiel #4
0
    def update(self, space: Space, function: Function) -> None:
        """Wraps Artificial Flora over all agents and variables.

        Args:
            space: Space containing agents and update-related information.
            function: A Function object that will be used as the objective function.

        """

        # Sorts the agents
        space.agents.sort(key=lambda x: x.fit)

        # Creates a list of new agents
        new_agents = []

        # Iterates thorugh all agents
        for i, agent in enumerate(space.agents):
            # Iterates through amount of branches
            for _ in range(self.m):
                # Makes a copy of current agent
                a = copy.deepcopy(agent)

                # Generates random numbers
                r1 = r.generate_uniform_random_number()
                r2 = r.generate_uniform_random_number()
                r3 = r.generate_uniform_random_number()

                # Calculates the new distance (eq. 1)
                distance = (self.g_distance[i] * r1 * self.c1 +
                            self.p_distance[i] * r2 * self.c2)

                # Generates a random gaussian number
                D = r.generate_gaussian_random_number(
                    0, distance, (space.n_variables, space.n_dimensions))

                # Updates offspring's position (eq. 5)
                a.position += D

                # Clips its limits
                a.clip_by_bound()

                # Evaluates its fitness
                a.fit = function(a.position)

                # Calculates the probability of selection (eq. 6)
                p = np.fabs(np.sqrt(a.fit / space.agents[-1].fit)) * self.Q

                # If random number is smaller than probability of selection
                if r3 < p:
                    # Appends the offsprings
                    new_agents.append(a)

            # Updates both grandparent and parent distances (eq. 2 and 3)
            self.g_distance[i] = self.p_distance[i]
            self.p_distance[i] = np.std(agent.position - a.position)

        # Randomly selects the agents
        idx = d.generate_choice_distribution(len(new_agents), None,
                                             space.n_agents)
        space.agents = [new_agents[i] for i in idx]
Beispiel #5
0
    def _roulette_selection(self, fitness, a=0.1):
        """Performs a roulette selection on the population (eq. 8).

        Args:
            fitness (list): A fitness list of every agent.
            a (float): Selection regularizer.

        Returns:
            The selected index of the population.

        """

        # Defines the minimum fitness of current generation
        min_fitness = np.min(fitness)

        # Re-arrange the list of fitness by inverting it (eq. 7)
        inv_fitness = [1 / (a + fit - min_fitness) for fit in fitness]

        # Calculates the total inverted fitness
        total_fitness = np.sum(inv_fitness)

        # Calculates the probability of each inverted fitness (eq. 8)
        probs = [fit / total_fitness for fit in inv_fitness]

        # Performs the selection process
        selected = d.generate_choice_distribution(len(probs), probs, 1)

        return selected[0]
Beispiel #6
0
    def _update(self, agents, best_agent, function, sigma):
        """Method that wraps updates over all agents and variables.

        Args:
            agents (list): List of agents.
            best_agent (Agent): Global best agent.
            function (Function): A Function object that will be used as the objective function.
            sigma (list): Width between lower and upper bounds.

        """

        # Calculates a list of fitness per agent
        fitness = [
            1 / (1 + agent.fit) if agent.fit >= 0 else 1 + np.abs(agent.fit)
            for agent in agents
        ]

        # Calculates the total fitness
        total_fitness = np.sum(fitness)

        # Calculates the probability of each agent's fitness
        probs = [fit / total_fitness for fit in fitness]

        # Iterate through all agents
        for agent in agents:
            # For every decision variable
            for j in range(agent.n_variables):
                # Selects a random individual based on its probability
                s = d.generate_choice_distribution(len(agents), probs, 1)[0]

                # Calculates the lambda factor
                lambda_k = self.alpha / (1 + probs[s])

                # Updates the decision variable position
                agent.position[j] += lambda_k * (
                    (agents[s].position[j] + best_agent.position[j]) / 2 -
                    agent.position[j])

                # Generates an uniform random number
                r1 = r.generate_uniform_random_number()

                # If random number is smaller than probability of mutation
                if r1 < self.p_mutation:
                    # Mutates the decision variable position
                    agent.position[
                        j] += sigma[j] * r.generate_gaussian_random_number()

            # Check agent limits
            agent.clip_limits()

            # Calculates its fitness
            agent.fit = function(agent.position)
Beispiel #7
0
    def update(self, space: Space, function: Function) -> None:
        """Wraps Satin Bowerbird Optimizer over all agents and variables (eq. 1-7).

        Args:
            space: Space containing agents and update-related information.
            function: A Function object that will be used as the objective function.

        """

        # Calculates a list of fitness per agent
        fitness = [
            1 / (1 + agent.fit) if agent.fit >= 0 else 1 + np.abs(agent.fit)
            for agent in space.agents
        ]

        # Calculates the total fitness
        total_fitness = np.sum(fitness)

        # Calculates the probability of each agent's fitness
        probs = [fit / total_fitness for fit in fitness]

        # Iterates through all agents
        for agent in space.agents:
            # For every decision variable
            for j in range(agent.n_variables):
                # Selects a random individual based on its probability
                s = d.generate_choice_distribution(len(space.agents), probs, 1)[0]

                # Calculates the lambda factor
                lambda_k = self.alpha / (1 + probs[s])

                # Updates the decision variable position
                agent.position[j] += lambda_k * (
                    (space.agents[s].position[j] + space.best_agent.position[j]) / 2
                    - agent.position[j]
                )

                # Generates an uniform random number
                r1 = r.generate_uniform_random_number()

                # If random number is smaller than probability of mutation
                if r1 < self.p_mutation:
                    # Mutates the decision variable position
                    agent.position[j] += (
                        self.sigma[j] * r.generate_gaussian_random_number()
                    )

            # Checks agent's limits
            agent.clip_by_bound()

            # Calculates its fitness
            agent.fit = function(agent.position)
Beispiel #8
0
    def _dark_zone(self, agents, best_agent, function, life, counter):
        """Performs the dark-zone update process.

        Args:
            agents (list): List of agents.
            best_agent (Agent): Global best agent.
            function (Function): A Function object that will be used as the objective function.
            life (np.array): An array holding each cell's current life.
            counter (np.array): An array holding each cell's copy counter.

        """

        # Iterate through all agents
        for i, agent in enumerate(agents):
            # Generates the first random number, between 0 and 100
            r1 = r.generate_uniform_random_number(0, 100)

            # If random number is smaller than cell's life
            if r1 < life[i]:
                # Increases it counter by one
                counter[i] += 1

            # If it is not smaller
            else:
                # Resets the counter to one
                counter[i] = 1

            # Generates the counting distribution and pick three cells
            C = d.generate_choice_distribution(len(agents),
                                               counter / np.sum(counter),
                                               size=3)

            # Mutates a new cell based on current and pre-picked cells
            a = self._mutate_cell(agent, agents[C[0]], agents[C[1]],
                                  agents[C[2]])

            # Check agent limits
            a.clip_limits()

            # Calculates the fitness for the temporary position
            a.fit = function(a.position)

            # If new fitness is better than agent's fitness
            if a.fit < agent.fit:
                # Copy its position to the agent
                agent.position = copy.deepcopy(a.position)

                # And also copy its fitness
                agent.fit = copy.deepcopy(a.fit)

                # Increases the life of cell by ten
                life[i] += 10
Beispiel #9
0
    def _dark_zone(self, agents: List[Agent], function: Function) -> None:
        """Performs the dark-zone update process (alg. 1).

        Args:
            agents: List of agents.
            function: A Function object that will be used as the objective function.

        """

        # Iterates through all agents
        for i, agent in enumerate(agents):
            # Generates the first random number, between 0 and 100
            r1 = r.generate_uniform_random_number(0, 100)

            # If random number is smaller than cell's life
            if r1 < self.life[i]:
                # Increases it counter by one
                self.counter[i] += 1

            # If it is not smaller
            else:
                # Resets the counter to one
                self.counter[i] = 1

            # Generates the counting distribution and pick three cells
            C = d.generate_choice_distribution(len(agents),
                                               self.counter /
                                               np.sum(self.counter),
                                               size=3)

            # Mutates a new cell based on current and pre-picked cells
            a = self._mutate_cell(agent, agents[C[0]], agents[C[1]],
                                  agents[C[2]])

            # Checks agent's limits
            a.clip_by_bound()

            # Calculates the fitness for the temporary position
            a.fit = function(a.position)

            # If new fitness is better than agent's fitness
            if a.fit < agent.fit:
                # Copies its position and fitness to the agent
                agent.position = copy.deepcopy(a.position)
                agent.fit = copy.deepcopy(a.fit)

                # Increases the life of cell by ten
                self.life[i] += 10
Beispiel #10
0
    def _roulette_selection(self, n_agents: int,
                            fitness: List[float]) -> List[int]:
        """Performs a roulette selection on the population (p. 8).

        Args:
            n_agents: Number of agents allowed in the space.
            fitness: A fitness list of every agent.

        Returns:
            (List[int]): The selected indexes of the population.

        """

        # Calculates the number of selected individuals
        n_individuals = int(n_agents * self.p_selection)

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

        # Defines the maximum fitness of current generation
        max_fitness = np.max(fitness)

        # Re-arrange the list of fitness by inverting it
        # Note that we apply a trick due to it being designed for minimization
        # f'(x) = f_max - f(x)
        inv_fitness = [max_fitness - fit + c.EPSILON for fit in fitness]

        # Calculates the total inverted fitness
        total_fitness = np.sum(inv_fitness)

        # Calculates the probability of each inverted fitness
        probs = [fit / total_fitness for fit in inv_fitness]

        # Performs the selection process
        selected = d.generate_choice_distribution(n_agents, probs,
                                                  n_individuals)

        return selected
import opytimizer.math.distribution as d

# Generates a Bernoulli distribution
b = d.generate_bernoulli_distribution(prob=0.5, size=10)
print(b)

# Generates a choice distribution
c = d.generate_choice_distribution(n=10, probs=None, size=10)
print(c)

# Generates a Lévy distribution
l = d.generate_levy_distribution(beta=0.5, size=10)
print(l)
Beispiel #12
0
def test_generate_choice_distribution():
    choice_array = distribution.generate_choice_distribution(n=10, probs=None, size=10)

    assert choice_array.shape == (10,)