001 /*
002 * Java Genetic Algorithm Library (jenetics-3.7.0).
003 * Copyright (c) 2007-2016 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019 */
020 package org.jenetics;
021
022 import static java.util.Objects.requireNonNull;
023 import static java.util.stream.Collectors.joining;
024 import static java.util.stream.Collectors.toList;
025 import static org.jenetics.internal.util.Equality.eq;
026
027 import java.io.Serializable;
028 import java.util.ArrayList;
029 import java.util.Collection;
030 import java.util.Collections;
031 import java.util.Comparator;
032 import java.util.Iterator;
033 import java.util.List;
034 import java.util.ListIterator;
035 import java.util.RandomAccess;
036 import java.util.stream.Collector;
037 import java.util.stream.Stream;
038
039 import javax.xml.bind.annotation.XmlAccessType;
040 import javax.xml.bind.annotation.XmlAccessorType;
041 import javax.xml.bind.annotation.XmlAttribute;
042 import javax.xml.bind.annotation.XmlElement;
043 import javax.xml.bind.annotation.XmlRootElement;
044 import javax.xml.bind.annotation.XmlType;
045 import javax.xml.bind.annotation.adapters.XmlAdapter;
046 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
047
048 import org.jenetics.internal.util.Equality;
049 import org.jenetics.internal.util.Hash;
050 import org.jenetics.internal.util.jaxb;
051
052 import org.jenetics.util.Copyable;
053 import org.jenetics.util.Factory;
054
055 /**
056 * A population is a collection of Phenotypes.
057 *
058 * <p>
059 * <strong>This class is not synchronized.</strong> If multiple threads access
060 * a {@code Population} concurrently, and at least one of the threads modifies
061 * it, it <strong>must</strong> be synchronized externally.
062 *
063 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
064 * @since 1.0
065 * @version 2.0
066 */
067 @XmlJavaTypeAdapter(Population.Model.Adapter.class)
068 public class Population<G extends Gene<?, G>, C extends Comparable<? super C>>
069 implements
070 List<Phenotype<G, C>>,
071 Copyable<Population<G, C>>,
072 RandomAccess,
073 Serializable
074 {
075 private static final long serialVersionUID = 2L;
076
077 @SuppressWarnings({"rawtypes", "unchecked"})
078 private static final Population<?, ?> EMPTY =
079 new Population(Collections.EMPTY_LIST);
080
081
082 private final List<Phenotype<G, C>> _population;
083
084 /**
085 * Private <i>primary</i> constructor which assigns the underlying
086 * population without copying and precondition check.
087 */
088 private Population(final List<Phenotype<G, C>> population, boolean foo) {
089 _population = requireNonNull(population);
090 }
091
092 /**
093 * Constructs a population containing the elements of the specified collection,
094 * in the order they are returned by the collection's iterator.
095 *
096 * @param population the collection whose elements are to be placed into
097 * this list.
098 * @throws NullPointerException if the specified population is {@code null}.
099 */
100 public Population(final Collection<Phenotype<G, C>> population) {
101 this(new ArrayList<>(population), true);
102 }
103
104 /**
105 * Creating a new {@code Population} with the pre-allocated population
106 * size.
107 *
108 * @param size Pre-allocated population size.
109 * @throws IllegalArgumentException if the specified initial capacity is
110 * negative
111 */
112 public Population(final int size) {
113 this(new ArrayList<>(size), true);
114 }
115
116 /**
117 * Creating a new {@code Population}.
118 */
119 public Population() {
120 this(new ArrayList<>(), true);
121 }
122
123 /**
124 * Fills the population with individuals created by the given factory.
125 *
126 * @param factory the {@code Phenotype} factory.
127 * @param count the number of individuals to add to this population.
128 * @return return this population, for command chaining.
129 */
130 public Population<G, C> fill(
131 final Factory<Phenotype<G, C>> factory,
132 final int count
133 ) {
134 for (int i = 0; i < count; ++i) {
135 _population.add(factory.newInstance());
136 }
137 return this;
138 }
139
140 /**
141 * Add {@code Phenotype} to the {@code Population}.
142 *
143 * @param phenotype {@code Phenotype} to be add.
144 * @throws NullPointerException if the given {@code phenotype} is
145 * {@code null}.
146 */
147 @Override
148 public boolean add(final Phenotype<G, C> phenotype) {
149 requireNonNull(phenotype, "Phenotype");
150 return _population.add(phenotype);
151 }
152
153 /**
154 * Add {@code Phenotype} to the {@code Population}.
155 *
156 * @param index Index of the
157 * @param phenotype {@code Phenotype} to be add.
158 * @throws NullPointerException if the given {@code phenotype} is
159 * {@code null}.
160 */
161 @Override
162 public void add(final int index, final Phenotype<G, C> phenotype) {
163 requireNonNull(phenotype, "Phenotype");
164 _population.add(index, phenotype);
165 }
166
167 @Override
168 public boolean addAll(final Collection<? extends Phenotype<G, C>> c) {
169 return _population.addAll(c);
170 }
171
172 @Override
173 public boolean addAll(int index, Collection<? extends Phenotype<G, C>> c) {
174 return _population.addAll(index, c);
175 }
176
177 @Override
178 public Phenotype<G, C> get(final int index) {
179 return _population.get(index);
180 }
181
182 @Override
183 public Phenotype<G, C> set(final int index, final Phenotype<G, C> pt) {
184 requireNonNull(pt, "Phenotype");
185 return _population.set(index, pt);
186 }
187
188 @Override
189 public Stream<Phenotype<G, C>> stream() {
190 return _population.stream();
191 }
192
193 public void remove(final Phenotype<G, C> phenotype) {
194 requireNonNull(phenotype, "Phenotype");
195 _population.remove(phenotype);
196 }
197
198 @Override
199 public boolean remove(final Object o) {
200 return _population.remove(o);
201 }
202
203 @Override
204 public boolean removeAll(final Collection<?> c) {
205 return _population.removeAll(c);
206 }
207
208 @Override
209 public Phenotype<G, C> remove(final int index) {
210 return _population.remove(index);
211 }
212
213 @Override
214 public void clear() {
215 _population.clear();
216 }
217
218 /**
219 * Sorting the phenotypes in this population according to its fitness
220 * value in descending order.
221 */
222 public void populationSort() {
223 sortWith(Optimize.MAXIMUM.descending());
224 }
225
226 /**
227 * Sort this population according the order defined by the given
228 * {@code comparator}.
229 *
230 * @param comparator the comparator which defines the sorting order.
231 * @throws java.lang.NullPointerException if the {@code comparator} is
232 * {@code null}.
233 */
234 public void sortWith(final Comparator<? super C> comparator) {
235 _population.sort((a, b) ->
236 comparator.compare(a.getFitness(), b.getFitness())
237 );
238 }
239
240 /**
241 * Reverse the order of the population.
242 */
243 public void reverse() {
244 Collections.reverse(_population);
245 }
246
247 @Override
248 public Iterator<Phenotype<G, C>> iterator() {
249 return _population.iterator();
250 }
251
252 @Override
253 public ListIterator<Phenotype<G, C>> listIterator() {
254 return _population.listIterator();
255 }
256
257 @Override
258 public ListIterator<Phenotype<G, C>> listIterator(final int index) {
259 return _population.listIterator(index);
260 }
261
262 @Override
263 public int size() {
264 return _population.size();
265 }
266
267 @Override
268 public boolean isEmpty() {
269 return _population.isEmpty();
270 }
271
272 @Override
273 public boolean contains(final Object o) {
274 return _population.contains(o);
275 }
276
277 @Override
278 public boolean containsAll(final Collection<?> c) {
279 return _population.containsAll(c);
280 }
281
282 @Override
283 public int indexOf(final Object o) {
284 return _population.indexOf(o);
285 }
286
287 @Override
288 public int lastIndexOf(final Object o) {
289 return _population.lastIndexOf(o);
290 }
291
292 @Override
293 public boolean retainAll(final Collection<?> c) {
294 return _population.retainAll(c);
295 }
296
297 @Override
298 public List<Phenotype<G, C>> subList(final int fromIndex, final int toIndex) {
299 return _population.subList(fromIndex, toIndex);
300 }
301
302 @Override
303 public Object[] toArray() {
304 return _population.toArray();
305 }
306
307 @Override
308 public <A> A[] toArray(final A[] a) {
309 return _population.toArray(a);
310 }
311
312 @Override
313 public Population<G, C> copy() {
314 return new Population<>(new ArrayList<>(_population), true);
315 }
316
317 @Override
318 public int hashCode() {
319 return Hash.of(getClass()).and(_population).value();
320 }
321
322 @Override
323 public boolean equals(final Object obj) {
324 return Equality.of(this, obj).test(p -> eq(_population, p._population));
325 }
326
327 @Override
328 public String toString() {
329 return _population.stream()
330 .map(Object::toString)
331 .collect(joining("\n", "", "\n"));
332 }
333
334 /**
335 * Return an empty population.
336 *
337 * @param <G> the gene type
338 * @param <C> the fitness result type
339 * @return an empty population
340 */
341 @SuppressWarnings("unchecked")
342 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
343 Population<G, C> empty() {
344 return (Population<G, C>)EMPTY;
345 }
346
347 /**
348 * Returns a {@code Collector} that accumulates the input elements into a
349 * new {@code Population}.
350 *
351 * @param <G> the gene type
352 * @param <C> the fitness result type
353 * @return a {@code Collector} which collects all the input elements into a
354 * {@code Population}, in encounter order
355 */
356 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
357 Collector<Phenotype<G, C>, ?, Population<G, C>> toPopulation() {
358 return Collector.of(
359 Population::new,
360 Population::add,
361 (left, right) -> { left.addAll(right); return left; }
362 );
363 }
364
365 /* *************************************************************************
366 * JAXB object serialization
367 * ************************************************************************/
368
369 @XmlRootElement(name = "population")
370 @XmlType(name = "org.jenetics.Population")
371 @XmlAccessorType(XmlAccessType.FIELD)
372 @SuppressWarnings({"unchecked", "rawtypes"})
373 static final class Model {
374
375 @XmlAttribute(name = "size", required = true)
376 public int size;
377
378 @XmlElement(name = "phenotype", required = true)
379 public List phenotypes;
380
381 public static final class Adapter
382 extends XmlAdapter<Model, Population>
383 {
384 @Override
385 public Model marshal(final Population p) throws Exception {
386 final Model model = new Model();
387 model.size = p.size();
388 if (!p.isEmpty()) {
389 model.phenotypes = (List)p.stream()
390 .map(jaxb.Marshaller(p.get(0)))
391 .collect(toList());
392 }
393
394 return model;
395 }
396
397 @Override
398 public Population unmarshal(final Model model) throws Exception {
399 return (Population)model.phenotypes.stream()
400 .map(jaxb.Unmarshaller(model.phenotypes.get(0)))
401 .collect(toPopulation());
402 }
403 }
404
405 }
406 }
|