eckity.subpopulation
1import random 2import numpy as np 3 4from eckity.creators.creator import Creator 5from eckity.creators.gp_creators.full import FullCreator 6 7from eckity.genetic_operators.crossovers.subtree_crossover import SubtreeCrossover 8from eckity.genetic_operators.mutations.erc_mutation import ERCMutation 9from eckity.genetic_operators.mutations.subtree_mutation import SubtreeMutation 10from eckity.genetic_operators.selections.tournament_selection import TournamentSelection 11 12 13class Subpopulation: 14 """ 15 Subgroup of the experiment population. 16 17 Contains a specific encoding, fitness evaluation method, creator list, operator sequence and selection methods. 18 19 Parameters 20 ---------- 21 evaluator: IndividualEvaluator 22 fitness evaluation method for the individuals of this sub-population 23 24 creators: Creator or list of Creators, default=None 25 possible creators to generate individuals according to the encoding 26 of this sub-population (GPTrees, Bit Vectors etc.) 27 28 pcr: list of integers, default=None 29 probability mapping for each creator in creators parameter. 30 Length must match the length of creators parameter. 31 32 operators_sequence: list of Crossovers and Mutations, default=None 33 Possible crossover and mutation actions that can change the individuals' representations. 34 The operators will be done sequentially in each generation, by their order in the list. 35 See eckity.genetic_operators for more details on crossover and mutation operators 36 37 selection_methods: list of SelectionMethods 38 Methods for selecting individuals in each generation. 39 See eckity.genetic_operators for more details on selection methods 40 41 elitism_rate: float, default=0.0 42 What percentage of the sub-population's individuals should be kept as elites for the next generation 43 44 population_size: int, default=200 45 The number of individuals in this sub-population. 46 47 individuals: list of Individuals, default=None 48 The individuals list of this sub-population. 49 50 higher_is_better: bool, default=False 51 Determines if the fitness value of this sub-population's individuals should be maximized or minimized. 52 53 Attributes 54 ---------- 55 n_elite: int 56 Number of the sub-population's elite individuals. 57 In every generation, there will be n_elites slots for the elite individuals 58 that will be copied as-is to the next generation. 59 """ 60 61 def __init__(self, 62 evaluator, 63 creators=None, 64 pcr=None, 65 operators_sequence=None, 66 selection_methods=None, 67 elitism_rate=0.0, 68 population_size=200, 69 individuals=None, 70 higher_is_better=False): 71 72 # verify valid creators and creation probability inputs 73 if creators is None: 74 full_cr = FullCreator() 75 creators = [full_cr] 76 elif isinstance(creators, Creator): 77 creators = [creators] 78 elif isinstance(creators, list): 79 if len(creators) == 0: 80 raise ValueError('Creators list cannot be empty') 81 for creator in creators: 82 if not isinstance(creator, Creator): 83 raise ValueError('Detected a non-creator instance as an element in creators list') 84 else: 85 raise ValueError( 86 'Parameter creators must be either a Creator or a list of Creators\n ' 87 'received creators with unexpected type of', type(creators) 88 ) 89 90 if pcr is None: 91 pcr = [1 / len(creators) for _ in creators] 92 93 if len(creators) != len(pcr): 94 raise ValueError(f'Number of creators ({len(creators)}) \ 95 must match number of creation probabilities {(len(pcr))}!') 96 if sum(pcr) != 1: 97 raise ValueError(f'Sum of creation probabilities ({pcr}) must be 1!') 98 99 # set default args 100 if operators_sequence is None: 101 operators_sequence = [SubtreeCrossover(arity=2, probability=0.9), 102 SubtreeMutation(arity=1, probability=0.7), 103 ERCMutation(arity=1, probability=0.1)] 104 if selection_methods is None: 105 selection_methods = [(TournamentSelection(tournament_size=10, higher_is_better=higher_is_better), 1)] 106 107 self.creators = creators 108 self._pcr = pcr 109 self._operators_sequence = operators_sequence 110 self.population_size = population_size 111 self._selection_methods = selection_methods 112 self.higher_is_better = higher_is_better 113 self.evaluator = evaluator 114 115 self.n_elite = round(elitism_rate * self.population_size) 116 self.individuals = individuals 117 118 def create_subpopulation_individuals(self): 119 if self.individuals is None: 120 # Select one creator to generate individuals, with respect to the creators' probabilities 121 selected_creator = random.choices(self.creators, weights=self._pcr)[ 122 0] # random.choices returns [selected_creator] 123 self.individuals = selected_creator.create_individuals(self.population_size, self.higher_is_better) 124 125 def get_operators_sequence(self): 126 return self._operators_sequence 127 128 def get_selection_methods(self): 129 return self._selection_methods 130 131 def get_best_individual(self): 132 sorted_inds = sorted(self.individuals, key=lambda ind: ind.get_augmented_fitness(), 133 reverse=self.higher_is_better) 134 return sorted_inds[0] 135 136 def get_worst_individual(self): 137 sorted_inds = sorted(self.individuals, key=lambda ind: ind.get_augmented_fitness(), 138 reverse=not self.higher_is_better) 139 return sorted_inds[0] 140 141 def get_average_fitness(self): 142 return np.mean([indiv.get_pure_fitness() for indiv in self.individuals]) 143 144 def contains_individual(self, individual): 145 return individual in self.individuals
class
Subpopulation:
14class Subpopulation: 15 """ 16 Subgroup of the experiment population. 17 18 Contains a specific encoding, fitness evaluation method, creator list, operator sequence and selection methods. 19 20 Parameters 21 ---------- 22 evaluator: IndividualEvaluator 23 fitness evaluation method for the individuals of this sub-population 24 25 creators: Creator or list of Creators, default=None 26 possible creators to generate individuals according to the encoding 27 of this sub-population (GPTrees, Bit Vectors etc.) 28 29 pcr: list of integers, default=None 30 probability mapping for each creator in creators parameter. 31 Length must match the length of creators parameter. 32 33 operators_sequence: list of Crossovers and Mutations, default=None 34 Possible crossover and mutation actions that can change the individuals' representations. 35 The operators will be done sequentially in each generation, by their order in the list. 36 See eckity.genetic_operators for more details on crossover and mutation operators 37 38 selection_methods: list of SelectionMethods 39 Methods for selecting individuals in each generation. 40 See eckity.genetic_operators for more details on selection methods 41 42 elitism_rate: float, default=0.0 43 What percentage of the sub-population's individuals should be kept as elites for the next generation 44 45 population_size: int, default=200 46 The number of individuals in this sub-population. 47 48 individuals: list of Individuals, default=None 49 The individuals list of this sub-population. 50 51 higher_is_better: bool, default=False 52 Determines if the fitness value of this sub-population's individuals should be maximized or minimized. 53 54 Attributes 55 ---------- 56 n_elite: int 57 Number of the sub-population's elite individuals. 58 In every generation, there will be n_elites slots for the elite individuals 59 that will be copied as-is to the next generation. 60 """ 61 62 def __init__(self, 63 evaluator, 64 creators=None, 65 pcr=None, 66 operators_sequence=None, 67 selection_methods=None, 68 elitism_rate=0.0, 69 population_size=200, 70 individuals=None, 71 higher_is_better=False): 72 73 # verify valid creators and creation probability inputs 74 if creators is None: 75 full_cr = FullCreator() 76 creators = [full_cr] 77 elif isinstance(creators, Creator): 78 creators = [creators] 79 elif isinstance(creators, list): 80 if len(creators) == 0: 81 raise ValueError('Creators list cannot be empty') 82 for creator in creators: 83 if not isinstance(creator, Creator): 84 raise ValueError('Detected a non-creator instance as an element in creators list') 85 else: 86 raise ValueError( 87 'Parameter creators must be either a Creator or a list of Creators\n ' 88 'received creators with unexpected type of', type(creators) 89 ) 90 91 if pcr is None: 92 pcr = [1 / len(creators) for _ in creators] 93 94 if len(creators) != len(pcr): 95 raise ValueError(f'Number of creators ({len(creators)}) \ 96 must match number of creation probabilities {(len(pcr))}!') 97 if sum(pcr) != 1: 98 raise ValueError(f'Sum of creation probabilities ({pcr}) must be 1!') 99 100 # set default args 101 if operators_sequence is None: 102 operators_sequence = [SubtreeCrossover(arity=2, probability=0.9), 103 SubtreeMutation(arity=1, probability=0.7), 104 ERCMutation(arity=1, probability=0.1)] 105 if selection_methods is None: 106 selection_methods = [(TournamentSelection(tournament_size=10, higher_is_better=higher_is_better), 1)] 107 108 self.creators = creators 109 self._pcr = pcr 110 self._operators_sequence = operators_sequence 111 self.population_size = population_size 112 self._selection_methods = selection_methods 113 self.higher_is_better = higher_is_better 114 self.evaluator = evaluator 115 116 self.n_elite = round(elitism_rate * self.population_size) 117 self.individuals = individuals 118 119 def create_subpopulation_individuals(self): 120 if self.individuals is None: 121 # Select one creator to generate individuals, with respect to the creators' probabilities 122 selected_creator = random.choices(self.creators, weights=self._pcr)[ 123 0] # random.choices returns [selected_creator] 124 self.individuals = selected_creator.create_individuals(self.population_size, self.higher_is_better) 125 126 def get_operators_sequence(self): 127 return self._operators_sequence 128 129 def get_selection_methods(self): 130 return self._selection_methods 131 132 def get_best_individual(self): 133 sorted_inds = sorted(self.individuals, key=lambda ind: ind.get_augmented_fitness(), 134 reverse=self.higher_is_better) 135 return sorted_inds[0] 136 137 def get_worst_individual(self): 138 sorted_inds = sorted(self.individuals, key=lambda ind: ind.get_augmented_fitness(), 139 reverse=not self.higher_is_better) 140 return sorted_inds[0] 141 142 def get_average_fitness(self): 143 return np.mean([indiv.get_pure_fitness() for indiv in self.individuals]) 144 145 def contains_individual(self, individual): 146 return individual in self.individuals
Subgroup of the experiment population.
Contains a specific encoding, fitness evaluation method, creator list, operator sequence and selection methods.
Parameters
- evaluator (IndividualEvaluator): fitness evaluation method for the individuals of this sub-population
- creators (Creator or list of Creators, default=None): possible creators to generate individuals according to the encoding of this sub-population (GPTrees, Bit Vectors etc.)
- pcr (list of integers, default=None): probability mapping for each creator in creators parameter. Length must match the length of creators parameter.
- operators_sequence (list of Crossovers and Mutations, default=None): Possible crossover and mutation actions that can change the individuals' representations. The operators will be done sequentially in each generation, by their order in the list. See eckity.genetic_operators for more details on crossover and mutation operators
- selection_methods (list of SelectionMethods): Methods for selecting individuals in each generation. See eckity.genetic_operators for more details on selection methods
- elitism_rate (float, default=0.0): What percentage of the sub-population's individuals should be kept as elites for the next generation
- population_size (int, default=200): The number of individuals in this sub-population.
- individuals (list of Individuals, default=None): The individuals list of this sub-population.
- higher_is_better (bool, default=False): Determines if the fitness value of this sub-population's individuals should be maximized or minimized.
Attributes
- n_elite (int): Number of the sub-population's elite individuals. In every generation, there will be n_elites slots for the elite individuals that will be copied as-is to the next generation.
Subpopulation( evaluator, creators=None, pcr=None, operators_sequence=None, selection_methods=None, elitism_rate=0.0, population_size=200, individuals=None, higher_is_better=False)
62 def __init__(self, 63 evaluator, 64 creators=None, 65 pcr=None, 66 operators_sequence=None, 67 selection_methods=None, 68 elitism_rate=0.0, 69 population_size=200, 70 individuals=None, 71 higher_is_better=False): 72 73 # verify valid creators and creation probability inputs 74 if creators is None: 75 full_cr = FullCreator() 76 creators = [full_cr] 77 elif isinstance(creators, Creator): 78 creators = [creators] 79 elif isinstance(creators, list): 80 if len(creators) == 0: 81 raise ValueError('Creators list cannot be empty') 82 for creator in creators: 83 if not isinstance(creator, Creator): 84 raise ValueError('Detected a non-creator instance as an element in creators list') 85 else: 86 raise ValueError( 87 'Parameter creators must be either a Creator or a list of Creators\n ' 88 'received creators with unexpected type of', type(creators) 89 ) 90 91 if pcr is None: 92 pcr = [1 / len(creators) for _ in creators] 93 94 if len(creators) != len(pcr): 95 raise ValueError(f'Number of creators ({len(creators)}) \ 96 must match number of creation probabilities {(len(pcr))}!') 97 if sum(pcr) != 1: 98 raise ValueError(f'Sum of creation probabilities ({pcr}) must be 1!') 99 100 # set default args 101 if operators_sequence is None: 102 operators_sequence = [SubtreeCrossover(arity=2, probability=0.9), 103 SubtreeMutation(arity=1, probability=0.7), 104 ERCMutation(arity=1, probability=0.1)] 105 if selection_methods is None: 106 selection_methods = [(TournamentSelection(tournament_size=10, higher_is_better=higher_is_better), 1)] 107 108 self.creators = creators 109 self._pcr = pcr 110 self._operators_sequence = operators_sequence 111 self.population_size = population_size 112 self._selection_methods = selection_methods 113 self.higher_is_better = higher_is_better 114 self.evaluator = evaluator 115 116 self.n_elite = round(elitism_rate * self.population_size) 117 self.individuals = individuals
def
create_subpopulation_individuals(self):
119 def create_subpopulation_individuals(self): 120 if self.individuals is None: 121 # Select one creator to generate individuals, with respect to the creators' probabilities 122 selected_creator = random.choices(self.creators, weights=self._pcr)[ 123 0] # random.choices returns [selected_creator] 124 self.individuals = selected_creator.create_individuals(self.population_size, self.higher_is_better)