1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.evolve.impl;
25
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Iterator;
29
30 import javax.swing.event.EventListenerList;
31
32 import org.dishevelled.evolve.EvolutionaryAlgorithm;
33 import org.dishevelled.evolve.EvolutionaryAlgorithmEvent;
34 import org.dishevelled.evolve.EvolutionaryAlgorithmListener;
35 import org.dishevelled.evolve.ExitStrategy;
36 import org.dishevelled.evolve.Fitness;
37 import org.dishevelled.evolve.Mutation;
38 import org.dishevelled.evolve.Recombination;
39 import org.dishevelled.evolve.Selection;
40
41 import org.dishevelled.weighted.WeightedMap;
42 import org.dishevelled.weighted.HashWeightedMap;
43
44
45
46
47
48
49
50
51 public final class EvolutionaryAlgorithmImpl<I>
52 implements EvolutionaryAlgorithm<I>
53 {
54
55 private static final float DEFAULT_LOAD_FACTOR = 0.75f;
56
57
58 private EventListenerList listenerList = new EventListenerList();
59
60
61
62
63
64 public EvolutionaryAlgorithmImpl()
65 {
66
67 }
68
69
70
71 public Collection<I> evolve(final Collection<I> individuals,
72 final ExitStrategy<I> exitStrategy,
73 final Recombination<I> recombination,
74 final Mutation<I> mutation,
75 final Fitness<I> fitness,
76 final Selection<I> selection)
77 {
78 checkParameters(individuals, exitStrategy, recombination, mutation, fitness, selection);
79
80
81 Collection<I> population = new ArrayList<I>(individuals);
82
83 WeightedMap<I> scores = new HashWeightedMap<I>(population.size(), DEFAULT_LOAD_FACTOR);
84 for (I i : individuals)
85 {
86 scores.put(i, Double.valueOf(0.0d));
87 }
88
89 int time = 0;
90 while (!exitStrategy.evaluate(population, scores, time))
91 {
92 fireExitFailed(population, scores, time);
93
94
95 Collection<I> recombined = recombination.recombine(population);
96 fireRecombined(population, recombined);
97
98
99 Collection<I> mutated = mutation.mutate(recombined);
100 fireMutated(recombined, mutated);
101
102
103 for (I i : mutated)
104 {
105 Double score = fitness.score(i);
106 scores.put(i, score);
107 fireFitnessCalculated(i, score);
108 }
109
110
111 population = selection.select(mutated, scores);
112 fireSelected(mutated, population, scores);
113
114
115 for (Iterator<I> keys = scores.keySet().iterator(); keys.hasNext(); )
116 {
117 I i = keys.next();
118 if (!population.contains(i))
119 {
120 keys.remove();
121 }
122 }
123
124 time++;
125 }
126
127
128 fireExitSucceeded(population, scores, time);
129 return population;
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144 private void checkParameters(final Collection<I> individuals,
145 final ExitStrategy<I> exitStrategy,
146 final Recombination<I> recombination,
147 final Mutation<I> mutation,
148 final Fitness<I> fitness,
149 final Selection<I> selection)
150 {
151
152 if (individuals == null)
153 {
154 throw new IllegalArgumentException("individuals must not be null");
155 }
156 if (individuals.size() == 0)
157 {
158 throw new IllegalArgumentException("individuals must not be empty");
159 }
160 if (exitStrategy == null)
161 {
162 throw new IllegalArgumentException("exitStrategy must not be null");
163 }
164 if (recombination == null)
165 {
166 throw new IllegalArgumentException("recombination must not be null");
167 }
168 if (mutation == null)
169 {
170 throw new IllegalArgumentException("mutation must not be null");
171 }
172 if (fitness == null)
173 {
174 throw new IllegalArgumentException("fitness must not be null");
175 }
176 if (selection == null)
177 {
178 throw new IllegalArgumentException("selection must not be null");
179 }
180 }
181
182
183
184
185
186
187
188 public void addEvolutionaryAlgorithmListener(final EvolutionaryAlgorithmListener<I> l)
189 {
190 listenerList.add(EvolutionaryAlgorithmListener.class, l);
191 }
192
193
194 public void removeEvolutionaryAlgorithmListener(final EvolutionaryAlgorithmListener<I> l)
195 {
196 listenerList.remove(EvolutionaryAlgorithmListener.class, l);
197 }
198
199
200 public int getEvolutionaryAlgorithmListenerCount()
201 {
202 return listenerList.getListenerCount(EvolutionaryAlgorithmListener.class);
203 }
204
205
206 public EvolutionaryAlgorithmListener<I>[] getEvolutionaryAlgorithmListeners()
207 {
208 return (EvolutionaryAlgorithmListener<I>[]) listenerList.getListeners(EvolutionaryAlgorithmListener.class);
209 }
210
211
212
213
214
215
216
217
218 private void fireExitFailed(final Collection<I> population, final WeightedMap<I> scores, final int time)
219 {
220 Object[] listeners = listenerList.getListenerList();
221 EvolutionaryAlgorithmEvent<I> e = null;
222
223 for (int i = listeners.length - 2; i >= 0; i -= 2)
224 {
225 if (listeners[i] == EvolutionaryAlgorithmListener.class)
226 {
227 if (e == null)
228 {
229 e = new EvolutionaryAlgorithmEvent<I>(this, population, scores, time);
230 }
231
232 ((EvolutionaryAlgorithmListener<I>) listeners[i + 1]).exitFailed(e);
233 }
234 }
235 }
236
237
238
239
240
241
242
243
244 private void fireExitSucceeded(final Collection<I> population, final WeightedMap<I> scores, final int time)
245 {
246 Object[] listeners = listenerList.getListenerList();
247 EvolutionaryAlgorithmEvent<I> e = null;
248
249 for (int i = listeners.length - 2; i >= 0; i -= 2)
250 {
251 if (listeners[i] == EvolutionaryAlgorithmListener.class)
252 {
253 if (e == null)
254 {
255 e = new EvolutionaryAlgorithmEvent<I>(this, population, scores, time);
256 }
257
258 ((EvolutionaryAlgorithmListener<I>) listeners[i + 1]).exitSucceeded(e);
259 }
260 }
261 }
262
263
264
265
266
267
268
269 private void fireRecombined(final Collection<I> population, final Collection<I> recombined)
270 {
271 Object[] listeners = listenerList.getListenerList();
272 EvolutionaryAlgorithmEvent<I> e = null;
273
274 for (int i = listeners.length - 2; i >= 0; i -= 2)
275 {
276 if (listeners[i] == EvolutionaryAlgorithmListener.class)
277 {
278 if (e == null)
279 {
280 e = new EvolutionaryAlgorithmEvent<I>(this, population, recombined, (Collection<I>) null);
281 }
282
283 ((EvolutionaryAlgorithmListener<I>) listeners[i + 1]).recombined(e);
284 }
285 }
286 }
287
288
289
290
291
292
293
294 private void fireMutated(final Collection<I> recombined, final Collection<I> mutated)
295 {
296 Object[] listeners = listenerList.getListenerList();
297 EvolutionaryAlgorithmEvent<I> e = null;
298
299 for (int i = listeners.length - 2; i >= 0; i -= 2)
300 {
301 if (listeners[i] == EvolutionaryAlgorithmListener.class)
302 {
303 if (e == null)
304 {
305 e = new EvolutionaryAlgorithmEvent<I>(this, null, recombined, mutated);
306 }
307
308 ((EvolutionaryAlgorithmListener<I>) listeners[i + 1]).mutated(e);
309 }
310 }
311 }
312
313
314
315
316
317
318
319 private void fireFitnessCalculated(final I individual, final Double score)
320 {
321 Object[] listeners = listenerList.getListenerList();
322 EvolutionaryAlgorithmEvent<I> e = null;
323
324 for (int i = listeners.length - 2; i >= 0; i -= 2)
325 {
326 if (listeners[i] == EvolutionaryAlgorithmListener.class)
327 {
328 if (e == null)
329 {
330 e = new EvolutionaryAlgorithmEvent<I>(this, individual, score);
331 }
332
333 ((EvolutionaryAlgorithmListener<I>) listeners[i + 1]).fitnessCalculated(e);
334 }
335 }
336 }
337
338
339
340
341
342
343
344
345 private void fireSelected(final Collection<I> population,
346 final Collection<I> selected,
347 final WeightedMap<I> scores)
348 {
349 Object[] listeners = listenerList.getListenerList();
350 EvolutionaryAlgorithmEvent<I> e = null;
351
352 for (int i = listeners.length - 2; i >= 0; i -= 2)
353 {
354 if (listeners[i] == EvolutionaryAlgorithmListener.class)
355 {
356 if (e == null)
357 {
358 e = new EvolutionaryAlgorithmEvent<I>(this, population, selected, scores);
359 }
360
361 ((EvolutionaryAlgorithmListener<I>) listeners[i + 1]).selected(e);
362 }
363 }
364 }
365 }