Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/bpzoran/gadapt
Browse files Browse the repository at this point in the history
  • Loading branch information
bpzoran committed May 30, 2024
2 parents b8a4299 + 9960f8e commit 6e5f5a7
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 49 deletions.
15 changes: 8 additions & 7 deletions gadapt/factory/ga_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
from gadapt.operations.cost_finding.base_cost_finder import BaseCostFinder
from gadapt.operations.cost_finding.elitism_cost_finder import ElitismCostFinder
from gadapt.operations.crossover.base_crossover import BaseCrossover
from gadapt.operations.crossover.blending_parent_diversity_crossover import (
BlendingParentDiversityCrossover,
)
from gadapt.operations.exit_check.avg_cost_exit_checker import AvgCostExitChecker
from gadapt.operations.exit_check.base_exit_checker import BaseExitChecker
from gadapt.operations.exit_check.min_cost_exit_checker import MinCostExitChecker
Expand Down Expand Up @@ -118,6 +115,8 @@
from gadapt.operations.population_update.common_population_updater import (
CommonPopulationUpdater,
)
from gadapt.operations.crossover.base_crossover_event_handler import BaseCrossoverEventHandler
from gadapt.operations.crossover.parent_diversity_crossover_event_handler import ParentDiversityCrossoverEventHandler


class GAFactory(BaseGAFactory):
Expand Down Expand Up @@ -515,16 +514,18 @@ def _get_crossover(self) -> BaseCrossover:
for value in mutator_strings
if value in definitions.POPULATION_MUTATION_SELECTION_STRINGS
]
crossover_event_handler: BaseCrossoverEventHandler = BaseCrossoverEventHandler()
if (
not population_mutation_selection_strings
or definitions.PARENT_DIVERSITY in mutator_strings
):
return BlendingParentDiversityCrossover()
crossover_event_handler = ParentDiversityCrossoverEventHandler()

if self._ga.crossover == definitions.BLENDING:
return BlendingCrossover()
return BlendingCrossover(crossover_event_handler)
if self._ga.crossover == definitions.UNIFORM:
return UniformCrossover()
return BlendingParentDiversityCrossover()
return UniformCrossover(crossover_event_handler)
return BlendingCrossover(crossover_event_handler)

def _get_variable_updater(self):
"""
Expand Down
9 changes: 7 additions & 2 deletions gadapt/operations/crossover/base_crossover.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@

from gadapt.ga_model.gene import Gene
from gadapt.ga_model.chromosome import Chromosome
from gadapt.operations.crossover.base_crossover_event_handler import BaseCrossoverEventHandler


class BaseCrossover(ABC):
"""Base Crossover Class"""

def __init__(
self,
event_handler: BaseCrossoverEventHandler

):
self._current_gene_number = -1
self._event_handler = event_handler

def mate(self, chromosome_pairs: List[Tuple[Chromosome, Chromosome]], population):
"""
Expand Down Expand Up @@ -65,6 +69,7 @@ def _mate_pair(
return self._offspring1, self._offspring2

def _cross_genetic_material(self):
self._event_handler.pre_cross_genetic_material()
number_of_genes = len(self._father)
for self._current_gene_number in range(number_of_genes):
self._mother_gene, self._father_gene = self._get_mother_father_genes()
Expand Down Expand Up @@ -174,7 +179,7 @@ def _increase_generation(self):
self._offspring2.last_immigrant_generation = current_generation

def _decision_variable_crossed(self):
pass
self._event_handler.on_decision_variable_crossed(mother_gene=self._mother_gene, father_gene=self._father_gene)

def _all_decision_variable_crossed(self):
pass
self._event_handler.on_all_decision_variable_crossed(offspring1=self._offspring1, offspring2=self._offspring2)
12 changes: 12 additions & 0 deletions gadapt/operations/crossover/base_crossover_event_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class BaseCrossoverEventHandler:
"""
Handles crossover events
"""
def on_decision_variable_crossed(self, *args, **kwargs):
pass

def on_all_decision_variable_crossed(self, *args, **kwargs):
pass

def pre_cross_genetic_material(self, *args, **kwargs):
pass
4 changes: 3 additions & 1 deletion gadapt/operations/crossover/blending_crossover.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import random

from gadapt.operations.crossover.base_crossover import BaseCrossover
from gadapt.operations.crossover.base_crossover_event_handler import BaseCrossoverEventHandler


class BlendingCrossover(BaseCrossover):
Expand All @@ -13,8 +14,9 @@ class BlendingCrossover(BaseCrossover):

def __init__(
self,
event_handler: BaseCrossoverEventHandler
):
super(BlendingCrossover, self).__init__()
super(BlendingCrossover, self).__init__(event_handler)
self._current_gene_number = -1

def _combine(self):
Expand Down
37 changes: 0 additions & 37 deletions gadapt/operations/crossover/blending_parent_diversity_crossover.py

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from gadapt.utils import ga_utils
from gadapt.operations.crossover.base_crossover_event_handler import BaseCrossoverEventHandler


class ParentDiversityCrossoverEventHandler(BaseCrossoverEventHandler):
"""
Handles crossover events using parent diversity mutation.
"""

def __init__(self):
self._genetic_diversity = None

def _get_genetic_diversity(self, mother_gene, father_gene) -> float:
return abs(
mother_gene.variable_value - father_gene.variable_value
) / (
father_gene.decision_variable.max_value
- father_gene.decision_variable.min_value
)

def _get_parent_diversity(self):
return round(ga_utils.average(self._genetic_diversity), 2)

def on_decision_variable_crossed(self, *args, **kwargs):
mother_gene = kwargs.get('mother_gene')
father_gene = kwargs.get('father_gene')
if mother_gene is None or father_gene is None:
return
self._genetic_diversity.append(self._get_genetic_diversity(mother_gene, father_gene))

def on_all_decision_variable_crossed(self, *args, **kwargs):
parent_diversity = self._get_parent_diversity()
offspring1 = kwargs.get('offspring1')
offspring2 = kwargs.get('offspring2')
if offspring1 is None or offspring2 is None:
return
offspring1.parent_diversity = parent_diversity
offspring2.parent_diversity = parent_diversity

def pre_cross_genetic_material(self, *args, **kwargs):
self._genetic_diversity = []
4 changes: 3 additions & 1 deletion gadapt/operations/crossover/uniform_crossover.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Tuple

from gadapt.operations.crossover.base_crossover import BaseCrossover
from gadapt.operations.crossover.base_crossover_event_handler import BaseCrossoverEventHandler


class UniformCrossover(BaseCrossover):
Expand All @@ -11,8 +12,9 @@ class UniformCrossover(BaseCrossover):

def __init__(
self,
event_handler: BaseCrossoverEventHandler
):
super(UniformCrossover, self).__init__()
super(UniformCrossover, self).__init__(event_handler)

def _combine(self) -> Tuple[float, float]:
rnd = random.randint(0, 2)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name="gadapt",
version="0.4.14",
version="0.4.15",
author="Zoran Jankovic",
author_email="[email protected]",
url="https://github.com/bpzoran/gadapt",
Expand Down

0 comments on commit 6e5f5a7

Please sign in to comment.