001 /*
002 * Java Genetic Algorithm Library (jenetics-4.0.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@gmail.com)
019 */
020 package io.jenetics;
021
022 import java.io.IOException;
023 import java.io.ObjectInputStream;
024 import java.io.ObjectOutputStream;
025 import java.io.Serializable;
026
027 import io.jenetics.internal.util.Equality;
028 import io.jenetics.internal.util.Hash;
029 import io.jenetics.internal.util.reflect;
030 import io.jenetics.util.DoubleRange;
031 import io.jenetics.util.ISeq;
032 import io.jenetics.util.IntRange;
033 import io.jenetics.util.MSeq;
034
035 /**
036 * Numeric chromosome implementation which holds 64 bit floating point numbers.
037 *
038 * @see DoubleGene
039 *
040 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
041 * @since 1.6
042 * @version 4.0
043 */
044 public class DoubleChromosome
045 extends AbstractBoundedChromosome<Double, DoubleGene>
046 implements
047 NumericChromosome<Double, DoubleGene>,
048 Serializable
049 {
050 private static final long serialVersionUID = 2L;
051
052 /**
053 * Create a new chromosome from the given {@code genes} and the allowed
054 * length range of the chromosome.
055 *
056 * @since 4.0
057 *
058 * @param genes the genes that form the chromosome.
059 * @param lengthRange the allowed length range of the chromosome
060 * @throws NullPointerException if one of the arguments is {@code null}.
061 * @throws IllegalArgumentException if the length of the gene sequence is
062 * empty, doesn't match with the allowed length range, the minimum
063 * or maximum of the range is smaller or equal zero or the given
064 * range size is zero.
065 */
066 protected DoubleChromosome(
067 final ISeq<DoubleGene> genes,
068 final IntRange lengthRange
069 ) {
070 super(genes, lengthRange);
071 }
072
073 /**
074 * Create a new random chromosome.
075 *
076 * @since 4.0
077 *
078 * @param min the min value of the {@link DoubleGene}s (inclusively).
079 * @param max the max value of the {@link DoubleGene}s (exclusively).
080 * @param lengthRange the allowed length range of the chromosome.
081 * @throws NullPointerException if one of the arguments is {@code null}.
082 * @throws IllegalArgumentException if the length is smaller than one
083 */
084 public DoubleChromosome(
085 final Double min,
086 final Double max,
087 final IntRange lengthRange
088 ) {
089 this(DoubleGene.seq(min, max, lengthRange), lengthRange);
090 _valid = true;
091 }
092
093 /**
094 * Create a new random {@code DoubleChromosome}.
095 *
096 * @param min the min value of the {@link DoubleGene}s (inclusively).
097 * @param max the max value of the {@link DoubleGene}s (exclusively).
098 * @param length the length of the chromosome.
099 * @throws NullPointerException if one of the arguments is {@code null}.
100 * @throws IllegalArgumentException if the length is smaller than one
101 */
102 public DoubleChromosome(final Double min,final Double max,final int length) {
103 this(min, max, IntRange.of(length));
104 }
105
106 /**
107 * Create a new random {@code DoubleChromosome} of length one.
108 *
109 * @param min the minimal value of this chromosome (inclusively).
110 * @param max the maximal value of this chromosome (exclusively).
111 * @throws NullPointerException if one of the arguments is {@code null}.
112 */
113 public DoubleChromosome(final Double min, final Double max) {
114 this(min, max, 1);
115 }
116
117 /**
118 * Returns an double array containing all of the elements in this chromosome
119 * in proper sequence. If the chromosome fits in the specified array, it is
120 * returned therein. Otherwise, a new array is allocated with the length of
121 * this chromosome.
122 *
123 * @since 3.0
124 *
125 * @param array the array into which the elements of this chromosomes are to
126 * be stored, if it is big enough; otherwise, a new array is
127 * allocated for this purpose.
128 * @return an array containing the elements of this chromosome
129 * @throws NullPointerException if the given {@code array} is {@code null}
130 */
131 public double[] toArray(final double[] array) {
132 final double[] a = array.length >= length() ? array : new double[length()];
133 for (int i = length(); --i >= 0;) {
134 a[i] = doubleValue(i);
135 }
136
137 return a;
138 }
139
140 /**
141 * Returns an double array containing all of the elements in this chromosome
142 * in proper sequence.
143 *
144 * @since 3.0
145 *
146 * @return an array containing the elements of this chromosome
147 */
148 public double[] toArray() {
149 return toArray(new double[length()]);
150 }
151
152 /**
153 * Create a new {@code DoubleChromosome} with the given genes.
154 *
155 * @param genes the genes of the chromosome.
156 * @return a new chromosome with the given genes.
157 * @throws IllegalArgumentException if the length of the genes array is
158 * empty.
159 */
160 public static DoubleChromosome of(final DoubleGene... genes) {
161 return new DoubleChromosome(ISeq.of(genes), IntRange.of(genes.length));
162 }
163
164 /**
165 * Create a new random chromosome.
166 *
167 * @since 4.0
168 *
169 * @param min the min value of the {@link DoubleGene}s (inclusively).
170 * @param max the max value of the {@link DoubleGene}s (exclusively).
171 * @param lengthRange the allowed length range of the chromosome.
172 * @return a new {@code DoubleChromosome} with the given parameter
173 * @throws IllegalArgumentException if the length of the gene sequence is
174 * empty, doesn't match with the allowed length range, the minimum
175 * or maximum of the range is smaller or equal zero or the given
176 * range size is zero.
177 * @throws NullPointerException if the given {@code lengthRange} is
178 * {@code null}
179 */
180 public static DoubleChromosome of(
181 final double min,
182 final double max,
183 final IntRange lengthRange
184 ) {
185 return new DoubleChromosome(min, max, lengthRange);
186 }
187
188 /**
189 * Create a new random {@code DoubleChromosome}.
190 *
191 * @param min the min value of the {@link DoubleGene}s (inclusively).
192 * @param max the max value of the {@link DoubleGene}s (exclusively).
193 * @param length the length of the chromosome.
194 * @return a new {@code DoubleChromosome} with the given parameter
195 * @throws IllegalArgumentException if the {@code length} is smaller than
196 * one.
197 */
198 public static DoubleChromosome of(
199 final double min,
200 final double max,
201 final int length
202 ) {
203 return new DoubleChromosome(min, max, length);
204 }
205
206 /**
207 * Create a new random chromosome.
208 *
209 * @since 4.0
210 *
211 * @param range the integer range of the chromosome.
212 * @param lengthRange the allowed length range of the chromosome.
213 * @return a new {@code DoubleChromosome} with the given parameter
214 * @throws IllegalArgumentException if the length of the gene sequence is
215 * empty, doesn't match with the allowed length range, the minimum
216 * or maximum of the range is smaller or equal zero or the given
217 * range size is zero.
218 * @throws NullPointerException if the given {@code lengthRange} is
219 * {@code null}
220 */
221 public static DoubleChromosome of(
222 final DoubleRange range,
223 final IntRange lengthRange
224 ) {
225 return new DoubleChromosome(range.getMin(), range.getMax(), lengthRange);
226 }
227
228 /**
229 * Create a new random {@code DoubleChromosome}.
230 *
231 * @since 3.2
232 *
233 * @param range the integer range of the chromosome.
234 * @param length the length of the chromosome.
235 * @return a new random {@code DoubleChromosome}
236 * @throws NullPointerException if the given {@code range} is {@code null}
237 * @throws IllegalArgumentException if the {@code length} is smaller than
238 * one.
239 */
240 public static DoubleChromosome of(final DoubleRange range, final int length) {
241 return new DoubleChromosome(range.getMin(), range.getMax(), length);
242 }
243
244 /**
245 * Create a new random {@code DoubleChromosome} of length one.
246 *
247 * @param min the minimal value of this chromosome (inclusively).
248 * @param max the maximal value of this chromosome (exclusively).
249 * @return a new {@code DoubleChromosome} with the given parameter
250 */
251 public static DoubleChromosome of(final double min, final double max) {
252 return new DoubleChromosome(min, max);
253 }
254
255 /**
256 * Create a new random {@code DoubleChromosome} of length one.
257 *
258 * @since 3.2
259 *
260 * @param range the double range of the chromosome.
261 * @return a new random {@code DoubleChromosome} of length one
262 * @throws NullPointerException if the given {@code range} is {@code null}
263 */
264 public static DoubleChromosome of(final DoubleRange range) {
265 return new DoubleChromosome(range.getMin(), range.getMax());
266 }
267
268 @Override
269 public DoubleChromosome newInstance(final ISeq<DoubleGene> genes) {
270 return new DoubleChromosome(genes, lengthRange());
271 }
272
273 @Override
274 public DoubleChromosome newInstance() {
275 return new DoubleChromosome(_min, _max, lengthRange());
276 }
277
278 @Override
279 public int hashCode() {
280 return Hash.of(getClass()).and(super.hashCode()).value();
281 }
282
283 @Override
284 public boolean equals(final Object obj) {
285 return Equality.of(this, obj).test(super::equals);
286 }
287
288
289 /* *************************************************************************
290 * Java object serialization
291 * ************************************************************************/
292
293 private void writeObject(final ObjectOutputStream out)
294 throws IOException
295 {
296 out.defaultWriteObject();
297
298 out.writeInt(length());
299 out.writeObject(lengthRange());
300 out.writeDouble(_min);
301 out.writeDouble(_max);
302
303 for (DoubleGene gene : _genes) {
304 out.writeDouble(gene.getAllele());
305 }
306 }
307
308 private void readObject(final ObjectInputStream in)
309 throws IOException, ClassNotFoundException
310 {
311 in.defaultReadObject();
312
313 final MSeq<DoubleGene> genes = MSeq.ofLength(in.readInt());
314 reflect.setField(this, "_lengthRange", in.readObject());
315 reflect.setField(this, "_min", in.readDouble());
316 reflect.setField(this, "_max", in.readDouble());
317
318 for (int i = 0; i < genes.length(); ++i) {
319 genes.set(i, new DoubleGene(in.readDouble(), _min, _max));
320 }
321
322 reflect.setField(this, "_genes", genes.toISeq());
323 }
324
325 }
|