def _mutualism( self, agent_i: Agent, agent_j: Agent, best_agent: Agent, function: Function ) -> None: """Performs the mutualism operation. Args: agent_i: Selected `i` agent. agent_j: Selected `j` agent. best_agent: Global best agent. function: A Function object that will be used as the objective function. """ # Copies temporary agents from `i` and `j` a = copy.deepcopy(agent_i) b = copy.deepcopy(agent_j) # Calculates the mutual vector (eq. 3) mutual_vector = (agent_i.position + agent_j.position) / 2 # Calculates the benefitial factors BF_1, BF_2 = np.random.choice([1, 2], 2, replace=False) # Generates a uniform random number r1 = r.generate_uniform_random_number() # Re-calculates the new positions (eq. 1 and 2) a.position += r1 * (best_agent.position - mutual_vector * BF_1) b.position += r1 * (best_agent.position - mutual_vector * BF_2) # Checks their limits a.clip_by_bound() b.clip_by_bound() # Evaluates both agents a.fit = function(a.position) b.fit = function(b.position) # If new position is better than agent's `i` position if a.fit < agent_i.fit: # Replaces the agent's `i` position and fitness agent_i.position = copy.deepcopy(a.position) agent_i.fit = copy.deepcopy(a.fit) # If new position is better than agent's `j` position if b.fit < agent_j.fit: # Replaces the agent's `j` position and fitness agent_j.position = copy.deepcopy(b.position) agent_j.fit = copy.deepcopy(b.fit)
def _rellocation(self, agent: Agent, best_agent: Agent, function: Function) -> None: """Performs the fox rellocation procedure. Args: agent: Current agent. best_agent: Best agent. function: A Function object that will be used as the objective function. """ # Creates a temporary agent temp = copy.deepcopy(agent) # Calculates the square root of euclidean distance between agent and best agent (eq. 1) distance = np.sqrt( g.euclidean_distance(temp.position, best_agent.position)) # Randomly selects the scaling hyperparameter alpha = r.generate_uniform_random_number(0, distance) # Calculates individual reallocation (eq. 2) temp.position += alpha * np.sign(best_agent.position - temp.position) # Checks agent's limits temp.clip_by_bound() # Calculates the fitness for the temporary position temp.fit = function(temp.position) # If new fitness is better than agent's fitness if temp.fit < agent.fit: # Copies its position and fitness to the agent agent.position = copy.deepcopy(temp.position) agent.fit = copy.deepcopy(temp.fit)
def _commensalism( self, agent_i: Agent, agent_j: Agent, best_agent: Agent, function: Function ) -> None: """Performs the commensalism operation. Args: agent_i: Selected `i` agent. agent_j: Selected `j` agent. best_agent: Global best agent. function: A Function object that will be used as the objective function. """ # Copies a temporary agent from `i` a = copy.deepcopy(agent_i) # Generates a uniform random number r1 = r.generate_uniform_random_number(-1, 1) # Updates the agent's position (eq. 4) a.position += r1 * (best_agent.position - agent_j.position) # Checks its limits a.clip_by_bound() # Evaluates its new position a.fit = function(a.position) # If the new position is better than the current agent's position if a.fit < agent_i.fit: # Replaces the current agent's position and fitness agent_i.position = copy.deepcopy(a.position) agent_i.fit = copy.deepcopy(a.fit)
def _parasitism(self, agent_i: Agent, agent_j: Agent, function: Function) -> None: """Performs the parasitism operation. Args: agent_i: Selected `i` agent. agent_j: Selected `j` agent. function: A Function object that will be used as the objective function. """ # Creates a temporary parasite agent p = copy.deepcopy(agent_i) # Generates a integer random number r1 = r.generate_integer_random_number(0, agent_i.n_variables) # Updates its position on selected variable with a uniform random number p.position[r1] = r.generate_uniform_random_number(p.lb[r1], p.ub[r1]) # Checks its limits p.clip_by_bound() # Evaluates its position p.fit = function(p.position) # If the new potision is better than agent's `j` position if p.fit < agent_j.fit: # Replaces the agent's `j` position and fitness agent_j.position = copy.deepcopy(p.position) agent_j.fit = copy.deepcopy(p.fit)
def _evaluate_location(self, agent: Agent, neighbour: Agent, function: Function, index: int) -> None: """Evaluates a food source location and update its value if possible (eq. 2.2). Args: agent: An agent. neighbour: A neightbour agent. function: A function object. index: Index of trial. """ # Generates an uniform random number r1 = r.generate_uniform_random_number(-1, 1) # Copies actual food source location a = copy.deepcopy(agent) # Change its location according to equation 2.2 a.position = agent.position + (agent.position - neighbour.position) * r1 # Checks agent's limits a.clip_by_bound() # Evaluating its fitness a.fit = function(a.position) # Check if fitness is improved if a.fit < agent.fit: # If yes, reset the number of trials for this particular food source self.trial[index] = 0 # Copies the new position and fitness agent.position = copy.deepcopy(a.position) agent.fit = copy.deepcopy(a.fit) # If not else: # We increse the trials counter self.trial[index] += 1
def _update_position( self, agent: Agent, best_agent: Agent, function: Function, energy: float ) -> None: """Updates agent's position. Args: agent: An agent instance. best_agent: A best agent instance. function: A Function object that will be used as the objective function. energy: Current energy value. """ # Makes a copy of agent a = copy.deepcopy(agent) # Calculates the distance between agent and best agent distance = agent.position - best_agent.position # Iterates through all decision variables for j in range(agent.n_variables): # Iterates through all dimensions for k in range(agent.n_dimensions): # If distance equals to zero if distance[j][k] == 0: # Updates the position by sampling a gaussian number r1 = r.generate_gaussian_random_number(0, energy) a.position[j][k] += self.direction[j][k] * r1 # If distance is different from zero else: # If distance is smaller than zero if distance[j][k] < 0: # Updates the position by adding an exponential number a.position[j][k] += r.generate_exponential_random_number( np.fabs(distance[j][k]) ) # If distance is bigger than zero else: # Updates the position by subtracting an exponential number a.position[j][k] -= r.generate_exponential_random_number( distance[j][k] ) # Clips the temporary agent's limits a.clip_by_bound() # Evaluates its new position a.fit = function(a.position) # If temporary agent's fitness is better than current agent's fitness if a.fit < agent.fit: # Replaces position and fitness agent.position = copy.deepcopy(a.position) agent.fit = copy.deepcopy(a.fit) # Generates a random number r1 = r.generate_uniform_random_number() # If random number is smaller than probability of forking if r1 < self.p_fork: # Makes a new copy of current agent a = copy.deepcopy(agent) # Generates a random position a.fill_with_uniform() # Re-evaluates its position a.fit = function(a.position) # If new fitness is better than agent's fitness if a.fit < agent.fit: # Replaces position and fitness agent.position = copy.deepcopy(a.position) agent.fit = copy.deepcopy(a.fit)