001 /*
002 * Java Genetic Algorithm Library (jenetics-1.5.0).
003 * Copyright (c) 2007-2013 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 java.util.Objects.requireNonNull;
023 import static org.jenetics.util.object.eq;
024 import static org.jenetics.util.object.hashCodeOf;
025
026 import javolution.text.Text;
027 import javolution.text.TextBuilder;
028 import javolution.xml.XMLSerializable;
029
030 import org.jscience.mathematics.number.Number;
031
032 import org.jenetics.util.Mean;
033
034 /**
035 * Abstract base class for implementing concrete NumberGenes.
036 *
037 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
038 * @since 1.0
039 * @version 1.2 — <em>$Date: 2013-11-28 $</em>
040 */
041 public abstract class NumberGene<
042 N extends Number<N>,
043 G extends NumberGene<N, G>
044 >
045 extends Number<G>
046 implements
047 Gene<N, G>,
048 Mean<G>,
049 XMLSerializable
050 {
051 private static final long serialVersionUID = 1L;
052
053 /**
054 * The minimum value of this {@code NumberGene}. This field is marked
055 * as transient and must serialized manually by sub classes.
056 */
057 protected transient N _min;
058
059 /**
060 * The maximum value of this {@code NumberGene}. This field is marked
061 * as transient and must serialized manually by sub classes.
062 */
063 protected transient N _max;
064
065 /**
066 * The value of this {@code NumberGene}. This field is marked
067 * as transient and must serialized manually by sub classes.
068 */
069 protected transient N _value;
070
071 private transient boolean _valid = true;
072
073 protected NumberGene() {
074 }
075
076 /**
077 * Boxes a given Java number into the required number object.
078 *
079 * @param value the Java number to box.
080 * @return the boxed number.
081 */
082 protected abstract N box(final java.lang.Number value);
083
084 /**
085 * Create a new gene from the given {@code value}.
086 *
087 * @param value the value of the new gene.
088 * @return a new gene with the given value.
089 */
090 public abstract G newInstance(final N value);
091
092 @Override
093 public G copy() {
094 return newInstance(_value);
095 }
096
097 /**
098 * Create a new NumberGene with the same limits and the given value.
099 *
100 * @param value The value of the new NumberGene.
101 * @return The new NumberGene.
102 * @throws NullPointerException if the given {@code value} is {@code null}.
103 */
104 public G newInstance(final java.lang.Number value) {
105 return newInstance(box(value));
106 }
107
108 /**
109 * Set the {@code NumerGene}.
110 *
111 * @param value The value of the number gene.
112 * @param min The allowed min value of the gene.
113 * @param max The allows max value of the gene.
114 * @throws NullPointerException if one of the given number is null.
115 */
116 protected void set(final N value, final N min, final N max) {
117 _min = requireNonNull(min, "Min value");
118 _max = requireNonNull(max, "Max value");
119 _value = requireNonNull(value, "Gene value");
120 _valid = _value.compareTo(_min) >= 0 && _value.compareTo(_max) <= 0;
121 }
122
123 /**
124 * Test whether this is a valid NumberGene and its value is within the
125 * interval closed interval [min, max].
126 *
127 * @return if this gene is valid, which means the gene value is within the
128 * closed interval [min, max].
129 */
130 @Override
131 public boolean isValid() {
132 return _valid;
133 }
134
135 /**
136 * Return the number value of this gene.
137 *
138 * @return the number value of this gene.
139 */
140 public N getNumber() {
141 return _value;
142 }
143
144 @Override
145 public N getAllele() {
146 return _value;
147 }
148
149 /**
150 * Return the allowed min value.
151 *
152 * @return The allowed min value.
153 */
154 public N getMin() {
155 return _min;
156 }
157
158 /**
159 * Return the allowed max value.
160 *
161 * @return The allowed max value.
162 */
163 public N getMax() {
164 return _max;
165 }
166
167 @Override
168 public double doubleValue() {
169 return _value.doubleValue();
170 }
171
172 @Override
173 public long longValue() {
174 return _value.longValue();
175 }
176
177 @Override
178 public boolean isLargerThan(final G that) {
179 return _value.isLargerThan(that._value);
180 }
181
182 @Override
183 public G plus(final G that) {
184 return newInstance(_value.plus(that._value));
185 }
186
187 @Override
188 public G opposite() {
189 return newInstance(_value.opposite());
190 }
191
192 @Override
193 public G times(final G that) {
194 return newInstance(_value.times(that._value));
195 }
196
197 /**
198 * Remind that this method is not consistent with the {@link #equals(Object)}
199 * method. Since this method only compares the {@code value} and the
200 * {@code equals} method also takes the {@code min} and {@code max} value
201 * into account.
202 * [code]
203 * final NumberGene〈?, ?〉 ng1 = ...
204 * final NumberGene〈?, ?〉 ng2 = ...
205 *
206 * if (ng1.equals(ng2) {
207 * // Holds for every ng1 and ng2.
208 * assert(ng1.compareTo(ng2) == 0);
209 * }
210 * if (ng1.compareTo(ng2) == 0) {
211 * // Doesn't hold for every ng1 and ng2.
212 * assert(ng1.equals(ng2));
213 * }
214 * [/code]
215 */
216 @Override
217 public int compareTo(final G that) {
218 return _value.compareTo(that._value);
219 }
220
221 @Override
222 public int hashCode() {
223 return hashCodeOf(getClass()).and(_value).and(_min).and(_max).value();
224 }
225
226 @Override
227 public boolean equals(final Object obj) {
228 if (obj == this) {
229 return true;
230 }
231 if (obj == null || obj.getClass() != getClass()) {
232 return false;
233 }
234
235 final NumberGene<?, ?> gene = (NumberGene<?, ?>)obj;
236 return eq(_value, gene._value) &&
237 eq(_min, gene._min) &&
238 eq(_max, gene._max);
239 }
240
241 @Override
242 public Text toText() {
243 TextBuilder out = new TextBuilder();
244 out.append("[").append(_value).append("]");
245 return out.toText();
246 }
247
248 }
249
250
251
252
253
|