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