Evaluate solutions¶
The lifecycle of metaheuristics often requires evaluating a list of solutions on every iteration. In evolutionary algorithms, for example, this list of solutions is known as population.
In order to evaluate a population, NSGA-II (and in general, any generational algorithm in jMetalPy) uses an evaluator object.
Sequential¶
The default evaluator runs in a sequential fashion (i.e., one solution at a time):
from jmetal.util.evaluator import SequentialEvaluator
algorithm = NSGAII(
problem=problem,
population_size=100,
offspring_population_size=100,
...
population_evaluator = SequentialEvaluator(),
)
API¶
SequentialEvaluator
¶
Bases: Evaluator[S]
Cached evaluations¶
EvaluatorWithCache wraps any evaluator and avoids evaluating the same decision variables more
than once. It is useful when each evaluation calls an expensive simulator. Cache misses are passed
to the wrapped evaluator, so the same wrapper works with sequential and parallel evaluators:
from jmetal.util.evaluator import EvaluatorWithCache, MultiprocessEvaluator
evaluator = EvaluatorWithCache(MultiprocessEvaluator(processes=8))
algorithm = NSGAII(
problem=problem,
population_size=100,
offspring_population_size=100,
...
population_evaluator=evaluator,
)
The wrapper restores both objective and constraint values for cached solutions. The algorithm's evaluation counter still advances by the population size, including cache hits, so use a time-based termination criterion when comparing the simulator work saved by caching.
API¶
EvaluatorWithCache(base_evaluator)
¶
Bases: Evaluator[S]
Cache evaluations while delegating cache misses to another evaluator.
The cache key is built from a solution's type and decision variables. Objective and constraint values are copied into the cache, so later mutations of an evaluated solution do not alter cached results. A cache is scoped to one problem instance and is cleared when the evaluator is used with a different problem.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_evaluator
|
Evaluator[S]
|
Evaluator used for solutions that are not already cached. |
required |
Source code in src/jmetal/util/evaluator.py
Parallel¶
Solutions can also be evaluated in parallel, using threads or processes:
from jmetal.util.evaluator import MapEvaluator
from jmetal.util.evaluator import MultiprocessEvaluator
jMetalPy also includes evaluators based on Apache Spark and Dask, useful when a single solution evaluation is itself expensive (e.g. simulation-based problems):
from jmetal.util.evaluator import SparkEvaluator
algorithm = NSGAII(
problem=problem,
population_size=100,
offspring_population_size=100,
...
population_evaluator = SparkEvaluator(processes=8),
)
Or by means of Dask:
from jmetal.util.evaluator import DaskEvaluator
algorithm = NSGAII(
problem=problem,
population_size=100,
offspring_population_size=100,
...
population_evaluator = DaskEvaluator(),
)
Warning
SparkEvaluator and DaskEvaluator require pySpark and Dask, respectively (install via
pip install "jmetalpy[distributed]"). Both currently run against a local Spark/Dask
scheduler (local[n]) — they parallelize evaluation across the cores of one machine, not
across a cluster, regardless of the processes argument.
API¶
MapEvaluator(processes=None)
¶
MultiprocessEvaluator(processes=None)
¶
SparkEvaluator(processes=8)
¶
Bases: Evaluator[S]