/*
Copyright 2009 by Marcin Szubert
Licensed under the Academic Free License version 3.0
*/
package cecj.eval;
import java.util.ArrayList;
import java.util.List;
import cecj.archive.ArchivingSubpopulation;
import cecj.archive.CoevolutionaryArchive;
import cecj.interaction.InteractionResult;
import cecj.sampling.SamplingMethod;
import ec.EvolutionState;
import ec.Individual;
import ec.util.Parameter;
/**
* Extends the simple evaluation process with an archiving mechanism.
*
* The evaluation procedure is realized in the following manner. Firstly, after taking simple
* evaluation steps as in the superclass, additional opponents are selected among archival
* individuals (an archive is maintained for each subpopulation). Outcomes of the interactions with
* such opponents are added to results obtained by the superclass and aggregated together.
* Eventually, subpopulation individuals are submitted to the archive which decides if any of them
* is worth keeping. While interaction scheme and fitness aggregation method are inherited from the
* SimpleCoevolutionaryEvaluator
, archival sampling methods must be defined separately
* for each of the archives.
*
* Often, opponents sampled from the population are less competent than these from the archive; to
* address this issue, additional parameters were created that specify the relative importance of
* opponents from both sources - archive-inds-weight
and pop-inds-weight
.
*
* @author Marcin Szubert
*
*/
public class ArchivingCoevolutionaryEvaluator extends SimpleCoevolutionaryEvaluator {
private static final String P_ARCHIVE = "archive";
private static final String P_ARCHIVE_INDS_WEIGHT = "archive-inds-weight";
private static final String P_ARCHIVE_SAMPLING_METHOD = "archive-sampling-method";
private CoevolutionaryArchive archive;
private List> archiveOpponents;
private SamplingMethod[] archiveSamplingMethod;
private int archiveIndsWeight;
@Override
public void setup(final EvolutionState state, final Parameter base) {
super.setup(state, base);
Parameter archiveParam = base.push(P_ARCHIVE);
archive = (CoevolutionaryArchive) (state.parameters.getInstanceForParameter(archiveParam,
null, CoevolutionaryArchive.class));
archive.setup(state, base.push(P_ARCHIVE));
Parameter archiveIndsWeightParam = base.push(P_ARCHIVE_INDS_WEIGHT);
archiveIndsWeight = state.parameters.getIntWithDefault(archiveIndsWeightParam, null, 1);
archiveOpponents = new ArrayList>(numSubpopulations);
archiveSamplingMethod = new SamplingMethod[numSubpopulations];
for (int subpop = 0; subpop < numSubpopulations; subpop++) {
archiveOpponents.add(new ArrayList());
setupArchivingSubpopulation(state, base, subpop);
}
}
private void setupArchivingSubpopulation(EvolutionState state, Parameter base, int subpop) {
Parameter samplingMethodParam = base.push(P_SUBPOP).push("" + subpop).push(
P_ARCHIVE_SAMPLING_METHOD);
archiveSamplingMethod[subpop] = (SamplingMethod) (state.parameters.getInstanceForParameter(
samplingMethodParam, null, SamplingMethod.class));
archiveSamplingMethod[subpop].setup(state, samplingMethodParam);
}
@Override
public void evaluatePopulation(EvolutionState state) {
if (!(state.population.subpops[0] instanceof ArchivingSubpopulation)) {
state.output.fatal("Archiving evaluator requires archiving subpopulation");
}
super.evaluatePopulation(state);
for (int subpop = 0; subpop < numSubpopulations; subpop++) {
archiveOpponents.set(subpop, findOpponentsFromArchive(state, subpop));
}
for (int subpop = 0; subpop < numSubpopulations; subpop++) {
List> subpopulationResults = interactionScheme
.performInteractions(state, subpop, archiveOpponents);
fitnessAggregateMethod[subpop].addToAggregate(state, subpop, subpopulationResults,
archiveIndsWeight);
fitnessAggregateMethod[subpop].assignFitness(state, subpop);
if (statistics != null) {
statistics.printInteractionResults(state, subpopulationResults, subpop);
}
}
archive.submit(state);
}
private List findOpponentsFromArchive(EvolutionState state, int subpop) {
List archivalInds = ((ArchivingSubpopulation) state.population.subpops[subpop])
.getArchivalIndividuals();
return archiveSamplingMethod[subpop].sample(state, archivalInds);
}
}