def update(self, space: Space, function: Function, iteration: int, n_iterations: int) -> None: """Wraps Henry Gas Solubility Optimization 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. iteration: Current iteration. n_iterations: Maximum number of iterations. """ # Creates n-wise clusters clusters = g.n_wise(space.agents, self.pressure.shape[1]) # Iterates through all clusters for i, cluster in enumerate(clusters): # Calculates the system's current temperature (eq. 8) T = np.exp(-iteration / n_iterations) # Updates Henry's coefficient (eq. 8) self.coefficient[i] *= np.exp(-self.constant[i] * (1 / T - 1 / 298.15)) # Transforms the cluster into a list and sorts it cluster = list(cluster) cluster.sort(key=lambda x: x.fit) # Iterates through all agents in cluster for j, agent in enumerate(cluster): # Calculates agent's solubility (eq. 9) solubility = self.K * self.coefficient[i] * self.pressure[i][j] # Updates agent's position (eq. 10) agent.position = self._update_position(agent, cluster[0], space.best_agent, solubility) # Clips agent's limits agent.clip_by_bound() # Re-calculates its fitness agent.fit = function(agent.position) # Re-sorts the whole space space.agents.sort(key=lambda x: x.fit) # Generates a uniform random number r1 = r.generate_uniform_random_number() # Calculates the number of worst agents (eq. 11) N = int(len(space.agents) * (r1 * (0.2 - 0.1) + 0.1)) # Iterates through every bad agent for agent in space.agents[-N:]: # Generates another uniform random number r2 = r.generate_uniform_random_number() # Updates bad agent's position (eq. 12) agent.position = agent.lb + r2 * (agent.ub - agent.lb)
def test_n_wise(): list = [1, 2, 3, 4] pairs = general.n_wise(list) for _ in pairs: pass assert type(pairs).__name__ == 'callable_iterator' or 'generator'
def _update(self, agents, function): """Method that wraps selection, crossover and mutation over all agents and variables. Args: agents (list): List of agents. function (Function): A Function object that will be used as the objective function. """ # Creating a list to hold the new population new_agents = [] # Retrieving the number of agents n_agents = len(agents) # Calculates a list of fitness from every agent fitness = [agent.fit + c.EPSILON for agent in agents] # Selects the parents selected = self._roulette_selection(n_agents, fitness) # For every pair of selected parents for s in g.n_wise(selected): # Performs the crossover alpha, beta = self._crossover(agents[s[0]], agents[s[1]]) # Performs the mutation alpha, beta = self._mutation(alpha, beta) # Checking `alpha` limits alpha.clip_limits() # Checking `beta` limits beta.clip_limits() # Calculates new fitness for `alpha` alpha.fit = function(alpha.position) # Calculates new fitness for `beta` beta.fit = function(beta.position) # Appends the mutated agents to the children new_agents.extend([alpha, beta]) # Joins both populations agents += new_agents # Sorting agents agents.sort(key=lambda x: x.fit) return agents[:n_agents]
def _crossover(self, space): """Crossover a number of individuals pre-selected through a tournament procedure (p. 101). 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.n_wise(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)
def update(self, space: Space, function: Function) -> None: """Wraps Genetic Algorithm 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. """ # Creates a list to hold the new population new_agents = [] # Retrieves the number of agents n_agents = len(space.agents) # Calculates a list of fitness from every agent fitness = [agent.fit + c.EPSILON for agent in space.agents] # Selects the parents selected = self._roulette_selection(n_agents, fitness) # For every pair of selected parents for s in g.n_wise(selected): # Performs the crossover and mutation alpha, beta = self._crossover(space.agents[s[0]], space.agents[s[1]]) alpha, beta = self._mutation(alpha, beta) # Checking `alpha` and `beta` limits alpha.clip_by_bound() beta.clip_by_bound() # Calculates new fitness for `alpha` and `beta` alpha.fit = function(alpha.position) beta.fit = function(beta.position) # Appends the mutated agents to the children new_agents.extend([alpha, beta]) # Joins both populations, sort agents and gathers best `n_agents` space.agents += new_agents space.agents.sort(key=lambda x: x.fit) space.agents = space.agents[:n_agents]
def _update(self, agents, best_agent, function, coefficient, pressure, constant, iteration, n_iterations): """Method that wraps Henry Gas Solubility Optimization 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. coefficient (np.array): Henry's coefficient array. pressure (np.array): Partial pressure array. constant (np.array): Constants array. iteration (int): Current iteration. n_iterations (int): Maximum number of iterations. """ # Creates n-wise clusters clusters = g.n_wise(agents, pressure.shape[1]) # Iterates through all clusters for i, cluster in enumerate(clusters): # Calculates the system's current temperature (eq. 8) T = np.exp(-iteration / n_iterations) # Updates Henry's coefficient (eq. 8) coefficient[i] *= np.exp(-constant[i] * (1 / T - 1 / 298.15)) # Transforms the cluster into a list and sorts it cluster = list(cluster) cluster.sort(key=lambda x: x.fit) # Iterates through all agents in cluster for j, agent in enumerate(cluster): # Calculates agent's solubility (eq. 9) solubility = self.K * coefficient[i] * pressure[i][j] # Updates agent's position (eq. 10) agent.position = self._update_position(agent, cluster[0], best_agent, solubility) # Clips agent's limits agent.clip_limits() # Re-calculates its fitness agent.fit = function(agent.position) # Re-sorts the whole space agents.sort(key=lambda x: x.fit) # Generates a uniform random number r1 = r.generate_uniform_random_number() # Calculates the number of worst agents (eq. 11) N = int(len(agents) * (r1 * (0.2 - 0.1) + 0.1)) # Iterates through every bad agent for agent in agents[-N:]: # Generates another uniform random number r2 = r.generate_uniform_random_number() # Updates bad agent's position (eq. 12) agent.position = agent.lb + r2 * (agent.ub - agent.lb)
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}")