EvolutionListenerLogTopN.java
package net.bmahe.genetics4j.core.evolutionlisteners;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.IntStream;
import org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.Logger;
import net.bmahe.genetics4j.core.Genotype;
public class EvolutionListenerLogTopN<T extends Comparable<T>> implements EvolutionListener<T> {
private final Logger logger;
private final int topN;
private final int skipN;
private final Comparator<T> comparator;
private Function<Genotype, String> prettyPrinter;
public EvolutionListenerLogTopN(final Logger _logger, final int _topN, final int _skipN,
final Comparator<T> _comparator, final Function<Genotype, String> _prettyPrinter) {
Validate.notNull(_logger);
Validate.isTrue(_topN > 0);
Validate.isTrue(_skipN >= 0);
this.logger = _logger;
this.topN = _topN;
this.skipN = _skipN;
this.comparator = _comparator != null ? _comparator : Comparator.naturalOrder();
this.prettyPrinter = _prettyPrinter != null ? _prettyPrinter : t -> t.toString();
}
public EvolutionListenerLogTopN(final Logger _logger, final int _topN, final int _skipN) {
this(_logger, _topN, _skipN, null, null);
}
@Override
public void onEvolution(final long generation, final List<Genotype> population, final List<T> fitness,
final boolean isDone) {
if (skipN > 0 && generation % skipN != 0) {
return;
}
logger.info("Top {} individuals at generation {}", topN, generation);
IntStream.range(0, fitness.size())
.boxed()
.sorted((a, b) -> comparator.reversed().compare(fitness.get(a), fitness.get(b)))
.limit(topN)
.forEach((index) -> logger.info(" Fitness: {} -> {}",
fitness.get(index),
this.prettyPrinter.apply(population.get(index))));
}
}