Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/multiobjective/nsga2/NSGA2Evaluator.java @ 9598

Last change on this file since 9598 was 6152, checked in by bfarka, 14 years ago

added ecj and custom statistics to communicate with the okb services #1441

File size: 8.4 KB
Line 
1/*
2  Copyright 2010 by Sean Luke and George Mason University
3  Licensed under the Academic Free License version 3.0
4  See the file "LICENSE" for more information
5*/
6
7package ec.multiobjective.nsga2;
8
9import java.util.*;
10import ec.*;
11import ec.multiobjective.*;
12import ec.simple.*;
13import ec.util.*;
14
15/*
16 * NSGA2Evaluator.java
17 *
18 * Created: Sat Oct 16 00:19:57 EDT 2010
19 * By: Faisal Abidi and Sean Luke
20 */
21
22
23/**
24 * The NSGA2Evaluator is a simple generational evaluator which
25 * evaluates every single member of the population (in a multithreaded fashion).
26 * Then it reduces the population size to an <i>archive</i> consisting of the
27 * best front ranks.  When there isn't enough space to fit another front rank,
28 * individuals in that final front rank vie for the remaining slots in the archive
29 * based on their sparsity.
30 *
31 * <p>The evaluator is also responsible for calculating the rank and
32 * sparsity values stored in the NSGA2MultiObjectiveFitness class and used largely
33 * for statistical information.
34 *
35 * <p>NSGA-II has fixed archive size (the population size), and so ignores the 'elites'
36 * declaration.  However it will adhere to the 'reevaluate-elites' parameter in SimpleBreeder
37 * to determine whether to force fitness reevaluation.
38 *
39 */
40 
41public class NSGA2Evaluator extends SimpleEvaluator
42    {
43    /** The original population size is stored here so NSGA2 knows how large to create the archive
44        (it's the size of the original population -- keep in mind that NSGA2Breeder had made the
45        population larger to include the children. */
46    public int originalPopSize[];
47
48    public void setup(final EvolutionState state, final Parameter base)
49        {
50        super.setup(state, base);
51        Parameter p = new Parameter(Initializer.P_POP);
52        int subpopsLength = state.parameters.getInt(p.push(Population.P_SIZE), null, 1);
53        Parameter p_subpop;
54        originalPopSize = new int[subpopsLength];
55        for (int i = 0; i < subpopsLength; i++)
56            {
57            p_subpop = p.push(Population.P_SUBPOP).push("" + i).push(Subpopulation.P_SUBPOPSIZE);
58            originalPopSize[i] = state.parameters.getInt(p_subpop, null, 1);
59            }
60        }
61
62
63    /**
64     * Evaluates the population, then builds the archive and reduces the population to just the archive.
65     */
66    public void evaluatePopulation(final EvolutionState state)
67        {
68        super.evaluatePopulation(state);
69        for (int x = 0; x < state.population.subpops.length; x++)
70            state.population.subpops[x].individuals =
71                buildArchive(state, x);
72        }
73
74
75    /** Build the auxiliary fitness data and reduce the subpopulation to just the archive, which is
76        returned. */
77    public Individual[] buildArchive(EvolutionState state, int subpop)
78        {
79        Individual[] dummy = new Individual[0];
80        ArrayList ranks = assignFrontRanks(state.population.subpops[subpop]);
81               
82        ArrayList newSubpopulation = new ArrayList();
83        int size = ranks.size();
84        for(int i = 0; i < size; i++)
85            {
86            Individual[] rank = (Individual[])((ArrayList)(ranks.get(i))).toArray(dummy);
87            assignSparsity(rank);
88            if (rank.length + newSubpopulation.size() >= originalPopSize[subpop])
89                {
90                // first sort the rank by sparsity
91                ec.util.QuickSort.qsort(rank, new SortComparator()
92                    {
93                    public boolean lt(Object a, Object b)
94                        {
95                        Individual i1 = (Individual) a;
96                        Individual i2 = (Individual) b;
97                        return (((NSGA2MultiObjectiveFitness) i1.fitness).sparsity > ((NSGA2MultiObjectiveFitness) i2.fitness).sparsity);
98                        }
99
100                    public boolean gt(Object a, Object b)
101                        {
102                        Individual i1 = (Individual) a;
103                        Individual i2 = (Individual) b;
104                        return (((NSGA2MultiObjectiveFitness) i1.fitness).sparsity < ((NSGA2MultiObjectiveFitness) i2.fitness).sparsity);
105                        }
106                    });
107
108                // then put the m sparsest individuals in the new population
109                int m = originalPopSize[subpop] - newSubpopulation.size();
110                for(int j = 0 ; j < m; j++)
111                    newSubpopulation.add(rank[j]);
112                               
113                // and bail
114                break;
115                }
116            else
117                {
118                // dump in everyone
119                for(int j = 0 ; j < rank.length; j++)
120                    newSubpopulation.add(rank[j]);
121                }
122            }
123
124        Individual[] archive = (Individual[])(newSubpopulation.toArray(dummy));
125               
126        // maybe force reevaluation
127        NSGA2Breeder breeder = (NSGA2Breeder)(state.breeder);
128        if (breeder.reevaluateElites[subpop])
129            for(int i = 0 ; i < archive.length; i++)
130                archive[i].evaluated = false;
131
132        return archive;
133        }
134
135
136
137    /** Divides inds into ranks and assigns each individual's rank to be the rank it was placed into.
138        Each front is an ArrayList. */
139    public ArrayList assignFrontRanks(Subpopulation subpop)
140        {
141        Individual[] inds = subpop.individuals;
142        ArrayList frontsByRank = MultiObjectiveFitness.partitionIntoRanks(inds);
143
144        int numRanks = frontsByRank.size();
145        for(int rank = 0; rank < numRanks; rank++)
146            {
147            ArrayList front = (ArrayList)(frontsByRank.get(rank));
148            int numInds = front.size();
149            for(int ind = 0; ind < numInds; ind++)
150                ((NSGA2MultiObjectiveFitness)(((Individual)(front.get(ind))).fitness)).rank = rank;
151            }
152        return frontsByRank;
153        }
154
155
156
157    /**
158     * Computes and assigns the sparsity values of a given front.
159     */
160    public void assignSparsity(Individual[] front)
161        {
162        int numObjectives = ((NSGA2MultiObjectiveFitness) front[0].fitness).getObjectives().length;
163               
164        for (int i = 0; i < front.length; i++)
165            ((NSGA2MultiObjectiveFitness) front[i].fitness).sparsity = 0;
166
167        for (int i = 0; i < numObjectives; i++)
168            {
169            final int o = i;
170            // 1. Sort front by each objective.
171            // 2. Sum the manhattan distance of an individual's neighbours over
172            // each objective.
173            // NOTE: No matter which objectives objective you sort by, the
174            // first and last individuals will always be the same (they maybe
175            // interchanged though). This is because a Pareto front's
176            // objective values are strictly increasing/decreasing.
177            ec.util.QuickSort.qsort(front, new SortComparator()
178                {
179                public boolean lt(Object a, Object b)
180                    {
181                    Individual i1 = (Individual) a;
182                    Individual i2 = (Individual) b;
183                    return (((NSGA2MultiObjectiveFitness) i1.fitness).getObjective(o) < ((NSGA2MultiObjectiveFitness) i2.fitness).getObjective(o));
184                    }
185
186                public boolean gt(Object a, Object b)
187                    {
188                    Individual i1 = (Individual) a;
189                    Individual i2 = (Individual) b;
190                    return (((NSGA2MultiObjectiveFitness) i1.fitness).getObjective(o) > ((NSGA2MultiObjectiveFitness) i2.fitness).getObjective(o));
191                    }
192                });
193
194            // Compute and assign sparsity.
195            // the first and last individuals are the sparsest.
196            ((NSGA2MultiObjectiveFitness) front[0].fitness).sparsity = Double.POSITIVE_INFINITY;
197            ((NSGA2MultiObjectiveFitness) front[front.length - 1].fitness).sparsity = Double.POSITIVE_INFINITY;
198            for (int j = 1; j < front.length - 1; j++)
199                {
200                NSGA2MultiObjectiveFitness f_j = (NSGA2MultiObjectiveFitness) (front[j].fitness);
201                NSGA2MultiObjectiveFitness f_jplus1 = (NSGA2MultiObjectiveFitness) (front[j+1].fitness);
202                NSGA2MultiObjectiveFitness f_jminus1 = (NSGA2MultiObjectiveFitness) (front[j-1].fitness);
203                               
204                // store the NSGA2Sparsity in sparsity
205                f_j.sparsity += (f_jplus1.getObjective(o) - f_jminus1.getObjective(o)) / (f_j.maxObjective[o] - f_j.minObjective[o]);
206                }
207            }
208        }
209    }
Note: See TracBrowser for help on using the repository browser.