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.DoubleRange;
043 import org.jenetics.util.ISeq;
044 import org.jenetics.util.MSeq;
045
046 /**
047 * Numeric chromosome implementation which holds 64 bit floating point 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(DoubleChromosome.Model.Adapter.class)
054 public class DoubleChromosome
055 extends AbstractBoundedChromosome<Double, DoubleGene>
056 implements
057 NumericChromosome<Double, DoubleGene>,
058 Serializable
059 {
060 private static final long serialVersionUID = 1L;
061
062 /**
063 * Create a new chromosome from the given genes array.
064 *
065 * @param genes the genes of the new chromosome.
066 * @throws IllegalArgumentException if the gene sequence is empty
067 * @throws NullPointerException if the {@code genes} are {@code null}.
068 */
069 protected DoubleChromosome(final ISeq<DoubleGene> genes) {
070 super(genes);
071 }
072
073 /**
074 * Create a new random {@code DoubleChromosome}.
075 *
076 * @param min the min value of the {@link DoubleGene}s (inclusively).
077 * @param max the max value of the {@link DoubleGene}s (exclusively).
078 * @param length the length of the chromosome.
079 * @throws NullPointerException if one of the arguments is {@code null}.
080 * @throws IllegalArgumentException if the length is smaller than one
081 */
082 public DoubleChromosome(final Double min,final Double max,final int length) {
083 this(DoubleGene.seq(min, max, length));
084 _valid = true;
085 }
086
087 /**
088 * Create a new random {@code DoubleChromosome} of length one.
089 *
090 * @param min the minimal value of this chromosome (inclusively).
091 * @param max the maximal value of this chromosome (exclusively).
092 * @throws NullPointerException if one of the arguments is {@code null}.
093 */
094 public DoubleChromosome(final Double min, final Double max) {
095 this(min, max, 1);
096 }
097
098 /**
099 * Returns an double array containing all of the elements in this chromosome
100 * in proper sequence. If the chromosome fits in the specified array, it is
101 * returned therein. Otherwise, a new array is allocated with the length of
102 * this chromosome.
103 *
104 * @since 3.0
105 *
106 * @param array the array into which the elements of this chromosomes are to
107 * be stored, if it is big enough; otherwise, a new array is
108 * allocated for this purpose.
109 * @return an array containing the elements of this chromosome
110 * @throws NullPointerException if the given {@code array} is {@code null}
111 */
112 public double[] toArray(final double[] array) {
113 final double[] a = array.length >= length() ?
114 array : new double[length()];
115
116 for (int i = length(); --i >= 0;) {
117 a[i] = doubleValue(i);
118 }
119
120 return a;
121 }
122
123 /**
124 * Returns an double array containing all of the elements in this chromosome
125 * in proper sequence.
126 *
127 * @since 3.0
128 *
129 * @return an array containing the elements of this chromosome
130 */
131 public double[] toArray() {
132 return toArray(new double[length()]);
133 }
134
135 /**
136 * Create a new {@code DoubleChromosome} with the given genes.
137 *
138 * @param genes the genes of the chromosome.
139 * @return a new chromosome with the given genes.
140 * @throws IllegalArgumentException if the length of the genes array is
141 * empty.
142 */
143 public static DoubleChromosome of(final DoubleGene... genes) {
144 return new DoubleChromosome(ISeq.of(genes));
145 }
146
147 /**
148 * Create a new random {@code DoubleChromosome}.
149 *
150 * @param min the min value of the {@link DoubleGene}s (inclusively).
151 * @param max the max value of the {@link DoubleGene}s (exclusively).
152 * @param length the length of the chromosome.
153 * @return a new {@code DoubleChromosome} with the given parameter
154 * @throws IllegalArgumentException if the {@code length} is smaller than
155 * one.
156 */
157 public static DoubleChromosome of(
158 final double min,
159 double max,
160 final int length
161 ) {
162 return new DoubleChromosome(min, max, length);
163 }
164
165 /**
166 * Create a new random {@code DoubleChromosome}.
167 *
168 * @since 3.2
169 *
170 * @param range the integer range of the chromosome.
171 * @param length the length of the chromosome.
172 * @return a new random {@code DoubleChromosome}
173 * @throws NullPointerException if the given {@code range} is {@code null}
174 * @throws IllegalArgumentException if the {@code length} is smaller than
175 * one.
176 */
177 public static DoubleChromosome of(final DoubleRange range, final int length) {
178 return new DoubleChromosome(range.getMin(), range.getMax(), length);
179 }
180
181 /**
182 * Create a new random {@code DoubleChromosome} of length one.
183 *
184 * @param min the minimal value of this chromosome (inclusively).
185 * @param max the maximal value of this chromosome (exclusively).
186 * @return a new {@code DoubleChromosome} with the given parameter
187 */
188 public static DoubleChromosome of(final double min, final double max) {
189 return new DoubleChromosome(min, max);
190 }
191
192 /**
193 * Create a new random {@code DoubleChromosome} of length one.
194 *
195 * @since 3.2
196 *
197 * @param range the double range of the chromosome.
198 * @return a new random {@code DoubleChromosome} of length one
199 * @throws NullPointerException if the given {@code range} is {@code null}
200 */
201 public static DoubleChromosome of(final DoubleRange range) {
202 return new DoubleChromosome(range.getMin(), range.getMax());
203 }
204
205 @Override
206 public DoubleChromosome newInstance(final ISeq<DoubleGene> genes) {
207 return new DoubleChromosome(genes);
208 }
209
210 @Override
211 public DoubleChromosome newInstance() {
212 return new DoubleChromosome(_min, _max, length());
213 }
214
215 @Override
216 public int hashCode() {
217 return Hash.of(getClass()).and(super.hashCode()).value();
218 }
219
220 @Override
221 public boolean equals(final Object obj) {
222 return Equality.of(this, obj).test(super::equals);
223 }
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.writeDouble(_min);
237 out.writeDouble(_max);
238
239 for (DoubleGene gene : _genes) {
240 out.writeDouble(gene.getAllele());
241 }
242 }
243
244 private void readObject(final ObjectInputStream in)
245 throws IOException, ClassNotFoundException
246 {
247 in.defaultReadObject();
248
249 final MSeq<DoubleGene> genes = MSeq.ofLength(in.readInt());
250 _min = in.readDouble();
251 _max = in.readDouble();
252
253 for (int i = 0; i < genes.length(); ++i) {
254 genes.set(i, new DoubleGene(in.readDouble(), _min, _max));
255 }
256
257 _genes = genes.toISeq();
258 }
259
260 /* *************************************************************************
261 * JAXB object serialization
262 * ************************************************************************/
263
264 @XmlRootElement(name = "double-chromosome")
265 @XmlType(name = "org.jenetics.DoubleChromosome")
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 double min;
274
275 @XmlAttribute(name = "max", required = true)
276 public double max;
277
278 @XmlElement(name = "allele", required = true, nillable = false)
279 public List<Double> values;
280
281 public final static class Adapter
282 extends XmlAdapter<Model, DoubleChromosome>
283 {
284 @Override
285 public Model marshal(final DoubleChromosome 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(DoubleGene::getAllele).asList();
291 return m;
292 }
293
294 @Override
295 public DoubleChromosome unmarshal(final Model model) {
296 final Double min = model.min;
297 final Double max = model.max;
298 return new DoubleChromosome(
299 model.values.stream()
300 .map(value -> new DoubleGene(value, min, max))
301 .collect(toISeq())
302 );
303 }
304 }
305
306 }
307 }
|