Class DefaultEvolutionListener<T extends Comparable<T>>

java.lang.Object
net.bmahe.genetics4j.core.evolutionlisteners.DefaultEvolutionListener<T>
Type Parameters:
T - the type of fitness values, must be Comparable
All Implemented Interfaces:
EvolutionListener<T>

public class DefaultEvolutionListener<T extends Comparable<T>> extends Object implements EvolutionListener<T>
A simple default evolution listener that outputs progress to System.out without requiring external logging dependencies.

This implementation provides basic evolution monitoring by displaying generation information, population size, timestamp, thread information, and the best performing individuals based on fitness comparison. It's designed as a zero-dependency alternative to logging-based listeners for users who want immediate feedback without setting up logging frameworks.

The output format includes:

  • Timestamp and thread name for tracking execution context
  • Generation number and population size
  • Completion status when evolution finishes
  • Top N individuals with their fitness values and genotype representations

Features:

  • Zero external dependencies - uses System.out for output
  • Works with any Comparable fitness type
  • Configurable number of top individuals to display
  • Optional generation skipping for reduced output frequency
  • Customizable genotype pretty-printing
  • Thread-safe implementation
  • Automatic fitness ordering (respects EA configuration's fitness comparator)
  • Custom comparator support for specialized fitness ordering

Example usage:

// Basic usage - shows best individual each generation
EvolutionListener<Double> listener = new DefaultEvolutionListener<>();

// Show top 3 individuals every 10 generations
EvolutionListener<Double> listener = new DefaultEvolutionListener<>(3, 10);

// With custom genotype formatter
EvolutionListener<Double> listener = new DefaultEvolutionListener<>(1,
		0,
		null,
		genotype -> "Custom: " + genotype.toString());

// With custom fitness comparator (e.g., for minimization problems)
EvolutionListener<Double> listener = new DefaultEvolutionListener<>(1, 0, Comparator.reverseOrder(), null);

Thread Safety: This class is thread-safe and can be used in multi-threaded evolutionary algorithm executions. The output includes thread names to help identify concurrent executions.

Performance Considerations: When using generation skipping (skipN > 0), the listener performs minimal work for skipped generations, making it suitable for long-running evolutions where frequent output is not desired.

Since:
4.0.0
See Also:
  • Field Details

  • Constructor Details

    • DefaultEvolutionListener

      public DefaultEvolutionListener()
      Creates a default evolution listener that shows the best individual each generation.
    • DefaultEvolutionListener

      public DefaultEvolutionListener(int topN)
      Creates a default evolution listener that shows the top N individuals each generation.
      Parameters:
      topN - the number of top individuals to display (must be positive)
    • DefaultEvolutionListener

      public DefaultEvolutionListener(int topN, int skipN)
      Creates a default evolution listener with generation skipping.
      Parameters:
      topN - the number of top individuals to display (must be positive)
      skipN - the number of generations to skip between outputs (0 = no skipping)
    • DefaultEvolutionListener

      public DefaultEvolutionListener(int topN, Function<Genotype,String> prettyPrinter)
      Creates a default evolution listener with custom genotype formatting.
      Parameters:
      topN - the number of top individuals to display (must be positive)
      prettyPrinter - function to format genotypes for display (null uses toString())
    • DefaultEvolutionListener

      public DefaultEvolutionListener(int topN, int skipN, Comparator<T> userComparator, Function<Genotype,String> prettyPrinter)
      Creates a fully configurable default evolution listener.
      Parameters:
      topN - the number of top individuals to display (must be positive). If larger than population size, all individuals will be shown.
      skipN - the number of generations to skip between outputs (0 = no skipping). For example, skipN=2 means display every 3rd generation.
      userComparator - custom comparator for fitness values (null uses EA configuration ordering). This allows for custom fitness ordering, such as minimization problems using Comparator.reverseOrder().
      prettyPrinter - function to format genotypes for display (null uses Genotype::toString). Useful for custom genotype representations.
      Throws:
      IllegalArgumentException - if topN is not positive or skipN is negative
  • Method Details

    • preEvaluation

      public void preEvaluation(AbstractEAConfiguration<T> eaConfiguration)

      Initializes the listener with the EA configuration and sets up the fitness comparator for ordering individuals. If a custom comparator was provided during construction, it takes precedence over the EA configuration's comparator.

      Specified by:
      preEvaluation in interface EvolutionListener<T extends Comparable<T>>
      Parameters:
      eaConfiguration - the evolutionary algorithm configuration
      Throws:
      NullPointerException - if eaConfiguration is null
    • onEvolution

      public void onEvolution(long generation, List<Genotype> population, List<T> fitness, boolean isDone)
      Called after each generation to notify about evolution progress.

      This method is invoked by the evolutionary algorithm after each generation has been completed, providing access to the current population state and fitness values. The implementation can use this information for monitoring, logging, or adaptive control.

      The method is called with:

      • Current generation number (starting from 0)
      • Complete population of genotypes for this generation
      • Corresponding fitness values for each individual
      • Flag indicating whether evolution has completed

      Important notes:

      • Population and fitness lists are guaranteed to have the same size
      • Fitness values correspond to genotypes at the same index
      • Data may be shared with the evolution algorithm; avoid modification
      • Method should execute quickly to avoid impacting evolution performance

      Displays evolution progress including timestamp, thread name, generation number, population size, and the top performing individuals. Output is skipped for certain generations if skipN > 0 was configured during construction.

      The method sorts individuals by fitness using the configured comparator and displays up to topN individuals. When evolution is complete (isDone=true), additional completion messages are shown.

      Specified by:
      onEvolution in interface EvolutionListener<T extends Comparable<T>>
      Parameters:
      generation - the current generation number
      population - the current population of genotypes
      fitness - the fitness values corresponding to the population
      isDone - true if this is the final generation
      Throws:
      NullPointerException - if population, fitness, or eaConfiguration is null
      IllegalStateException - if preEvaluation was not called before this method