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