Skip to content

Commit

Permalink
add operations history
Browse files Browse the repository at this point in the history
  • Loading branch information
MangaBoba committed Mar 12, 2024
1 parent 3bafcaa commit d704780
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 8 deletions.
11 changes: 10 additions & 1 deletion gefest/core/configs/optimization_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from golem.core.optimisers.adaptive.operator_agent import MutationAgentTypeEnum
from golem.core.optimisers.genetic.operators.inheritance import GeneticSchemeTypesEnum
from golem.core.optimisers.genetic.operators.selection import SelectionTypesEnum
from loguru import logger
from pydantic import BaseModel, ConfigDict, model_validator

from gefest.core.configs.tuner_params import TunerParams
Expand Down Expand Up @@ -96,7 +97,7 @@ class OptimizationParams(BaseModel):
moead_multi_objective_selector_neighbors: int = 2
"""Parameter used in moead selector."""

optimizer: ValidOptimizer = 'gefest_ga'
optimizer: Optional[ValidOptimizer] = 'gefest_ga'
"""Optimizer."""

pair_selector: Callable = panmixis
Expand Down Expand Up @@ -207,6 +208,14 @@ def create_classes_instances(self):
"""Selects and initializes specified modules."""
if isinstance(self.optimizer, str):
self.optimizer = getattr(OptimizerTypes, self.optimizer).value
elif self.optimizer is None:
logger.warning('Optimizer not provided.')

if len(self.crossover_each_prob) != len(self.crossovers):
raise ValueError('Mismatch number of crossovers and probs.')

if len(self.mutation_each_prob) != len(self.mutations):
raise ValueError('Mismatch number of mutations and probs.')

if isinstance(self.postprocess_rules[0], str):
self.postprocess_rules = [getattr(Rules, name).value for name in self.postprocess_rules]
Expand Down
3 changes: 3 additions & 0 deletions gefest/core/geometry/datastructs/point.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class Point:
x: float
y: float

def __hash__(self) -> int:
return hash((self.x, self.y))

@computed_field(repr=False)
def coords(self) -> list[float]:
"""List coordinates representation."""
Expand Down
3 changes: 3 additions & 0 deletions gefest/core/geometry/datastructs/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class Polygon:
points: list[Point] = Field(default_factory=list)
id_: Optional[Union[UUID, PolyID]] = Field(default_factory=uuid4)

def __hash__(self) -> int:
return hash((self.id_, *self.points))

def __len__(self) -> int:
return len(self.points)

Expand Down
17 changes: 16 additions & 1 deletion gefest/core/geometry/datastructs/structure.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Union
from typing import Any, Union
from uuid import UUID, uuid4

from pydantic import Field
Expand All @@ -17,6 +17,9 @@ class Structure:
extra_characteristics: dict = Field(default_factory=dict)
id_: UUID = Field(default_factory=uuid4)

def __hash__(self) -> int:
return hash((self.id_, *self.polygons, *self.fitness))

def __len__(self):
return len(self.polygons)

Expand All @@ -35,6 +38,7 @@ def __setitem__(self, key, value):
if polygons[key] != value:
polygons[key] = value
self.polygons = tuple(polygons)
self.id_ = uuid4()

def __getitem__(self, key):
return self.polygons[key]
Expand All @@ -57,3 +61,14 @@ def remove(self, value):
polygons = list(self.polygons)
polygons.remove(value)
self.polygons = tuple(polygons)

def set_extra(self, field: str, data: Any):
"""Add any extra information."""
if field in self.extra_characteristics.keys():
self.extra_characteristics[field].append(data)
else:
self.extra_characteristics[field] = [data]

def clear_extra(self):
"""Clear all extra information."""
self.extra_characteristics = {}
14 changes: 10 additions & 4 deletions gefest/core/opt/operators/crossovers.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,16 @@ def crossover_structures(
size=1,
p=operations_probs,
)
new_structure = chosen_crossover[0](s1, s2, domain)
if not new_structure:
new_structures = chosen_crossover[0](s1, s2, domain)
if not new_structures:
logger.warning(f'None out: {chosen_crossover[0].__name__}')
else:
for child in new_structures:
child.clear_extra()
child.set_extra('crossover', (chosen_crossover[0].__name__))
child.set_extra('parents', (structure1.id_, structure2.id_))

return new_structure
return new_structures


# pairs for crossover selection
Expand Down Expand Up @@ -83,7 +88,7 @@ def structure_level_crossover(
result = list(copy.deepcopy(part_1))
result.extend(copy.deepcopy(part_2))

new_structure = Structure(polygons=result)
new_structure = Structure(polygons=result, parent='structure_level_crossover')

return (new_structure,)

Expand Down Expand Up @@ -142,6 +147,7 @@ def polygon_level_crossover(

idx_ = where(s1.polygons, lambda p: p == poly_1)[0]
s1[idx_] = new_poly
s1.parent = 'polygon_level_crossover'
return (s1,)


Expand Down
6 changes: 5 additions & 1 deletion gefest/core/opt/operators/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ def mutate_structure(
size=1,
p=operations_probs,
)
new_structure = chosen_mutation[0](new_structure, domain, idx_)
new_structure = chosen_mutation[0](copy.deepcopy(new_structure), domain, idx_)

if not new_structure:
logger.warning(f'None out: {chosen_mutation[0].__name__}')
else:
new_structure.set_extra('mutations', (idx_, chosen_mutation[0].__name__))

new_structure.set_extra('parents', structure.id_)
return new_structure


Expand Down
4 changes: 3 additions & 1 deletion gefest/tools/optimizers/GA/GA.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(
if len(self.opt_params.objectives) > 1:
if self.opt_params.multiobjective_selector.__name__ == 'MOEAD':
self.opt_params.extra = 0
logger.warning('For moead extra not available.')
logger.warning('Extra not available for moead.')

self.selector = self.opt_params.multiobjective_selector(
single_demention_selection=self.selector,
Expand All @@ -72,8 +72,10 @@ def optimize(self) -> list[Structure]:
mutated_child = self.mutation(child)
self._pop.extend(mutated_child)
self._pop.extend(self.sampler(self.opt_params.extra))
self._pop = list(set(self._pop))
self._pop = self.objectives_evaluator(self._pop)
self.log_dispatcher.log_pop(self._pop, str(step + 1))

self._pop = self.selector(self._pop, self.pop_size)
pbar.set_description(f'Best fitness: {self._pop[0].fitness}')
return self._pop

0 comments on commit d704780

Please sign in to comment.