LongChromosome.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.8.0).
003  * Copyright (c) 2007-2017 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.util.ISeq.toISeq;
023 
024 import java.io.IOException;
025 import java.io.ObjectInputStream;
026 import java.io.ObjectOutputStream;
027 import java.io.Serializable;
028 import java.util.List;
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.Equality;
040 import org.jenetics.internal.util.Hash;
041 
042 import org.jenetics.util.ISeq;
043 import org.jenetics.util.LongRange;
044 import org.jenetics.util.MSeq;
045 
046 /**
047  * Numeric chromosome implementation which holds 64 bit integer numbers.
048  *
049  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
050  @since 1.6
051  @version 3.2
052  */
053 @XmlJavaTypeAdapter(LongChromosome.Model.Adapter.class)
054 public class LongChromosome
055     extends AbstractBoundedChromosome<Long, LongGene>
056     implements
057         NumericChromosome<Long, LongGene>,
058         Serializable
059 {
060     private static final long serialVersionUID = 1L;
061 
062 
063     protected LongChromosome(final ISeq<LongGene> genes) {
064         super(genes);
065     }
066 
067     /**
068      * Create a new random {@code LongChromosome}.
069      *
070      @param min the min value of the {@link LongGene}s (inclusively).
071      @param max the max value of the {@link LongGene}s (inclusively).
072      @param length the length of the chromosome.
073      @throws NullPointerException if one of the arguments is {@code null}.
074      @throws IllegalArgumentException if the {@code length} is smaller than
075      *         one.
076      */
077     public LongChromosome(final Long min, final Long max, final int length) {
078         this(LongGene.seq(min, max, length));
079         _valid = true;
080     }
081 
082     /**
083      * Create a new random {@code LongChromosome} of length one.
084      *
085      @param min the minimal value of this chromosome (inclusively).
086      @param max the maximal value of this chromosome (inclusively).
087      @throws NullPointerException if one of the arguments is {@code null}.
088      */
089     public LongChromosome(final Long min, final Long max) {
090         this(min, max, 1);
091     }
092 
093     /**
094      * Returns an long array containing all of the elements in this chromosome
095      * in proper sequence.  If the chromosome fits in the specified array, it is
096      * returned therein. Otherwise, a new array is allocated with the length of
097      * this chromosome.
098      *
099      @since 3.0
100      *
101      @param array the array into which the elements of this chromosomes are to
102      *        be stored, if it is big enough; otherwise, a new array is
103      *        allocated for this purpose.
104      @return an array containing the elements of this chromosome
105      @throws NullPointerException if the given {@code array} is {@code null}
106      */
107     public long[] toArray(final long[] array) {
108         final long[] a = array.length >= length() ?
109             array : new long[length()];
110 
111         for (int i = length(); --i >= 0;) {
112             a[i= longValue(i);
113         }
114 
115         return a;
116     }
117 
118     /**
119      * Returns an long array containing all of the elements in this chromosome
120      * in proper sequence.
121      *
122      @since 3.0
123      *
124      @return an array containing the elements of this chromosome
125      */
126     public long[] toArray() {
127         return toArray(new long[length()]);
128     }
129 
130     /**
131      * Create a new {@code LongChromosome} with the given genes.
132      *
133      @param genes the genes of the chromosome.
134      @return a new chromosome with the given genes.
135      @throws IllegalArgumentException if the length of the genes array is
136      *         empty.
137      @throws NullPointerException if the given {@code genes} are {@code null}
138      */
139     public static LongChromosome of(final LongGene... genes) {
140         return new LongChromosome(ISeq.of(genes));
141     }
142 
143     /**
144      * Create a new random {@code LongChromosome}.
145      *
146      @param min the min value of the {@link LongGene}s (inclusively).
147      @param max the max value of the {@link LongGene}s (inclusively).
148      @param length the length of the chromosome.
149      @return a new {@code LongChromosome} with the given gene parameters.
150      @throws IllegalArgumentException if the {@code length} is smaller than
151      *         one.
152      */
153     public static LongChromosome of(
154         final long min,
155         final long max,
156         final int length
157     ) {
158         return new LongChromosome(min, max, length);
159     }
160 
161     /**
162      * Create a new random {@code LongChromosome}.
163      *
164      @since 3.2
165      *
166      @param range the long range of the chromosome.
167      @param length the length of the chromosome.
168      @return a new random {@code LongChromosome}
169      @throws NullPointerException if the given {@code range} is {@code null}
170      @throws IllegalArgumentException if the {@code length} is smaller than
171      *         one.
172      */
173     public static LongChromosome of(final LongRange range, final int length) {
174         return new LongChromosome(range.getMin(), range.getMax(), length);
175     }
176 
177     /**
178      * Create a new random {@code LongChromosome} of length one.
179      *
180      @param min the minimal value of this chromosome (inclusively).
181      @param max the maximal value of this chromosome (inclusively).
182      @return a new {@code LongChromosome} with the given gene parameters.
183      */
184     public static LongChromosome of(final long min, final long max) {
185         return new LongChromosome(min, max);
186     }
187 
188     /**
189      * Create a new random {@code LongChromosome} of length one.
190      *
191      @since 3.2
192      *
193      @param range the long range of the chromosome.
194      @return a new random {@code LongChromosome} of length one
195      @throws NullPointerException if the given {@code range} is {@code null}
196      */
197     public static LongChromosome of(final LongRange range) {
198         return new LongChromosome(range.getMin(), range.getMax());
199     }
200 
201     @Override
202     public LongChromosome newInstance(final ISeq<LongGene> genes) {
203         return new LongChromosome(genes);
204     }
205 
206     @Override
207     public LongChromosome newInstance() {
208         return new LongChromosome(_min, _max, length());
209     }
210 
211     @Override
212     public int hashCode() {
213         return Hash.of(getClass()).and(super.hashCode()).value();
214     }
215 
216     @Override
217     public boolean equals(final Object obj) {
218         return Equality.of(this, obj).test(super::equals);
219     }
220 
221     /* *************************************************************************
222      *  Java object serialization
223      * ************************************************************************/
224 
225     private void writeObject(final ObjectOutputStream out)
226         throws IOException
227     {
228         out.defaultWriteObject();
229 
230         out.writeInt(length());
231         out.writeLong(_min);
232         out.writeLong(_max);
233 
234         for (LongGene gene : _genes) {
235             out.writeLong(gene.getAllele());
236         }
237     }
238 
239     private void readObject(final ObjectInputStream in)
240         throws IOException, ClassNotFoundException
241     {
242         in.defaultReadObject();
243 
244         final MSeq<LongGene> genes = MSeq.ofLength(in.readInt());
245         _min = in.readLong();
246         _max = in.readLong();
247 
248         for (int i = 0; i < genes.length(); ++i) {
249             genes.set(i, new LongGene(in.readLong(), _min, _max));
250         }
251 
252         _genes = genes.toISeq();
253     }
254 
255     /* *************************************************************************
256      *  JAXB object serialization
257      * ************************************************************************/
258 
259     @XmlRootElement(name = "long-chromosome")
260     @XmlType(name = "org.jenetics.LongChromosome")
261     @XmlAccessorType(XmlAccessType.FIELD)
262     final static class Model {
263 
264         @XmlAttribute(name = "length", required = true)
265         public int length;
266 
267         @XmlAttribute(name = "min", required = true)
268         public long min;
269 
270         @XmlAttribute(name = "max", required = true)
271         public long max;
272 
273         @XmlElement(name = "allele", required = true, nillable = false)
274         public List<Long> values;
275 
276         public final static class Adapter
277             extends XmlAdapter<Model, LongChromosome>
278         {
279             @Override
280             public Model marshal(final LongChromosome c) {
281                 final Model m = new Model();
282                 m.length = c.length();
283                 m.min = c._min;
284                 m.max = c._max;
285                 m.values = c.toSeq().map(LongGene::getAllele).asList();
286                 return m;
287             }
288 
289             @Override
290             public LongChromosome unmarshal(final Model model) {
291                 final Long min = model.min;
292                 final Long max = model.max;
293                 return new LongChromosome(
294                     model.values.stream()
295                         .map(value -> new LongGene(value, min, max))
296                         .collect(toISeq())
297                 );
298             }
299         }
300     }
301 }