Population.java
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 pthrows 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 modelthrows Exception {
399                 return (Population)model.phenotypes.stream()
400                     .map(jaxb.Unmarshaller(model.phenotypes.get(0)))
401                     .collect(toPopulation());
402             }
403         }
404 
405     }
406 }