Population.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.0.0).
003  * Copyright (c) 2007-2014 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 &mdash; <em>$Date: 2014-12-28 $</em>
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     private final List<Phenotype<G, C>> _population;
078 
079     private Population(final List<Phenotype<G, C>> population, boolean foo) {
080         _population = population;
081     }
082 
083     /**
084      * Constructs a population containing the elements of the specified collection,
085      * in the order they are returned by the collection's iterator.
086      *
087      @param population the collection whose elements are to be placed into
088      *         this list.
089      @throws NullPointerException if the specified population is {@code null}.
090      */
091     public Population(final Collection<Phenotype<G, C>> population) {
092         this(new ArrayList<>(population)true);
093     }
094 
095     /**
096      * Creating a new {@code Population} with the pre-allocated population
097      * size.
098      *
099      @param size Pre-allocated population size.
100      @throws IllegalArgumentException if the specified initial capacity is
101      *         negative
102      */
103     public Population(final int size) {
104         this(new ArrayList<>(size)true);
105     }
106 
107     /**
108      * Creating a new {@code Population}.
109      */
110     public Population() {
111         this(new ArrayList<>()true);
112     }
113 
114     /**
115      * Fills the population with individuals created by the given factory.
116      *
117      @param factory the {@code Phenotype} factory.
118      @param count the number of individuals to add to this population.
119      @return return this population, for command chaining.
120      */
121     public Population<G, C> fill(
122         final Factory<Phenotype<G, C>> factory,
123         final int count
124     ) {
125         for (int i = 0; i < count; ++i) {
126             _population.add(factory.newInstance());
127         }
128         return this;
129     }
130 
131     /**
132      * Add {@code Phenotype} to the {@code Population}.
133      *
134      @param phenotype {@code Phenotype} to be add.
135      @throws NullPointerException if the given {@code phenotype} is
136      *         {@code null}.
137      */
138     @Override
139     public boolean add(final Phenotype<G, C> phenotype) {
140         requireNonNull(phenotype, "Phenotype");
141         return _population.add(phenotype);
142     }
143 
144     /**
145      * Add {@code Phenotype} to the {@code Population}.
146      *
147      @param index Index of the
148      @param phenotype {@code Phenotype} to be add.
149      @throws NullPointerException if the given {@code phenotype} is
150      *         {@code null}.
151      */
152     @Override
153     public void add(final int index, final Phenotype<G, C> phenotype) {
154         requireNonNull(phenotype, "Phenotype");
155         _population.add(index, phenotype);
156     }
157 
158     @Override
159     public boolean addAll(final Collection<? extends Phenotype<G, C>> c) {
160         return _population.addAll(c);
161     }
162 
163     @Override
164     public boolean addAll(int index, Collection<? extends Phenotype<G, C>> c) {
165         return _population.addAll(index, c);
166     }
167 
168     @Override
169     public Phenotype<G, C> get(final int index) {
170         return _population.get(index);
171     }
172 
173     @Override
174     public Phenotype<G, C> set(final int index, final Phenotype<G, C> pt) {
175         requireNonNull(pt, "Phenotype");
176         return _population.set(index, pt);
177     }
178 
179     @Override
180     public Stream<Phenotype<G, C>> stream() {
181         return _population.stream();
182     }
183 
184     public void remove(final Phenotype<G, C> phenotype) {
185         requireNonNull(phenotype, "Phenotype");
186         _population.remove(phenotype);
187     }
188 
189     @Override
190     public boolean remove(final Object o) {
191         return _population.remove(o);
192     }
193 
194     @Override
195     public boolean removeAll(final Collection<?> c) {
196         return _population.removeAll(c);
197     }
198 
199     @Override
200     public Phenotype<G, C> remove(final int index) {
201         return _population.remove(index);
202     }
203 
204     @Override
205     public void clear() {
206         _population.clear();
207     }
208 
209     /**
210      * Sorting the phenotypes in this population according to its fitness
211      * value in descending order.
212      */
213     public void populationSort() {
214         sortWith(Optimize.MAXIMUM.descending());
215     }
216 
217     /**
218      * Sort this population according the order defined by the given
219      * {@code comparator}.
220      *
221      @param comparator the comparator which defines the sorting order.
222      @throws java.lang.NullPointerException if the {@code comparator} is
223      *         {@code null}.
224      */
225     public void sortWith(final Comparator<? super C> comparator) {
226         _population.sort((a, b->
227             comparator.compare(a.getFitness(), b.getFitness())
228         );
229     }
230 
231     /**
232      * Reverse the order of the population.
233      */
234     public void reverse() {
235         Collections.reverse(_population);
236     }
237 
238     @Override
239     public Iterator<Phenotype<G, C>> iterator() {
240         return _population.iterator();
241     }
242 
243     @Override
244     public ListIterator<Phenotype<G, C>> listIterator() {
245         return _population.listIterator();
246     }
247 
248     @Override
249     public ListIterator<Phenotype<G, C>> listIterator(final int index) {
250         return _population.listIterator(index);
251     }
252 
253     @Override
254     public int size() {
255         return _population.size();
256     }
257 
258     @Override
259     public boolean isEmpty() {
260         return _population.isEmpty();
261     }
262 
263     @Override
264     public boolean contains(final Object o) {
265         return _population.contains(o);
266     }
267 
268     @Override
269     public boolean containsAll(final Collection<?> c) {
270         return _population.containsAll(c);
271     }
272 
273     @Override
274     public int indexOf(final Object o) {
275         return _population.indexOf(o);
276     }
277 
278     @Override
279     public int lastIndexOf(final Object o) {
280         return _population.lastIndexOf(o);
281     }
282 
283     @Override
284     public boolean retainAll(final Collection<?> c) {
285         return _population.retainAll(c);
286     }
287 
288     @Override
289     public List<Phenotype<G, C>> subList(final int fromIndex, final int toIndex) {
290         return _population.subList(fromIndex, toIndex);
291     }
292 
293     @Override
294     public Object[] toArray() {
295         return _population.toArray();
296     }
297 
298     @Override
299     public <A> A[] toArray(final A[] a) {
300         return _population.toArray(a);
301     }
302 
303     @Override
304     public Population<G, C> copy() {
305         return new Population<>(new ArrayList<>(_population)true);
306     }
307 
308     @Override
309     public int hashCode() {
310         return Hash.of(getClass()).and(_population).value();
311     }
312 
313     @Override
314     public boolean equals(final Object obj) {
315         return Equality.of(this, obj).test(p -> eq(_population, p._population));
316     }
317 
318     @Override
319     public String toString() {
320         return _population.stream()
321             .map(Object::toString)
322             .collect(joining("\n""""\n"));
323     }
324 
325     /**
326      * Returns a {@code Collector} that accumulates the input elements into a
327      * new {@code Population}.
328      *
329      @param <G> the gene type
330      @param <C> the fitness result type
331      @return a {@code Collector} which collects all the input elements into a
332      *         {@code Population}, in encounter order
333      */
334     public static <G extends Gene<?, G>, C extends Comparable<? super C>>
335     Collector<Phenotype<G, C>, ?, Population<G, C>> toPopulation() {
336         return Collector.of(
337             Population::new,
338             Population::add,
339             (left, right-> left.addAll(right)return left; }
340         );
341     }
342 
343     /* *************************************************************************
344      *  JAXB object serialization
345      * ************************************************************************/
346 
347     @XmlRootElement(name = "population")
348     @XmlType(name = "org.jenetics.Population")
349     @XmlAccessorType(XmlAccessType.FIELD)
350     @SuppressWarnings({"unchecked""rawtypes"})
351     static final class Model {
352 
353         @XmlAttribute(name = "size", required = true)
354         public int size;
355 
356         @XmlElement(name = "phenotype", required = true)
357         public List phenotypes;
358 
359         public static final class Adapter
360             extends XmlAdapter<Model, Population>
361         {
362             @Override
363             public Model marshal(final Population pthrows Exception {
364                 final Model model = new Model();
365                 model.size = p.size();
366                 if (!p.isEmpty()) {
367                     model.phenotypes = (List)p.stream()
368                         .map(jaxb.Marshaller(p.get(0)))
369                         .collect(toList());
370                 }
371 
372                 return model;
373             }
374 
375             @Override
376             public Population unmarshal(final Model modelthrows Exception {
377                 return (Population)model.phenotypes.stream()
378                     .map(jaxb.Unmarshaller(model.phenotypes.get(0)))
379                     .collect(toPopulation());
380             }
381         }
382 
383     }
384 }