Skip to content

Commit

Permalink
Removed type errors
Browse files Browse the repository at this point in the history
  • Loading branch information
alcides committed Feb 9, 2024
1 parent c835fe4 commit f047262
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 259 deletions.
83 changes: 39 additions & 44 deletions examples/binary.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
from abc import ABC
from copy import deepcopy
import copy
from dataclasses import dataclass
from typing import Annotated
from geneticengine.algorithms.gp.operators.combinators import ParallelStep
from geneticengine.algorithms.gp.operators.crossover import GenericCrossoverStep
from geneticengine.algorithms.gp.operators.elitism import ElitismStep
from geneticengine.algorithms.gp.operators.mutation import GenericMutationStep
from geneticengine.evaluation import Evaluator
from geneticengine.evaluation.budget import AnyOf, TargetFitness, TimeBudget
from geneticengine.problems import Problem, SingleObjectiveProblem
from geneticengine.random.sources import NativeRandomSource, RandomSource
from geneticengine.representations.api import CrossoverOperator, MutationOperator, Representation
from geneticengine.problems import SingleObjectiveProblem
from geneticengine.random.sources import NativeRandomSource

from geneticengine.grammar.metahandlers.lists import ListSizeBetween
from geneticengine.grammar.grammar import extract_grammar
from geneticengine.representations.tree.treebased import (
TreeBasedRepresentation,
random_node,
)
from geneticengine.algorithms.gp.gp import GeneticProgramming

Expand Down Expand Up @@ -60,46 +55,46 @@ def fitness(i: BinaryList):
minimize=False,
)

class BitFlip(MutationOperator[BinaryList]):
def mutate(
self,
genotype: BinaryList,
problem: Problem,
evaluator: Evaluator,
representation: Representation,
random_source: RandomSource,
index_in_population: int,
generation: int,
) -> BinaryList:
assert isinstance(genotype, BinaryList)
random_pos = random_source.randint(0, SIZE - 1)
next_val = random_node(r=random_source, g=g, max_depth=1, starting_symbol=Bit)
copy = deepcopy(genotype)
copy.byte[random_pos] = next_val
return copy

class SinglePointCrossover(CrossoverOperator[BinaryList]):
def crossover(
self,
g1: BinaryList,
g2: BinaryList,
problem: Problem,
representation: Representation,
random_source: RandomSource,
index_in_population: int,
generation: int,
) -> tuple[BinaryList, BinaryList]:
p = random_source.randint(0, len(g1.byte))
p1 = copy.deepcopy(g1.byte[:p])
q1 = copy.deepcopy(g2.byte[:p])
p2 = copy.deepcopy(g2.byte[: len(g2.byte) - p])
q2 = copy.deepcopy(g1.byte[: len(g1.byte) - p])
return (BinaryList(byte=p1 + p2), BinaryList(byte=q1 + q2))
# class BitFlip(MutationOperator[BinaryList]):
# def mutate(
# self,
# genotype: BinaryList,
# problem: Problem,
# evaluator: Evaluator,
# representation: Representation,
# random_source: RandomSource,
# index_in_population: int,
# generation: int,
# ) -> BinaryList:
# assert isinstance(genotype, BinaryList)
# random_pos = random_source.randint(0, SIZE - 1)
# next_val = random_node(r=random_source, g=g, max_depth=1, starting_symbol=Bit)
# copy = deepcopy(genotype)
# copy.byte[random_pos] = next_val
# return copy

# class SinglePointCrossover(CrossoverOperator[BinaryList]):
# def crossover(
# self,
# g1: BinaryList,
# g2: BinaryList,
# problem: Problem,
# representation: Representation,
# random_source: RandomSource,
# index_in_population: int,
# generation: int,
# ) -> tuple[BinaryList, BinaryList]:
# p = random_source.randint(0, len(g1.byte))
# p1 = copy.deepcopy(g1.byte[:p])
# q1 = copy.deepcopy(g2.byte[:p])
# p2 = copy.deepcopy(g2.byte[: len(g2.byte) - p])
# q2 = copy.deepcopy(g1.byte[: len(g1.byte) - p])
# return (BinaryList(byte=p1 + p2), BinaryList(byte=q1 + q2))

step = ParallelStep(
[
GenericMutationStep(probability=0.5, operator=BitFlip()),
GenericCrossoverStep(probability=0.5, operator=SinglePointCrossover()),
GenericMutationStep(probability=0.5), # TODO: , operator=BitFlip()),
GenericCrossoverStep(probability=0.5), # TODO:, operator=SinglePointCrossover()),
ElitismStep(),
],
weights=[5, 4, 1],
Expand Down
2 changes: 1 addition & 1 deletion examples/pcfg_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ def count(xs):
d[x] += 1
return d

print(count([x.genotype.__class__ for x in alg.final_population]))
print(count(ind.genotype.__class__))
6 changes: 3 additions & 3 deletions geml/regressors.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from geneticengine.grammar.grammar import extract_grammar
from geneticengine.problems import SingleObjectiveProblem
from geneticengine.random.sources import NativeRandomSource
from geneticengine.representations.api import Representation
from geneticengine.representations.api import SolutionRepresentation
from geneticengine.representations.tree.treebased import TreeBasedRepresentation
from geml.grammars.basic_math import SafeDiv
from geml.grammars.basic_math import SafeLog
Expand Down Expand Up @@ -55,7 +55,7 @@ class GeneticProgrammingRegressor(BaseEstimator, TransformerMixin):
def __init__(
self,
nodes: list[type[Number]] | None = None,
representation: type[Representation] = TreeBasedRepresentation,
representation: type[SolutionRepresentation] = TreeBasedRepresentation,
population_size: int = 200,
n_elites: int = 5,
n_novelties: int = 10,
Expand Down Expand Up @@ -230,7 +230,7 @@ def __init__(
SafeSqrt,
*exp_literals,
], # "type: ignore"
representation_class: type[Representation] = TreeBasedRepresentation,
representation_class: type[SolutionRepresentation] = TreeBasedRepresentation,
population_size: int = 200,
number_of_generations: int = 100,
max_depth: int = 15,
Expand Down
18 changes: 8 additions & 10 deletions geneticengine/algorithms/gp/cooperativegp.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from geneticengine.problems import SingleObjectiveProblem
from geneticengine.random.sources import NativeRandomSource, RandomSource
from geneticengine.representations.api import Representation
from geneticengine.representations.api import SolutionRepresentation
from geneticengine.representations.tree.operators import InjectInitialPopulationWrapper
from geneticengine.representations.tree.treebased import TreeBasedRepresentation

Expand All @@ -32,8 +32,8 @@ def __init__(
grammar1: Grammar,
grammar2: Grammar,
function: Callable[[a, b], float],
representation1: Optional[Representation] = None,
representation2: Optional[Representation] = None,
representation1: Optional[SolutionRepresentation] = None,
representation2: Optional[SolutionRepresentation] = None,
population1_size: int = 100,
population2_size: int = 200,
coevolutions: int = 1000,
Expand Down Expand Up @@ -69,7 +69,7 @@ def __init__(
self.kwargs2 = kwargs2 or {}
self.random_source = random_source or NativeRandomSource()

def evolve(self) -> tuple[a, b]:
def search(self) -> tuple[a, b]:
@dataclass
class Bests:
b1: a
Expand Down Expand Up @@ -102,30 +102,28 @@ def f2(x: b) -> float:
gp1 = GeneticProgramming(
problem=p1,
representation=self.representation1,
random_source=self.random_source,
random=self.random_source,
population_size=self.population1_size,
initializer=InjectInitialPopulationWrapper(
population_initializer=InjectInitialPopulationWrapper(
[e.get_phenotype() for e in pop1],
init,
), # TODO: we might want to keep individuals, and not only the phenotypes.
**self.kwargs1,
)
ind = gp1.search()
self.bests.b1 = ind.get_phenotype()
pop1 = gp1.final_population
print("DATASET:", ind.get_fitness(p1))

gp2 = GeneticProgramming(
problem=p2,
representation=self.representation2,
random_source=self.random_source,
random=self.random_source,
population_size=self.population2_size,
initializer=InjectInitialPopulationWrapper([e.get_phenotype() for e in pop2], init),
population_initializer=InjectInitialPopulationWrapper([e.get_phenotype() for e in pop2], init),
**self.kwargs2,
)
ind = gp2.search()
self.bests.b2 = ind.get_phenotype()
pop2 = gp2.final_population
print("____________ Explanation:", ind.get_fitness(p2), ind.get_phenotype())

return (self.bests.b1, self.bests.b2)
4 changes: 2 additions & 2 deletions geneticengine/algorithms/gp/multipopulationgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def search(self) -> Individual:
for pop_size, initializer in zip(self.population_sizes, self.population_initializers)
]

self.tracker.evaluate(flatten(populations))
self.tracker.evaluate(list(flatten(populations)))

while not self.is_done():
generation += 1
Expand All @@ -122,7 +122,7 @@ def search(self) -> Individual:
)
for population, population_size in zip(populations, self.population_sizes)
]
self.tracker.evaluate(flatten(populations))
self.tracker.evaluate(list(flatten(populations)))

if self.migration_size > 0 and self.migration_step is not None:
for i, pop in enumerate(populations):
Expand Down
4 changes: 2 additions & 2 deletions geneticengine/algorithms/gp/operators/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from geneticengine.problems.helpers import sort_population
from geneticengine.problems import Problem
from geneticengine.random.sources import RandomSource
from geneticengine.representations.api import Representation
from geneticengine.representations.api import SolutionRepresentation
from geneticengine.evaluation import Evaluator


Expand All @@ -14,7 +14,7 @@ def iterate(
self,
problem: Problem,
evaluator: Evaluator,
representation: Representation,
representation: SolutionRepresentation,
random_source: RandomSource,
population: list[Individual],
target_size: int,
Expand Down
10 changes: 3 additions & 7 deletions geneticengine/algorithms/gp/simplegp.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def __init__(

if force_individual:
population_initializer = InjectInitialPopulationWrapper(
[representation_instance.phenotype_to_genotype(force_individual)],
[representation_instance.map(force_individual)],
population_initializer,
)

Expand All @@ -192,24 +192,20 @@ def __init__(

step: GeneticStep

mutation_operator = representation_instance.get_mutation()
crossover_operator = representation_instance.get_crossover()
if either_mut_or_cro is not None:
mutation_step = GenericMutationStep(
1,
operator=mutation_operator,
)
crossover_step = GenericCrossoverStep(1, operator=crossover_operator)
crossover_step = GenericCrossoverStep(1) # , operator=crossover_operator
step = ExclusiveParallelStep(
[mutation_step, crossover_step],
[either_mut_or_cro, 1 - either_mut_or_cro],
)
else:
mutation_step = GenericMutationStep(
probability_mutation,
operator=mutation_operator,
)
crossover_step = GenericCrossoverStep(probability_crossover, operator=crossover_operator)
crossover_step = GenericCrossoverStep(probability_crossover) # , operator=crossover_operator
step = SequenceStep(mutation_step, crossover_step)

selection_step: GeneticStep
Expand Down
4 changes: 2 additions & 2 deletions geneticengine/evaluation/budget.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ def __init__(self, targets: list[float]):
self.targets = targets

def is_done(self, tracker: SingleObjectiveProgressTracker): # TODO: MultiObjective?
comps = tracker.get_best_individual().get_fitness().fitness_components
return all(abs(c - self.v) < 0.001 for v, c in zip(self.targets, comps))
comps = tracker.get_best_individual().get_fitness(tracker.get_problem()).fitness_components
return all(abs(c - v) < 0.001 for v, c in zip(self.targets, comps))
8 changes: 1 addition & 7 deletions geneticengine/representations/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,10 @@ def initialize(
random_source: RandomSource,
target_size: int,
) -> list[Individual]:
def bound(i: int):
interval = (representation.max_depth - representation.min_depth) + 1
v = representation.min_depth + (i % interval)
return v

return [
Individual(
representation.instantiate(
r=random_source,
depth=bound(i),
random=random_source,
),
genotype_to_phenotype=representation.map,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
InitializationMethodType,
)
from geneticengine.representations.tree.initializations import pi_grow_method
from geneticengine.representations.tree.treebased import random_individual, random_node
from geneticengine.representations.tree.treebased import random_node
from geneticengine.solutions.tree import TreeNode
from geneticengine.grammar.utils import get_arguments
from geneticengine.grammar.utils import is_generic
Expand Down Expand Up @@ -293,7 +293,11 @@ def mutate(self, random: RandomSource, internal: Genotype, **kwargs) -> Genotype
return Genotype(dna)

def crossover(
self, random: RandomSource, parent1: Genotype, parent2: Genotype, **kwargs,
self,
random: RandomSource,
parent1: Genotype,
parent2: Genotype,
**kwargs,
) -> tuple[Genotype, Genotype]:
keys = parent1.dna.keys()

Expand Down
Loading

0 comments on commit f047262

Please sign in to comment.