source: java/ecj/cecj/archive/ParetoCoevolutionArchive.java @ 35

Last change on this file since 35 was 28, checked in by mszubert, 15 years ago

cecj - coEvolutionary Computation in Java with additional games package

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.4 KB
Line 
1package cecj.archive;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import cecj.interaction.InteractionResult;
7
8import ec.EvolutionState;
9import ec.Individual;
10
11/**
12 * Represents the archive for Pareto-Coevolution paradigm where each test is viewed as an objective
13 * in the sense of Multi-Objective Optimization.
14 *
15 * It provides methods for comparing individuals on the basis of their interaction results.
16 *
17 * @author Marcin Szubert
18 *
19 */
20public abstract class ParetoCoevolutionArchive extends CandidateTestArchive {
21
22        /**
23         * Tries to find a test for which <code>candidate1</code> has better outcome than
24         * <code>candidate2<code>. It is needed for <code>candidate1</code> to be non-dominated and thus
25         * useful to be stored in the archive. If the test is found it makes distinction between
26         * candidates.
27         *
28         * @param state
29         *            the current evolution state
30         * @param candidate1
31         *            the candidate which should appear to be better at some test
32         * @param candidate2
33         *            the reference candidate solution which is checked for dominating the candidate1
34         * @param tests
35         *            the list of test to be searched
36         * @return <code>null</code> if there is no such test
37         */
38        protected Individual findUsefulTest(EvolutionState state, Individual candidate1,
39                        Individual candidate2, List<Individual> tests) {
40                for (Individual test : tests) {
41                        InteractionResult result1 = problem.test(state, candidate1, test).first;
42                        InteractionResult result2 = problem.test(state, candidate2, test).first;
43                        if (result1.betterThan(result2)) {
44                                return test;
45                        }
46                }
47                return null;
48        }
49
50        /**
51         * Checks if <code>candidate1</code> Pareto-dominates <code>candidate2</code> or both candidates
52         * are equal with respect to <code>tests</code>. One candidate is Pareto-dominated if it has
53         * better or equal outcomes for all <code>tests</code> and for at least one - strictly better.
54         *
55         * @param state
56         *            the current evolution state
57         * @param candidate1
58         *            the candidate solution which is checked for dominating the other candidate
59         * @param candidate2
60         *            the candidate solutions which is checked for being dominated
61         * @param tests
62         *            the set of tests with respect to which dominance is checked
63         * @return <code>true</code> if <code>candidate1</code> dominates <code>candidate2</code> or
64         *         they are equal with respect to <code>tests</code>, <code>false</code> otherwise
65         */
66        protected boolean dominatesOrEqual(EvolutionState state, Individual candidate1,
67                        Individual candidate2, List<Individual> tests) {
68                return (findUsefulTest(state, candidate2, candidate1, tests) == null);
69        }
70
71        /**
72         * Checks if <code>candidate1</code> Pareto-dominates <code>candidate2</code> with respect to
73         * <code>tests</code>. One candidate is Pareto-dominated if it has better or equal outcomes for
74         * all <code>tests</code> and for at least one - strictly better.
75         *
76         * @param state
77         *            the current evolution state
78         * @param candidate1
79         *            the candidate solution which is checked for dominating the other candidate
80         * @param candidate2
81         *            the candidate solutions which is checked for being dominated
82         * @param tests
83         *            the set of tests with respect to which dominance is checked
84         * @return <code>true</code> if <code>candidate1</code> dominates <code>candidate2</code> with
85         *         respect to <code>tests</code>, <code>false</code> otherwise
86         */
87        protected boolean dominates(EvolutionState state, Individual candidate1, Individual candidate2,
88                        List<Individual> tests) {
89                if ((findUsefulTest(state, candidate2, candidate1, tests) == null)
90                                && (findUsefulTest(state, candidate1, candidate2, tests) != null)) {
91                        return true;
92                } else {
93                        return false;
94                }
95        }
96
97        /**
98         * Verifies if <code>candidate</code> is dominated by any candidate solution present in
99         * <code>cArchive</code> with respect to tests in <code>tArchive</code> or if another solution
100         * has equivalent outcomes for all tests in <code>tArchive</code>.
101         *
102         * If the archive contains a <code>candidate</code>, the outcome is <code>true</code>.
103         *
104         * @param state
105         *            the current evolution state
106         * @param candidate
107         *            the candidate which is checked for being dominated; it should not be in the
108         *            archive
109         * @param cArchive
110         *            the archive of candidate solutions
111         * @param tArchive
112         *            the archive of tests
113         * @return <code>true</code> if <code>candidate</code> is dominated by or equal to another
114         *         solution in the archive
115         */
116        protected boolean isDominatedOrEqual(EvolutionState state, Individual candidate,
117                        List<Individual> cArchive, List<Individual> tArchive) {
118                for (Individual otherCandidate : cArchive) {
119                        if (dominatesOrEqual(state, otherCandidate, candidate, tArchive)) {
120                                return true;
121                        }
122                }
123                return false;
124        }
125
126        /**
127         * Verifies if <code>candidate</code> is dominated by any candidate solution present in
128         * <code>cArchive</code> with respect to tests in <code>tArchive</code>.
129         *
130         * @param state
131         *            the current evolution state
132         * @param candidate
133         *            the candidate which is checked for being dominated
134         * @param cArchive
135         *            the archive of candidate solutions
136         * @param tArchive
137         *            the archive of tests
138         * @return <code>true</code> if <code>candidate</code> is dominated by any solution in the
139         *         archive
140         */
141        protected boolean isDominated(EvolutionState state, Individual candidate,
142                        List<Individual> cArchive, List<Individual> tArchive) {
143                for (Individual otherCandidate : cArchive) {
144                        if (dominates(state, otherCandidate, candidate, tArchive)) {
145                                return true;
146                        }
147                }
148                return false;
149        }
150
151        /**
152         * Checks if <code>newCandidate</code> is useful with respect to current archives of candidates
153         * and tests and new population of generated tests. A candidate solutions is considered
154         * <i>useful</i> if it is non-dominated and no solution is already present with identical
155         * outcomes for all tests.
156         *
157         * @param state
158         *            the current evolution state
159         * @param newCandidate
160         *            the candidate whose usefulness is verified
161         * @param cArchive
162         *            the archive of candidate solutions
163         * @param tArchive
164         *            the archive of tests
165         * @param newTests
166         *            the population of new tests
167         * @return <code>true</code> if <code>newCandidate</code> is <i>useful</i> and should be
168         *         included in the archive.
169         */
170        protected boolean isUseful(EvolutionState state, Individual newCandidate,
171                        List<Individual> cArchive, List<Individual> tArchive, List<Individual> newTests) {
172                if (isDominatedOrEqual(state, newCandidate, cArchive, tArchive)
173                                && isDominatedOrEqual(state, newCandidate, cArchive, newTests)) {
174                        return false;
175                } else {
176                        return true;
177                }
178        }
179
180        /**
181         * Finds tests which are needed to prove usefulness of given <code>newCandidate</code>. These
182         * tests should make distinctions between existing solutions in the <code>cArchive</code> and
183         * the new one. If the <code>newCandidate</code> solution is non-dominated without adding any of
184         * <code>newTests</code> to the test archive, the returned list is empty.
185         *
186         * @param state
187         *            the current evolution state
188         * @param newCandidate
189         *            the candidate solution whose non-dominated status is to be guaranteed
190         * @param cArchive
191         *            the archive of candidate solutions
192         * @param tArchive
193         *            the archive of tests
194         * @param newTests
195         *            the population of new tests
196         * @return the list of test individuals from <code>newTests</code> which should be added to the
197         *         <code>tArchive</code> to make <code>newCandidate</code> non-dominated. If even adding
198         *         all test is not sufficient, <code>null</code> is returned.
199         */
200        protected List<Individual> findUsefulTests(EvolutionState state, Individual newCandidate,
201                        List<Individual> cArchive, List<Individual> tArchive, List<Individual> newTests) {
202                List<Individual> selected = new ArrayList<Individual>();
203                List<Individual> rest = new ArrayList<Individual>(newTests);
204
205                for (Individual candidate : cArchive) {
206                        if (dominatesOrEqual(state, candidate, newCandidate, tArchive)
207                                        && dominatesOrEqual(state, candidate, newCandidate, selected)) {
208                                Individual test = findUsefulTest(state, newCandidate, candidate, rest);
209                                if (test == null) {
210                                        return null;
211                                } else {
212                                        selected.add(test);
213                                        rest.remove(test);
214                                }
215                        }
216                }
217
218                return selected;
219        }
220}
Note: See TracBrowser for help on using the repository browser.