Genotype.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.5.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 org.jenetics.internal.util.Equality.eq;
023 import static org.jenetics.util.ISeq.toISeq;
024 
025 import java.io.Serializable;
026 import java.util.Iterator;
027 import java.util.List;
028 import java.util.stream.Stream;
029 
030 import javax.xml.bind.annotation.XmlAccessType;
031 import javax.xml.bind.annotation.XmlAccessorType;
032 import javax.xml.bind.annotation.XmlAttribute;
033 import javax.xml.bind.annotation.XmlElement;
034 import javax.xml.bind.annotation.XmlRootElement;
035 import javax.xml.bind.annotation.XmlType;
036 import javax.xml.bind.annotation.adapters.XmlAdapter;
037 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
038 
039 import org.jenetics.internal.util.Hash;
040 import org.jenetics.internal.util.jaxb;
041 import org.jenetics.internal.util.reflect;
042 
043 import org.jenetics.util.Factory;
044 import org.jenetics.util.ISeq;
045 import org.jenetics.util.MSeq;
046 import org.jenetics.util.Seq;
047 import org.jenetics.util.Verifiable;
048 
049 /**
050  * The central class the GA is working with, is the {@code Genotype}. It is the
051  * structural representative of an individual. This class is the encoded problem
052  * solution with one to many {@link Chromosome}.
053  <p>
054  <img alt="Genotype" src="doc-files/Genotype.svg" width="400" height="252" >
055  </p>
056  * The chromosomes of a genotype doesn't have to have necessarily the same size.
057  * It is only required that all genes are from the same type and the genes within
058  * a chromosome have the same constraints; e. g. the same min- and max values
059  * for number genes.
060  *
061  <pre>{@code
062  * final Genotype<DoubleGene> genotype = Genotype.of(
063  *     DoubleChromosome.of(0.0, 1.0, 8),
064  *     DoubleChromosome.of(1.0, 2.0, 10),
065  *     DoubleChromosome.of(0.0, 10.0, 9),
066  *     DoubleChromosome.of(0.1, 0.9, 5)
067  * );
068  * }</pre>
069  * The code snippet above creates a genotype with the same structure as shown in
070  * the figure above. In this example the {@link DoubleGene} has been chosen as
071  * gene type.
072  *
073  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
074  @since 1.0
075  @version 3.0
076  */
077 @XmlJavaTypeAdapter(Genotype.Model.Adapter.class)
078 public final class Genotype<G extends Gene<?, G>>
079     implements
080         Factory<Genotype<G>>,
081         Iterable<Chromosome<G>>,
082         Verifiable,
083         Serializable
084 {
085     private static final long serialVersionUID = 3L;
086 
087     private final ISeq<Chromosome<G>> _chromosomes;
088     private final int _ngenes;
089 
090     //Caching isValid value.
091     private volatile Boolean _valid = null;
092 
093     private Genotype(
094         final ISeq<? extends Chromosome<G>> chromosomes,
095         final int ngenes
096     ) {
097         if (chromosomes.isEmpty()) {
098             throw new IllegalArgumentException("No chromosomes given.");
099         }
100 
101         _chromosomes = reflect.cast(chromosomes);
102         _ngenes = ngenes;
103     }
104 
105     /**
106      * Create a new Genotype from a given sequence of {@code Chromosomes}.
107      *
108      @param chromosomes The {@code Chromosome} array the {@code Genotype}
109      *         consists of.
110      @throws NullPointerException if {@code chromosomes} is null or one of its
111      *         element.
112      @throws IllegalArgumentException if {@code chromosome.length == 0}.
113      */
114     Genotype(final ISeq<? extends Chromosome<G>> chromosomes) {
115         this(chromosomes, ngenes(chromosomes));
116     }
117 
118     private static int ngenes(final Seq<? extends Chromosome<?>> chromosomes) {
119         return chromosomes.stream()
120             .mapToInt(c -> c.length())
121             .sum();
122     }
123 
124     /**
125      * Return the chromosome at the given index. It is guaranteed, that the
126      * returned chromosome is not null.
127      *
128      @param index Chromosome index.
129      @return The Chromosome.
130      @throws IndexOutOfBoundsException if
131      *         {@code (index < 0 || index >= _length)}.
132      */
133     public Chromosome<G> getChromosome(final int index) {
134         assert _chromosomes != null;
135         assert _chromosomes.get(index!= null;
136 
137         return _chromosomes.get(index);
138     }
139 
140     /**
141      * Return the first chromosome. This is a shortcut for
142      <pre>{@code
143      * final Genotype<DoubleGene>; gt = ...
144      * final Chromosome<DoubleGene> chromosome = gt.getChromosome(0);
145      * }</pre>
146      *
147      @return The first chromosome.
148      */
149     public Chromosome<G> getChromosome() {
150         assert _chromosomes != null;
151         assert _chromosomes.get(0!= null;
152 
153         return _chromosomes.get(0);
154     }
155 
156     /**
157      * Return the first {@link Gene} of the first {@link Chromosome} of this
158      * {@code Genotype}. This is a shortcut for
159      <pre>{@code
160      * final Genotype<DoubleGene> gt = ...
161      * final DoubleGene gene = gt.getChromosome(0).getGene(0);
162      * }</pre>
163      *
164      @return the first {@link Gene} of the first {@link Chromosome} of this
165      *         {@code Genotype}.
166      */
167     public G getGene() {
168         assert _chromosomes != null;
169         assert _chromosomes.get(0!= null;
170 
171         return _chromosomes.get(0).getGene();
172     }
173 
174     /**
175      * Return the gene from the given chromosome- and gene index. This is a
176      * shortcut for {@code gt.getChromosome(chromosomeIndex).getGene(geneIndex)}.
177      *
178      @since 3.0
179      *
180      @param chromosomeIndex the chromosome index
181      @param geneIndex the gene index within the chromosome
182      @return the gene with the given indexes
183      @throws IndexOutOfBoundsException if the given indexes are not within the
184      *         allowed range
185      */
186     public G get(final int chromosomeIndex, final int geneIndex) {
187         return getChromosome(chromosomeIndex).getGene(geneIndex);
188     }
189 
190     public ISeq<Chromosome<G>> toSeq() {
191         return _chromosomes;
192     }
193 
194     @Override
195     public Iterator<Chromosome<G>> iterator() {
196         return _chromosomes.iterator();
197     }
198 
199     /**
200      * Returns a sequential {@code Stream} of chromosomes with this genotype as
201      * its source.
202      *
203      @since 3.4
204      *
205      @return a sequential {@code Stream} of chromosomes
206      */
207     public Stream<Chromosome<G>> stream() {
208         return _chromosomes.stream();
209     }
210 
211     /**
212      * Getting the number of chromosomes of this genotype.
213      *
214      @return number of chromosomes.
215      */
216     public int length() {
217         return _chromosomes.length();
218     }
219 
220     /**
221      * Return the number of genes this genotype consists of. This is the sum of
222      * the number of genes of the genotype chromosomes.
223      *
224      @return Return the number of genes this genotype consists of.
225      */
226     public int getNumberOfGenes() {
227         return _ngenes;
228     }
229 
230     /**
231      * Test if this genotype is valid. A genotype is valid if all its
232      {@link Chromosome}s are valid.
233      *
234      @return true if this genotype is valid, false otherwise.
235      */
236     @Override
237     public boolean isValid() {
238         Boolean valid = _valid;
239         if (valid == null) {
240             valid = _chromosomes.forAll(Verifiable::isValid);
241             _valid = valid;
242         }
243 
244         return _valid;
245     }
246 
247     /**
248      * Return a new, random genotype by creating new, random chromosomes (calling
249      * the {@link Chromosome#newInstance()} method) from the chromosomes of this
250      * genotype.
251      */
252     @Override
253     public Genotype<G> newInstance() {
254         return new Genotype<>(_chromosomes.map(Factory::newInstance), _ngenes);
255     }
256 
257     Genotype<G> newInstance(final ISeq<Chromosome<G>> chromosomes) {
258         return new Genotype<>(chromosomes, _ngenes);
259     }
260 
261     @Override
262     public int hashCode() {
263         return Hash.of(getClass()).and(_chromosomes).value();
264     }
265 
266     @Override
267     public boolean equals(final Object obj) {
268         return obj instanceof Genotype<?> &&
269             eq(_chromosomes, ((Genotype<?>)obj)._chromosomes);
270     }
271 
272     @Override
273     public String toString() {
274         return _chromosomes.toString();
275     }
276 
277     /**
278      * Create a new {@code Genotype} from a given array of {@code Chromosomes}.
279      *
280      @since 3.0
281      *
282      @param <G> the gene type
283      @param first the first {@code Chromosome} of the {@code Genotype}
284      @param rest the rest of the genotypes chromosomes.
285      @return a new {@code Genotype} from the given chromosomes
286      @throws NullPointerException if {@code chromosomes} is {@code null} or
287      *         one of its element.
288      */
289     @SafeVarargs
290     public static <G extends Gene<?, G>> Genotype<G> of(
291         final Chromosome<G> first,
292         final Chromosome<G>... rest
293     ) {
294         final MSeq<Chromosome<G>> seq = MSeq.ofLength(+ rest.length);
295         seq.set(0, first);
296         for (int i = 0; i < rest.length; ++i) {
297             seq.set(i + 1, rest[i]);
298         }
299         return new Genotype<>(seq.toISeq());
300     }
301 
302     /**
303      * Create a new {@code Genotype} which consists of {@code n} chromosomes,
304      * which are created by the given {@code factory}. This method can be used
305      * for easily creating a <i>gene matrix</i>. The following example will
306      * create a 10x5 {@code DoubleGene} <i>matrix</i>.
307      *
308      <pre>{@code
309      * final Genotype<DoubleGene> gt = Genotype
310      *     .of(DoubleChromosome.of(0.0, 1.0, 10), 5);
311      * }</pre>
312      *
313      @since 3.0
314      *
315      @param <G> the gene type
316      @param factory the factory which creates the chromosomes this genotype
317      *        consists of
318      @param n the number of chromosomes this genotype consists of
319      @return new {@code Genotype} containing {@code n} chromosomes
320      @throws IllegalArgumentException if {@code n < 1}.
321      @throws NullPointerException if the {@code factory} is {@code null}.
322      */
323     public static <G extends Gene<?, G>> Genotype<G>
324     of(final Factory<? extends Chromosome<G>> factory, final int n) {
325         final ISeq<Chromosome<G>> ch = ISeq.of(factory::newInstance, n);
326         return new Genotype<>(ch);
327     }
328 
329     /**
330      * Create a new {@code Genotype} from a given array of {@code chromosomes}.
331      *
332      @since 3.0
333      *
334      @param <G> the gene type
335      @param chromosomes the {@code Chromosome}s the returned genotype consists
336      *        of
337      @return a new {@code Genotype} from the given chromosomes
338      @throws NullPointerException if {@code chromosomes} is {@code null} or
339      *         one of its element.
340      @throws IllegalArgumentException if {@code chromosome.length() < 1}.
341      */
342     public static <G extends Gene<?, G>> Genotype<G>
343     of(final Iterable<? extends Chromosome<G>> chromosomes) {
344         return new Genotype<>(ISeq.of(chromosomes));
345     }
346 
347     /* *************************************************************************
348      *  JAXB object serialization
349      * ************************************************************************/
350 
351     @XmlRootElement(name = "genotype")
352     @XmlType(name = "org.jenetics.Genotype")
353     @XmlAccessorType(XmlAccessType.FIELD)
354     @SuppressWarnings({"unchecked""rawtypes"})
355     static final class Model {
356 
357         @XmlAttribute(name = "length", required = true)
358         public int length;
359 
360         @XmlAttribute(name = "ngenes", required = true)
361         public int ngenes;
362 
363         @XmlElement(name = "chromosome", required = true, nillable = false)
364         public List chromosomes;
365 
366         public static final class Adapter
367             extends XmlAdapter<Model, Genotype>
368         {
369             @Override
370             public Model marshal(final Genotype gtthrows Exception {
371                 final Model model = new Model();
372                 model.length = gt.length();
373                 model.ngenes = gt.getNumberOfGenes();
374                 model.chromosomes = gt.toSeq()
375                     .map(jaxb.Marshaller(gt.getChromosome()))
376                     .asList();
377 
378                 return model;
379             }
380 
381             @Override
382             public Genotype unmarshal(final Model modelthrows Exception {
383                 final ISeq chs = (ISeq)model.chromosomes.stream()
384                     .map(jaxb.Unmarshaller(model.chromosomes.get(0)))
385                     .collect(toISeq());
386 
387                 return new Genotype(chs, model.ngenes);
388             }
389         }
390 
391         public static final Adapter ADAPTER = new Adapter();
392     }
393 }