source: java/ecj/cecj/eval/SimpleCoevolutionaryEvaluator.java @ 108

Last change on this file since 108 was 44, checked in by mszubert, 15 years ago

cecj, framsticks and games packages imported

File size: 6.8 KB
Line 
1/*
2  Copyright 2009 by Marcin Szubert
3  Licensed under the Academic Free License version 3.0
4*/
5
6package cecj.eval;
7
8import java.util.ArrayList;
9import java.util.List;
10
11import cecj.fitness.FitnessAggregateMethod;
12import cecj.interaction.InteractionResult;
13import cecj.interaction.InteractionScheme;
14import cecj.sampling.SamplingMethod;
15import cecj.statistics.CoevolutionaryStatistics;
16
17import ec.EvolutionState;
18import ec.Individual;
19import ec.util.Parameter;
20
21/**
22 *
23 * Simple coevolutionary evaluator without any additional mechanisms.
24 *
25 * This is the simplest implementation of conventional coevolutionary evaluation where interactions
26 * between individuals can be performed in an arbitrary order. However, the character and the scope
27 * of interactions can be different Ð it is defined by instantiating appropriate
28 * <code>InteractionScheme</code> subclass. The evaluation proceeds as follows. First of all, a
29 * reference set of opponent individuals is selected from each subpopulation. This task is handled
30 * by a <code>SamplingMethod</code> realization. Distinct sampling methods can be used by different
31 * subpopulations. Next, each subpopulation individuals are confronted with previously selected
32 * opponents from subpopulations pointed by the concrete <code>InteractionScheme</code> class.
33 * Finally, <code>FitnessAggregateMethod</code> is responsible for aggregating outcomes of these
34 * confrontations into a single fitness measure which is used later during selection stage of the
35 * evolutionary process. It evaluates individuals according to the outcomes of its interactions with
36 * other individuals. Interactions are not restricted to intraspecific or interspecific type, i.e.
37 * opponents can be chosen from the same population or any other coevolving population.
38 *
39 * In contrast to <code>TournamentCoevolutionaryEvaluator</code> all interactions can be simulated
40 * in any order. There are no sequential dependencies between interactions.
41 *
42 * @author Marcin Szubert
43 *
44 */
45public class SimpleCoevolutionaryEvaluator extends CoevolutionaryEvaluator {
46
47        protected static final String P_SUBPOP = "subpop";
48        private static final String P_STATISTICS = "statistics";
49        private static final String P_FITNESS_METHOD = "fitness-method";
50        private static final String P_POP_INDS_WEIGHT = "pop-inds-weight";
51        private static final String P_SAMPLING_METHOD = "sampling-method";
52        private static final String P_INTERACTION_SCHEME = "interaction-scheme";
53
54        /**
55         * Tests used to interact with candidate solutions.
56         */
57        protected List<List<Individual>> opponents;
58
59        /**
60         * Methods of sampling the opponents from particular populations.
61         */
62        protected SamplingMethod[] samplingMethod;
63
64        /**
65         * The Method of aggregating multiple interaction outcomes into single value.
66         */
67        protected FitnessAggregateMethod[] fitnessAggregateMethod;
68
69        /**
70         * Specifies how interactions between populations look like.
71         */
72        protected InteractionScheme interactionScheme;
73
74        /**
75         * Gathers statistics about evaluation stage.
76         */
77        protected CoevolutionaryStatistics statistics;
78
79        /**
80         * Indicates how important are population opponents with respect to potential archival
81         * opponents.
82         */
83        private int popIndsWeight;
84
85        @Override
86        public void setup(final EvolutionState state, final Parameter base) {
87                super.setup(state, base);
88
89                Parameter interactionSchemeParam = base.push(P_INTERACTION_SCHEME);
90                interactionScheme = (InteractionScheme) (state.parameters.getInstanceForParameter(
91                                interactionSchemeParam, null, InteractionScheme.class));
92                interactionScheme.setup(state, interactionSchemeParam);
93
94                Parameter popIndsWeightParam = base.push(P_POP_INDS_WEIGHT);
95                popIndsWeight = state.parameters.getIntWithDefault(popIndsWeightParam, null, 1);
96
97                Parameter statisticsParam = base.push(P_STATISTICS);
98                if (state.parameters.exists(statisticsParam)) {
99                        statistics = (CoevolutionaryStatistics) (state.parameters.getInstanceForParameter(
100                                        statisticsParam, null, CoevolutionaryStatistics.class));
101                        statistics.setup(state, statisticsParam);
102                }
103
104                opponents = new ArrayList<List<Individual>>(numSubpopulations);
105                samplingMethod = new SamplingMethod[numSubpopulations];
106                fitnessAggregateMethod = new FitnessAggregateMethod[numSubpopulations];
107
108                for (int subpop = 0; subpop < numSubpopulations; subpop++) {
109                        opponents.add(new ArrayList<Individual>());
110                        setupSubpopulation(state, base, subpop);
111                }
112        }
113
114        /**
115         * Sets up fitness aggregate methods and sampling method for the given subpopulation.
116         *
117         * @param state
118         *            the current evolutionary state
119         * @param base
120         *            the base parameter
121         * @param subpop
122         *            the subpopulation index
123         */
124        private void setupSubpopulation(EvolutionState state, Parameter base, int subpop) {
125                Parameter samplingMethodParam = base.push(P_SUBPOP).push("" + subpop).push(
126                                P_SAMPLING_METHOD);
127                samplingMethod[subpop] = (SamplingMethod) (state.parameters.getInstanceForParameter(
128                                samplingMethodParam, null, SamplingMethod.class));
129                samplingMethod[subpop].setup(state, samplingMethodParam);
130
131                Parameter fitnessMethodParam = base.push(P_SUBPOP).push("" + subpop).push(P_FITNESS_METHOD);
132                fitnessAggregateMethod[subpop] = (FitnessAggregateMethod) (state.parameters
133                                .getInstanceForParameter(fitnessMethodParam, null, FitnessAggregateMethod.class));
134        }
135
136        @Override
137        public void evaluatePopulation(EvolutionState state) {
138                for (int subpop = 0; subpop < numSubpopulations; subpop++) {
139                        opponents.set(subpop, findOpponentsFromSubpopulation(state, subpop));
140                }
141
142                for (int subpop = 0; subpop < numSubpopulations; subpop++) {
143                        List<List<InteractionResult>> subpopulationResults = interactionScheme
144                                        .performInteractions(state, subpop, opponents);
145
146                        fitnessAggregateMethod[subpop].prepareToAggregate(state, subpop);
147                        fitnessAggregateMethod[subpop].addToAggregate(state, subpop, subpopulationResults,
148                                        popIndsWeight);
149                        fitnessAggregateMethod[subpop].assignFitness(state, subpop);
150
151                        if (statistics != null) {
152                                statistics.printInteractionResults(state, subpopulationResults, subpop);
153                        }
154                }
155        }
156
157        /**
158         * Samples subpopulation to choose a reference set of individuals. Other individuals can be
159         * evaluated on the basis of interactions with this reference set. It may happen that
160         * individuals from the same subpopulation are tested int this way - it depends on
161         *
162         * @param subpop
163         *            the index of subpopulation
164         * @return a list of individuals sampled from the given subpopulation
165         */
166        private List<Individual> findOpponentsFromSubpopulation(EvolutionState state, int subpop) {
167                return samplingMethod[subpop].sample(state, state.population.subpops[subpop].individuals);
168        }
169
170        /**
171         * Returns the interaction scheme used during the evaluation.
172         *
173         * @return the interaction scheme used by this evaluator
174         */
175        public InteractionScheme getInteractionScheme() {
176                return interactionScheme;
177        }
178}
Note: See TracBrowser for help on using the repository browser.