eckity.multi_objective_evolution.nsga2_evolution
1from time import time 2from overrides import overrides 3 4from eckity.algorithms.algorithm import Algorithm 5from eckity.breeders.simple_breeder import SimpleBreeder 6from eckity.evaluators.simple_population_evaluator import SimplePopulationEvaluator 7from eckity.multi_objective_evolution.nsga2_front_sorting import NSGA2FrontSorting 8 9from eckity.termination_checkers.threshold_from_target_termination_checker \ 10 import ThresholdFromTargetTerminationChecker 11 12 13class NSGA2Evolution(Algorithm): 14 def __init__(self, 15 population, 16 statistics=None, 17 breeder=SimpleBreeder(), 18 population_evaluator=SimplePopulationEvaluator(), 19 NSGA2FrontSorting=NSGA2FrontSorting(), 20 max_generation=500, 21 events=None, 22 event_names=None, 23 termination_checker=ThresholdFromTargetTerminationChecker(threshold=0), 24 max_workers=None, 25 random_generator=None, 26 random_seed=time(), 27 generation_seed=None, 28 best_of_run_=None, 29 best_of_run_evaluator=None, 30 best_of_gen=None, 31 worst_of_gen=None, 32 generation_num=0): 33 34 if event_names is None: 35 _event_names = ['before_eval', 'after_eval', 'before_breeding', 'after_breeding'] 36 else: 37 _event_names = event_names 38 39 if statistics is None: 40 statistics = [] 41 42 super().__init__(population, statistics=statistics, breeder=breeder, population_evaluator=population_evaluator, 43 events=events, event_names=_event_names, max_workers=max_workers, 44 random_generator=random_generator, random_seed=random_seed, generation_seed=generation_seed, 45 termination_checker=termination_checker, generation_num=generation_num) 46 47 self.termination_checker = termination_checker 48 self.best_of_run_ = best_of_run_ 49 self.best_of_run_evaluator = best_of_run_evaluator 50 self.best_of_gen = best_of_gen 51 self.worst_of_gen = worst_of_gen 52 self.max_generation = max_generation 53 54 self.final_generation_ = None 55 self.NSGA2FrontSorting = NSGA2FrontSorting 56 57 # 58 @overrides 59 def generation_iteration(self, gen): 60 """ 61 Performs one iteration of the evolutionary run, for the current generation 62 63 Parameters 64 ---------- 65 gen: 66 current generation number (for example, generation #100) 67 68 Returns 69 ------- 70 None. 71 """ 72 73 # breed population 74 self.breeder.breed(self.population) 75 # Evaluate the entire population and get the best individual 76 77 self.population_evaluator.act(self.population) 78 79 self.NSGA2FrontSorting.select_for_population(self.population) 80 self.best_of_gen = self._get_pareto_fronts() 81 82 def _get_pareto_fronts(self): 83 ''' 84 Returns: the pareto front for each sub_population 85 ------- 86 ''' 87 pareto_fronts = [] 88 for sub_pop in self.population.sub_populations: 89 pareto_fronts.append([ind for ind in sub_pop.individuals if ind.fitness.front_rank == 1]) 90 return pareto_fronts 91 92 def initialize(self): 93 """ 94 Initialize the evolutionary algorithm 95 96 Register statistics to `after_generation` event 97 """ 98 super().initialize() 99 for stat in self.statistics: 100 self.register('after_generation', stat.write_statistics) 101 102 def execute(self, **kwargs): 103 """ 104 Compute output using best evolved individual. 105 Use `execute` in a non-sklearn setting. 106 Input keyword arguments that set variable values. 107 For example if `terminal_set=['x', 'y', 1, -1]` then call `execute(x=..., y=...)`. 108 109 Parameters 110 ---------- 111 **kwargs : keyword arguments 112 The input to the program (tree). 113 114 Returns 115 ------- 116 object 117 Output as computed by the best individual of the evolutionary run. 118 119 """ 120 return self.best_of_run_.execute(**kwargs) 121 122 @overrides 123 def finish(self): 124 """ 125 Finish the evolutionary run by showing the best individual and printing the best fitness 126 """ 127 self.best_of_run_.show() 128 print(self.best_of_run_.get_pure_fitness()) 129 130 def event_name_to_data(self, event_name): 131 if event_name == "init": 132 return { 133 "population": self.population, 134 "statistics": self.statistics, 135 "breeder": self.breeder, 136 "termination_checker": self.termination_checker, 137 "max_generation": self.max_generation, 138 "events": self.events, 139 "max_workers": self.max_workers 140 } 141 142 # default case 143 return { 144 "population": self.population, 145 "best_of_run_": self.best_of_run_, 146 "best_of_gen": self.best_of_gen, 147 "generation_num": self.generation_num 148 }
14class NSGA2Evolution(Algorithm): 15 def __init__(self, 16 population, 17 statistics=None, 18 breeder=SimpleBreeder(), 19 population_evaluator=SimplePopulationEvaluator(), 20 NSGA2FrontSorting=NSGA2FrontSorting(), 21 max_generation=500, 22 events=None, 23 event_names=None, 24 termination_checker=ThresholdFromTargetTerminationChecker(threshold=0), 25 max_workers=None, 26 random_generator=None, 27 random_seed=time(), 28 generation_seed=None, 29 best_of_run_=None, 30 best_of_run_evaluator=None, 31 best_of_gen=None, 32 worst_of_gen=None, 33 generation_num=0): 34 35 if event_names is None: 36 _event_names = ['before_eval', 'after_eval', 'before_breeding', 'after_breeding'] 37 else: 38 _event_names = event_names 39 40 if statistics is None: 41 statistics = [] 42 43 super().__init__(population, statistics=statistics, breeder=breeder, population_evaluator=population_evaluator, 44 events=events, event_names=_event_names, max_workers=max_workers, 45 random_generator=random_generator, random_seed=random_seed, generation_seed=generation_seed, 46 termination_checker=termination_checker, generation_num=generation_num) 47 48 self.termination_checker = termination_checker 49 self.best_of_run_ = best_of_run_ 50 self.best_of_run_evaluator = best_of_run_evaluator 51 self.best_of_gen = best_of_gen 52 self.worst_of_gen = worst_of_gen 53 self.max_generation = max_generation 54 55 self.final_generation_ = None 56 self.NSGA2FrontSorting = NSGA2FrontSorting 57 58 # 59 @overrides 60 def generation_iteration(self, gen): 61 """ 62 Performs one iteration of the evolutionary run, for the current generation 63 64 Parameters 65 ---------- 66 gen: 67 current generation number (for example, generation #100) 68 69 Returns 70 ------- 71 None. 72 """ 73 74 # breed population 75 self.breeder.breed(self.population) 76 # Evaluate the entire population and get the best individual 77 78 self.population_evaluator.act(self.population) 79 80 self.NSGA2FrontSorting.select_for_population(self.population) 81 self.best_of_gen = self._get_pareto_fronts() 82 83 def _get_pareto_fronts(self): 84 ''' 85 Returns: the pareto front for each sub_population 86 ------- 87 ''' 88 pareto_fronts = [] 89 for sub_pop in self.population.sub_populations: 90 pareto_fronts.append([ind for ind in sub_pop.individuals if ind.fitness.front_rank == 1]) 91 return pareto_fronts 92 93 def initialize(self): 94 """ 95 Initialize the evolutionary algorithm 96 97 Register statistics to `after_generation` event 98 """ 99 super().initialize() 100 for stat in self.statistics: 101 self.register('after_generation', stat.write_statistics) 102 103 def execute(self, **kwargs): 104 """ 105 Compute output using best evolved individual. 106 Use `execute` in a non-sklearn setting. 107 Input keyword arguments that set variable values. 108 For example if `terminal_set=['x', 'y', 1, -1]` then call `execute(x=..., y=...)`. 109 110 Parameters 111 ---------- 112 **kwargs : keyword arguments 113 The input to the program (tree). 114 115 Returns 116 ------- 117 object 118 Output as computed by the best individual of the evolutionary run. 119 120 """ 121 return self.best_of_run_.execute(**kwargs) 122 123 @overrides 124 def finish(self): 125 """ 126 Finish the evolutionary run by showing the best individual and printing the best fitness 127 """ 128 self.best_of_run_.show() 129 print(self.best_of_run_.get_pure_fitness()) 130 131 def event_name_to_data(self, event_name): 132 if event_name == "init": 133 return { 134 "population": self.population, 135 "statistics": self.statistics, 136 "breeder": self.breeder, 137 "termination_checker": self.termination_checker, 138 "max_generation": self.max_generation, 139 "events": self.events, 140 "max_workers": self.max_workers 141 } 142 143 # default case 144 return { 145 "population": self.population, 146 "best_of_run_": self.best_of_run_, 147 "best_of_gen": self.best_of_gen, 148 "generation_num": self.generation_num 149 }
Evolutionary algorithm to be executed.
Abstract Algorithm that can be extended to concrete algorithms such as SimpleAlgorithm.
Parameters
----------
population: Population
The population to be evolved. Consists of a list of individuals.
statistics: Statistics or list of Statistics, default=None
Provide multiple statistics on the population during the evolutionary run.
breeder: Breeder, default=SimpleBreeder() Responsible for applying the selection method and operator sequence on the individuals in each generation. Applies on one sub-population in simple case.
population_evaluator: PopulationEvaluator, default=SimplePopulationEvaluator() Responsible for evaluating each individual's fitness concurrently and returns the best individual of each subpopulation (returns a single individual in simple case).
max_generation: int, default=1000
Maximal number of generations to run the evolutionary process.
Note the evolution could end before reaching max_generation,
depends on the termination checker.
Note that there are max_generation + 1 (at max) fitness calculations,
but only max_generation (at max) of selection
events: dict(str, dict(object, function)), default=None
Dictionary of events, where each event holds a dictionary of (subscriber, callback method).
event_names: list of strings, default=None
Names of events to publish during the evolution.
termination_checker: TerminationChecker or a list of TerminationCheckers, default=ThresholdFromTargetTerminationChecker() Responsible for checking if the algorithm should finish before reaching max_generation.
max_workers: int, default=None
Maximal number of worker nodes for the Executor object
that evaluates the fitness of the individuals.
random_generator: module, default=random
Random generator module.
random_seed: float or int, default=current system time
Random seed for deterministic experiment.
generation_seed: int, default=None
Current generation seed. Useful for resuming a previously paused experiment.
generation_num: int, default=0
Current generation number
Attributes
----------
final_generation_: int
The generation in which the evolution ended.
15 def __init__(self, 16 population, 17 statistics=None, 18 breeder=SimpleBreeder(), 19 population_evaluator=SimplePopulationEvaluator(), 20 NSGA2FrontSorting=NSGA2FrontSorting(), 21 max_generation=500, 22 events=None, 23 event_names=None, 24 termination_checker=ThresholdFromTargetTerminationChecker(threshold=0), 25 max_workers=None, 26 random_generator=None, 27 random_seed=time(), 28 generation_seed=None, 29 best_of_run_=None, 30 best_of_run_evaluator=None, 31 best_of_gen=None, 32 worst_of_gen=None, 33 generation_num=0): 34 35 if event_names is None: 36 _event_names = ['before_eval', 'after_eval', 'before_breeding', 'after_breeding'] 37 else: 38 _event_names = event_names 39 40 if statistics is None: 41 statistics = [] 42 43 super().__init__(population, statistics=statistics, breeder=breeder, population_evaluator=population_evaluator, 44 events=events, event_names=_event_names, max_workers=max_workers, 45 random_generator=random_generator, random_seed=random_seed, generation_seed=generation_seed, 46 termination_checker=termination_checker, generation_num=generation_num) 47 48 self.termination_checker = termination_checker 49 self.best_of_run_ = best_of_run_ 50 self.best_of_run_evaluator = best_of_run_evaluator 51 self.best_of_gen = best_of_gen 52 self.worst_of_gen = worst_of_gen 53 self.max_generation = max_generation 54 55 self.final_generation_ = None 56 self.NSGA2FrontSorting = NSGA2FrontSorting
59 @overrides 60 def generation_iteration(self, gen): 61 """ 62 Performs one iteration of the evolutionary run, for the current generation 63 64 Parameters 65 ---------- 66 gen: 67 current generation number (for example, generation #100) 68 69 Returns 70 ------- 71 None. 72 """ 73 74 # breed population 75 self.breeder.breed(self.population) 76 # Evaluate the entire population and get the best individual 77 78 self.population_evaluator.act(self.population) 79 80 self.NSGA2FrontSorting.select_for_population(self.population) 81 self.best_of_gen = self._get_pareto_fronts()
Performs one iteration of the evolutionary run, for the current generation
Parameters
- gen:: current generation number (for example, generation #100)
Returns
- None.
93 def initialize(self): 94 """ 95 Initialize the evolutionary algorithm 96 97 Register statistics to `after_generation` event 98 """ 99 super().initialize() 100 for stat in self.statistics: 101 self.register('after_generation', stat.write_statistics)
Initialize the evolutionary algorithm
Register statistics to after_generation
event
103 def execute(self, **kwargs): 104 """ 105 Compute output using best evolved individual. 106 Use `execute` in a non-sklearn setting. 107 Input keyword arguments that set variable values. 108 For example if `terminal_set=['x', 'y', 1, -1]` then call `execute(x=..., y=...)`. 109 110 Parameters 111 ---------- 112 **kwargs : keyword arguments 113 The input to the program (tree). 114 115 Returns 116 ------- 117 object 118 Output as computed by the best individual of the evolutionary run. 119 120 """ 121 return self.best_of_run_.execute(**kwargs)
Compute output using best evolved individual.
Use execute
in a non-sklearn setting.
Input keyword arguments that set variable values.
For example if terminal_set=['x', 'y', 1, -1]
then call execute(x=..., y=...)
.
Parameters
- **kwargs (keyword arguments): The input to the program (tree).
Returns
- object: Output as computed by the best individual of the evolutionary run.
123 @overrides 124 def finish(self): 125 """ 126 Finish the evolutionary run by showing the best individual and printing the best fitness 127 """ 128 self.best_of_run_.show() 129 print(self.best_of_run_.get_pure_fitness())
Finish the evolutionary run by showing the best individual and printing the best fitness
131 def event_name_to_data(self, event_name): 132 if event_name == "init": 133 return { 134 "population": self.population, 135 "statistics": self.statistics, 136 "breeder": self.breeder, 137 "termination_checker": self.termination_checker, 138 "max_generation": self.max_generation, 139 "events": self.events, 140 "max_workers": self.max_workers 141 } 142 143 # default case 144 return { 145 "population": self.population, 146 "best_of_run_": self.best_of_run_, 147 "best_of_gen": self.best_of_gen, 148 "generation_num": self.generation_num 149 }
Convert a given event name to relevant data of the Algorithm for the event
Parameters
- event_name (string): name of the event that is happening
Returns
- dict: Algorithm data regarding the given event