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 — <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 p) throws 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 model) throws Exception {
377 return (Population)model.phenotypes.stream()
378 .map(jaxb.Unmarshaller(model.phenotypes.get(0)))
379 .collect(toPopulation());
380 }
381 }
382
383 }
384 }
|