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