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		}
class NSGA2Evolution(eckity.algorithms.algorithm.Algorithm):
 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.
NSGA2Evolution( population, statistics=None, breeder=<eckity.breeders.simple_breeder.SimpleBreeder object>, population_evaluator=<eckity.evaluators.simple_population_evaluator.SimplePopulationEvaluator object>, NSGA2FrontSorting=<eckity.multi_objective_evolution.nsga2_front_sorting.NSGA2FrontSorting object>, max_generation=500, events=None, event_names=None, termination_checker=<eckity.termination_checkers.threshold_from_target_termination_checker.ThresholdFromTargetTerminationChecker object>, max_workers=None, random_generator=None, random_seed=1688113158.9442189, generation_seed=None, best_of_run_=None, best_of_run_evaluator=None, best_of_gen=None, worst_of_gen=None, generation_num=0)
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
termination_checker
best_of_run_
best_of_run_evaluator
best_of_gen
worst_of_gen
max_generation
final_generation_
NSGA2FrontSorting
@overrides
def generation_iteration(self, gen):
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.
def initialize(self):
 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

def execute(self, **kwargs):
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.
@overrides
def finish(self):
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

def event_name_to_data(self, event_name):
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