1 | /* |
---|
2 | Copyright 2006 by Sean Luke |
---|
3 | Licensed under the Academic Free License version 3.0 |
---|
4 | See the file "LICENSE" for more information |
---|
5 | */ |
---|
6 | |
---|
7 | |
---|
8 | package ec.simple; |
---|
9 | import ec.Evaluator; |
---|
10 | import ec.EvolutionState; |
---|
11 | import ec.util.Parameter; |
---|
12 | import ec.Individual; |
---|
13 | |
---|
14 | /* |
---|
15 | * SimpleEvaluator.java |
---|
16 | * |
---|
17 | * Created: Wed Aug 18 21:31:18 1999 |
---|
18 | * By: Sean Luke |
---|
19 | */ |
---|
20 | |
---|
21 | /** |
---|
22 | * The SimpleEvaluator is a simple, non-coevolved generational evaluator which |
---|
23 | * evaluates every single member of every subpopulation individually in its |
---|
24 | * own problem space. One Problem instance is cloned from p_problem for |
---|
25 | * each evaluating thread. The Problem must implement SimpleProblemForm. |
---|
26 | * |
---|
27 | * @author Sean Luke |
---|
28 | * @version 1.0 |
---|
29 | */ |
---|
30 | |
---|
31 | public class SimpleEvaluator extends Evaluator |
---|
32 | { |
---|
33 | // checks to make sure that the Problem implements SimpleProblemForm |
---|
34 | public void setup(final EvolutionState state, final Parameter base) |
---|
35 | { |
---|
36 | super.setup(state,base); |
---|
37 | if (!(p_problem instanceof SimpleProblemForm)) |
---|
38 | state.output.fatal("" + this.getClass() + " used, but the Problem is not of SimpleProblemForm", |
---|
39 | base.push(P_PROBLEM)); |
---|
40 | } |
---|
41 | |
---|
42 | /** A simple evaluator that doesn't do any coevolutionary |
---|
43 | evaluation. Basically it applies evaluation pipelines, |
---|
44 | one per thread, to various subchunks of a new population. */ |
---|
45 | public void evaluatePopulation(final EvolutionState state) |
---|
46 | { |
---|
47 | int numinds[][] = |
---|
48 | new int[state.evalthreads][state.population.subpops.length]; |
---|
49 | int from[][] = |
---|
50 | new int[state.evalthreads][state.population.subpops.length]; |
---|
51 | |
---|
52 | for(int y=0;y<state.evalthreads;y++) |
---|
53 | for(int x=0;x<state.population.subpops.length;x++) |
---|
54 | { |
---|
55 | // figure numinds |
---|
56 | if (y<state.evalthreads-1) // not last one |
---|
57 | numinds[y][x]= |
---|
58 | state.population.subpops[x].individuals.length/ |
---|
59 | state.evalthreads; |
---|
60 | else // in case we're slightly off in division |
---|
61 | numinds[y][x]= |
---|
62 | state.population.subpops[x].individuals.length/ |
---|
63 | state.evalthreads + |
---|
64 | |
---|
65 | (state.population.subpops[x].individuals.length - |
---|
66 | (state.population.subpops[x].individuals.length / |
---|
67 | state.evalthreads) // note integer division |
---|
68 | *state.evalthreads); |
---|
69 | |
---|
70 | // figure from |
---|
71 | from[y][x]= |
---|
72 | (state.population.subpops[x].individuals.length/ |
---|
73 | state.evalthreads) * y; |
---|
74 | } |
---|
75 | |
---|
76 | if (state.evalthreads==1) |
---|
77 | evalPopChunk(state,numinds[0],from[0],0,(SimpleProblemForm)(p_problem.clone())); |
---|
78 | |
---|
79 | else |
---|
80 | { |
---|
81 | Thread[] t = new Thread[state.evalthreads]; |
---|
82 | |
---|
83 | // start up the threads |
---|
84 | for(int y=0;y<state.evalthreads;y++) |
---|
85 | { |
---|
86 | SimpleEvaluatorThread r = new SimpleEvaluatorThread(); |
---|
87 | r.threadnum = y; |
---|
88 | r.numinds = numinds[y]; |
---|
89 | r.from = from[y]; |
---|
90 | r.me = this; |
---|
91 | r.state = state; |
---|
92 | r.p = (SimpleProblemForm)(p_problem.clone()); |
---|
93 | t[y] = new Thread(r); |
---|
94 | t[y].start(); |
---|
95 | } |
---|
96 | |
---|
97 | // gather the threads |
---|
98 | for(int y=0;y<state.evalthreads;y++) try |
---|
99 | { |
---|
100 | t[y].join(); |
---|
101 | } |
---|
102 | catch(InterruptedException e) |
---|
103 | { |
---|
104 | state.output.fatal("Whoa! The main evaluation thread got interrupted! Dying..."); |
---|
105 | } |
---|
106 | |
---|
107 | } |
---|
108 | } |
---|
109 | |
---|
110 | /** A private helper function for evaluatePopulation which evaluates a chunk |
---|
111 | of individuals in a subpopulation for a given thread. |
---|
112 | Although this method is declared |
---|
113 | public (for the benefit of a private helper class in this file), |
---|
114 | you should not call it. */ |
---|
115 | |
---|
116 | protected void evalPopChunk(EvolutionState state, int[] numinds, int[] from, |
---|
117 | int threadnum, SimpleProblemForm p) |
---|
118 | { |
---|
119 | ((ec.Problem)p).prepareToEvaluate(state,threadnum); |
---|
120 | |
---|
121 | for(int pop=0;pop<state.population.subpops.length;pop++) |
---|
122 | { |
---|
123 | // start evaluatin'! |
---|
124 | int upperbound = from[pop]+numinds[pop]; |
---|
125 | for (int x=from[pop];x<upperbound;x++) |
---|
126 | { |
---|
127 | p.evaluate(state,state.population.subpops[pop].individuals[x], pop, threadnum); |
---|
128 | } |
---|
129 | } |
---|
130 | ((ec.Problem)p).finishEvaluating(state,threadnum); |
---|
131 | } |
---|
132 | |
---|
133 | /** The SimpleEvaluator determines that a run is complete by asking |
---|
134 | each individual in each population if he's optimal; if he |
---|
135 | finds an individual somewhere that's optimal, |
---|
136 | he signals that the run is complete. */ |
---|
137 | public boolean runComplete(final EvolutionState state) |
---|
138 | { |
---|
139 | for(int x = 0;x<state.population.subpops.length;x++) |
---|
140 | for(int y=0;y<state.population.subpops[x].individuals.length;y++) |
---|
141 | if (state.population.subpops[x]. |
---|
142 | individuals[y].fitness.isIdealFitness()) |
---|
143 | return true; |
---|
144 | return false; |
---|
145 | } |
---|
146 | } |
---|
147 | |
---|
148 | /** A private helper class for implementing multithreaded evaluation */ |
---|
149 | class SimpleEvaluatorThread implements Runnable |
---|
150 | { |
---|
151 | public int[] numinds; |
---|
152 | public int[] from; |
---|
153 | public SimpleEvaluator me; |
---|
154 | public EvolutionState state; |
---|
155 | public int threadnum; |
---|
156 | public SimpleProblemForm p; |
---|
157 | public synchronized void run() |
---|
158 | { me.evalPopChunk(state,numinds,from,threadnum,p); } |
---|
159 | } |
---|