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