Skip to content

Commit

Permalink
Objective wrapper in utils. Check if individual has fitness in wrappe…
Browse files Browse the repository at this point in the history
…r. Print progres depending on generation or evaluation
  • Loading branch information
HenrikMettler committed Sep 22, 2020
1 parent 15e5cbc commit 0eeaa62
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 22 deletions.
26 changes: 19 additions & 7 deletions cgp/hl_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ def evolve(
None
"""
if max_generations == np.inf and max_evaluations == np.inf:
raise ('Faulty configuration of evolve parameters: '
'Either max_generations or max_evaluation must be finite, to avoid non terminal evolutionary process')
raise (
"Faulty configuration of evolve parameters: "
"Either max_generations or max_evaluation must be finite, "
"to avoid non terminal evolutionary process"
)

ea.initialize_fitness_parents(pop, objective)
if callback is not None:
Expand All @@ -75,11 +78,20 @@ def evolve(
max_fitness = pop.champion.fitness

if print_progress:
print(
f"\r[{pop.generation + 1}/{max_generations}] max fitness: {max_fitness}\033[K",
end="",
flush=True,
)
if not max_generations == np.inf:
print(
f"\r[{pop.generation + 1}/{max_generations}] max fitness: {max_fitness}\033[K",
end="",
flush=True,
)
elif not max_evaluations == np.inf:
print(
f"\r[{objective.calls}/{max_evaluations}] max fitness: {max_fitness}\033[K",
end="",
flush=True,
)
else:
assert False # should never be reached

if callback is not None:
callback(pop)
Expand Down
25 changes: 24 additions & 1 deletion cgp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import numpy as np

from .individual import IndividualMultiGenome, IndividualSingleGenome
from .individual import IndividualBase, IndividualMultiGenome, IndividualSingleGenome
from .node import Node, primitives_dict


Expand Down Expand Up @@ -201,3 +201,26 @@ def primitives_from_class_names(primitives_str: Tuple[str, ...]) -> Tuple[Type[N
primitives.append(primitives_dict[s])

return tuple(primitives)


def objective(f: Callable[[IndividualBase], IndividualBase]):
""" Wrapper for the objective function.
Wraps the objective function and counts the calls of the function.
Parameters
----------
f: Callable
The objective function.
"""

@functools.wraps(f)
def wrapped(individual: IndividualBase):
if individual.fitness is None:
wrapped.calls += 1
return f(individual)
else:
return individual

wrapped.calls = 0
return wrapped
17 changes: 3 additions & 14 deletions examples/example_minimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import matplotlib.pyplot as plt
import numpy as np
import scipy.constants
import functools
from docopt import docopt

import cgp
Expand All @@ -41,20 +40,9 @@ def f_target(x):
# represented by a given individual and the target function evaluated
# on a set of random points.

def counted(f):
@functools.wraps(f)
def wrapped(*args, **kwargs):
wrapped.calls += 1
return f(*args, **kwargs)
wrapped.calls = 0
return wrapped


@counted
@cgp.utils.objective
def objective(individual):
if individual.fitness is not None:
objective.calls -= 1
return individual

n_function_evaluations = 1000

Expand Down Expand Up @@ -92,7 +80,8 @@ def objective(individual):

ea_params = {"n_offsprings": 4, "tournament_size": 2, "n_processes": 1}

evolve_params = {"max_generations": int(args["--max-generations"]), "min_fitness": 0.0}
evolve_params = {"max_generations": np.inf, "min_fitness": 0.0, "max_evaluations": 1000}
# Todo: change max_generations: int(args["--max-generations"])

# %%
# We create a population that will be evolved
Expand Down

0 comments on commit 0eeaa62

Please sign in to comment.