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.jenetix;
021
022 import static java.util.Objects.requireNonNull;
023 import static org.jenetics.util.RandomRegistry.getRandom;
024 import static org.jenetix.internal.random.nextBigInteger;
025
026 import java.io.Serializable;
027 import java.math.BigInteger;
028 import java.util.Random;
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.XmlRootElement;
034 import javax.xml.bind.annotation.XmlType;
035 import javax.xml.bind.annotation.XmlValue;
036 import javax.xml.bind.annotation.adapters.XmlAdapter;
037 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
038
039 import org.jenetics.internal.util.Hash;
040 import org.jenetics.internal.util.require;
041
042 import org.jenetics.NumericGene;
043 import org.jenetics.util.ISeq;
044 import org.jenetics.util.MSeq;
045 import org.jenetics.util.Mean;
046 import org.jenetics.util.RandomRegistry;
047
048 /**
049 * Numeric chromosome implementation which holds an arbitrary sized integer
050 * number.
051 *
052 * <p>This is a <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html">
053 * value-based</a> class; use of identity-sensitive operations (including
054 * reference equality ({@code ==}), identity hash code, or synchronization) on
055 * instances of {@code IntegerGene} may have unpredictable results and should
056 * be avoided.
057 *
058 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
059 * @since 3.5
060 * @version 3.5
061 */
062 @XmlJavaTypeAdapter(BigIntegerGene.Model.Adapter.class)
063 public final class BigIntegerGene
064 implements
065 NumericGene<BigInteger, BigIntegerGene>,
066 Mean<BigIntegerGene>,
067 Serializable
068 {
069 private static final long serialVersionUID = 1L;
070
071 private static final BigInteger TWO = BigInteger.valueOf(2);
072
073 private final BigInteger _value;
074 private final BigInteger _min;
075 private final BigInteger _max;
076
077 private BigIntegerGene(
078 final BigInteger value,
079 final BigInteger min,
080 final BigInteger max
081 ) {
082 _value = requireNonNull(value);
083 _min = requireNonNull(min);
084 _max = requireNonNull(max);
085 }
086
087 @Override
088 public BigInteger getAllele() {
089 return _value;
090 }
091
092 @Override
093 public BigInteger getMin() {
094 return _min;
095 }
096
097 @Override
098 public BigInteger getMax() {
099 return _max;
100 }
101
102 @Override
103 public BigIntegerGene mean(final BigIntegerGene that) {
104 final BigInteger value = _value.add(that._value).divide(TWO);
105 return of(value, _min, _max);
106 }
107
108 @Override
109 public BigIntegerGene newInstance(final Number number) {
110 return of(BigInteger.valueOf(number.longValue()), _min, _max);
111 }
112
113 @Override
114 public BigIntegerGene newInstance(final BigInteger value) {
115 return of(value, _min, _max);
116 }
117
118 @Override
119 public BigIntegerGene newInstance() {
120 return of(_min, _max);
121 }
122
123 @Override
124 public int hashCode() {
125 return Hash.of(getClass())
126 .and(_value)
127 .and(_min)
128 .and(_max).value();
129 }
130
131 @Override
132 public boolean equals(final Object obj) {
133 return obj instanceof BigIntegerGene &&
134 ((BigIntegerGene)obj)._value.equals(_value) &&
135 ((BigIntegerGene)obj)._min.equals(_min) &&
136 ((BigIntegerGene)obj)._max.equals(_max);
137 }
138
139 @Override
140 public String toString() {
141 return String.format("[%s]", _value);
142 }
143
144 /* *************************************************************************
145 * Static factory methods.
146 **************************************************************************/
147
148 static ISeq<BigIntegerGene> seq(
149 final BigInteger minimum,
150 final BigInteger maximum,
151 final int length
152 ) {
153 require.positive(length);
154
155 final Random r = getRandom();
156
157 return MSeq.<BigIntegerGene>ofLength(length)
158 .fill(() -> new BigIntegerGene(
159 nextBigInteger(r, minimum, maximum), minimum, maximum))
160 .toISeq();
161 }
162
163 /**
164 * Create a new random {@code BigIntegerGene} with the given value and the
165 * given range. If the {@code value} isn't within the interval [min, max],
166 * no exception is thrown. In this case the method
167 * {@link BigIntegerGene#isValid()} returns {@code false}.
168 *
169 * @param value the value of the gene.
170 * @param min the minimal valid value of this gene (inclusively).
171 * @param max the maximal valid value of this gene (inclusively).
172 * @return a new random {@code BigIntegerGene}
173 * @throws NullPointerException if one of the arguments is {@code null}
174 */
175 public static BigIntegerGene of(
176 final BigInteger value,
177 final BigInteger min,
178 final BigInteger max
179 ) {
180 return new BigIntegerGene(value, min, max);
181 }
182
183 /**
184 * Create a new random {@code BigIntegerGene}. It is guaranteed that the
185 * value of the {@code BigIntegerGene} lies in the interval [min, max].
186 *
187 * @param min the minimal valid value of this gene (inclusively).
188 * @param max the maximal valid value of this gene (inclusively).
189 * @return a new random {@code BigIntegerGene}
190 * @throws NullPointerException if one of the arguments is {@code null}
191 */
192 public static BigIntegerGene of(final BigInteger min, final BigInteger max) {
193 return of(
194 nextBigInteger(RandomRegistry.getRandom(), min, max),
195 min,
196 max
197 );
198 }
199
200
201 /* *************************************************************************
202 * JAXB object serialization
203 * ************************************************************************/
204
205 @XmlRootElement(name = "big-integer-gene")
206 @XmlType(name = "org.jenetix.BigIntegerGene")
207 @XmlAccessorType(XmlAccessType.FIELD)
208 final static class Model {
209
210 @XmlAttribute(name = "min", required = true)
211 public BigInteger min;
212
213 @XmlAttribute(name = "max", required = true)
214 public BigInteger max;
215
216 @XmlValue
217 public BigInteger value;
218
219 public final static class Adapter
220 extends XmlAdapter<Model, BigIntegerGene>
221 {
222 @Override
223 public Model marshal(final BigIntegerGene value) {
224 final Model m = new Model();
225 m.min = value.getMin();
226 m.max = value.getMax();
227 m.value = value.getAllele();
228 return m;
229 }
230
231 @Override
232 public BigIntegerGene unmarshal(final Model m) {
233 return BigIntegerGene.of(m.value, m.min, m.max);
234 }
235 }
236 }
237
238 }
|