package cecj.eval;
import java.util.ArrayList;
import java.util.List;
import cecj.fitness.FitnessAggregateMethod;
import cecj.interaction.InteractionResult;
import cecj.interaction.InteractionScheme;
import cecj.sampling.SamplingMethod;
import cecj.statistics.CoevolutionaryStatistics;
import ec.EvolutionState;
import ec.Individual;
import ec.util.Parameter;
/**
* Simple coevolutionary evaluator without any additional mechanisms.
*
* It evaluates individuals according to outcomes of its interactions with other individuals.
* Interactions are not restricted to intraspecific or interspecific type, i.e. opponents can be
* choosen from the same population or any other coevolving population.
*
* In contrast to TournamentCoevolutionaryEvaluator
all interactions can be simulated
* in any order. There are no sequantial dependencies between interactions.
*
* @author Marcin Szubert
*
*/
public class SimpleCoevolutionaryEvaluator extends CoevolutionaryEvaluator {
protected static final String P_SUBPOP = "subpop";
private static final String P_STATISTICS = "statistics";
private static final String P_FITNESS_METHOD = "fitness-method";
private static final String P_POP_INDS_WEIGHT = "pop-inds-weight";
private static final String P_SAMPLING_METHOD = "sampling-method";
private static final String P_INTERACTION_SCHEME = "interaction-scheme";
/**
* Tests used to interact with candidate solutions.
*/
protected List> opponents;
/**
* Methods of sampling the opponents from particular populations.
*/
protected SamplingMethod[] samplingMethod;
/**
* Method of aggregating multiple interaction outcomes into single value.
*/
protected FitnessAggregateMethod[] fitnessAggregateMethod;
/**
* Specifies how interactions between populations look like.
*/
protected InteractionScheme interactionScheme;
protected CoevolutionaryStatistics statistics;
private int popIndsWeight;
@Override
public void setup(final EvolutionState state, final Parameter base) {
super.setup(state, base);
Parameter interactionSchemeParam = base.push(P_INTERACTION_SCHEME);
interactionScheme = (InteractionScheme) (state.parameters
.getInstanceForParameter(interactionSchemeParam, null, InteractionScheme.class));
interactionScheme.setup(state, interactionSchemeParam);
Parameter popIndsWeightParam = base.push(P_POP_INDS_WEIGHT);
popIndsWeight = state.parameters.getIntWithDefault(popIndsWeightParam, null, 1);
Parameter statisticsParam = base.push(P_STATISTICS);
if (state.parameters.exists(statisticsParam)) {
statistics = (CoevolutionaryStatistics) (state.parameters
.getInstanceForParameter(statisticsParam, null, CoevolutionaryStatistics.class));
statistics.setup(state, statisticsParam);
}
opponents = new ArrayList>(numSubpopulations);
samplingMethod = new SamplingMethod[numSubpopulations];
fitnessAggregateMethod = new FitnessAggregateMethod[numSubpopulations];
for (int subpop = 0; subpop < numSubpopulations; subpop++) {
opponents.add(new ArrayList());
setupSubpopulation(state, base, subpop);
}
}
/**
* Sets up fitness aggregate methods and sampling method for the given subpopulation.
*
* @param state
* the current evolution state
* @param base
* the base parameter
* @param subpop
* the subpopulation index
*/
private void setupSubpopulation(EvolutionState state, Parameter base, int subpop) {
Parameter samplingMethodParam = base.push(P_SUBPOP).push("" + subpop)
.push(P_SAMPLING_METHOD);
samplingMethod[subpop] = (SamplingMethod) (state.parameters
.getInstanceForParameter(samplingMethodParam, null, SamplingMethod.class));
samplingMethod[subpop].setup(state, samplingMethodParam);
Parameter fitnessMethodParam = base.push(P_SUBPOP).push("" + subpop).push(P_FITNESS_METHOD);
fitnessAggregateMethod[subpop] = (FitnessAggregateMethod) (state.parameters
.getInstanceForParameter(fitnessMethodParam, null, FitnessAggregateMethod.class));
}
@Override
public void evaluatePopulation(EvolutionState state) {
for (int subpop = 0; subpop < numSubpopulations; subpop++) {
opponents.set(subpop, findOpponentsFromSubpopulation(state, subpop));
}
for (int subpop = 0; subpop < numSubpopulations; subpop++) {
List> subpopulationResults = interactionScheme
.performInteractions(state, subpop, opponents);
fitnessAggregateMethod[subpop].prepareToAggregate(state, subpop);
fitnessAggregateMethod[subpop].addToAggregate(state, subpop, subpopulationResults,
popIndsWeight);
fitnessAggregateMethod[subpop].assignFitness(state, subpop);
if (statistics != null) {
statistics.printInteractionResults(state, subpopulationResults, subpop);
}
}
}
/**
* Samples subpopulation to choose a reference set of individuals. Other individuals can be
* evaluated on the basis of interactions with this reference set. It may happen that
* individuals from the same subpopulation are tested int this way - it depends on
*
* @param subpop
*/
private List findOpponentsFromSubpopulation(EvolutionState state, int subpop) {
return samplingMethod[subpop].sample(state, state.population.subpops[subpop].individuals);
}
public InteractionScheme getInteractionScheme() {
return interactionScheme;
}
}