| 
001 /*002  * Java Genetic Algorithm Library (jenetics-4.3.0).
 003  * Copyright (c) 2007-2018 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@gmail.com)
 019  */
 020 package io.jenetics.ext;
 021
 022 import static java.util.Objects.requireNonNull;
 023 import static io.jenetics.internal.util.Hashes.hash;
 024 import static io.jenetics.util.RandomRegistry.getRandom;
 025
 026 import java.io.Serializable;
 027 import java.math.BigInteger;
 028 import java.util.Objects;
 029 import java.util.Random;
 030
 031 import io.jenetics.NumericGene;
 032 import io.jenetics.internal.util.require;
 033 import io.jenetics.util.ISeq;
 034 import io.jenetics.util.MSeq;
 035 import io.jenetics.util.Mean;
 036 import io.jenetics.util.RandomRegistry;
 037
 038 import io.jenetics.ext.internal.random;
 039
 040 /**
 041  * Numeric chromosome implementation which holds an arbitrary sized integer
 042  * number.
 043  *
 044  * <p>This is a <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html">
 045  * value-based</a> class; use of identity-sensitive operations (including
 046  * reference equality ({@code ==}), identity hash code, or synchronization) on
 047  * instances of {@code IntegerGene} may have unpredictable results and should
 048  * be avoided.
 049  *
 050  * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
 051  * @since 3.5
 052  * @version 3.5
 053  */
 054 public final class BigIntegerGene
 055     implements
 056         NumericGene<BigInteger, BigIntegerGene>,
 057         Mean<BigIntegerGene>,
 058         Serializable
 059 {
 060     private static final long serialVersionUID = 1L;
 061
 062     private static final BigInteger TWO = BigInteger.valueOf(2);
 063
 064     private final BigInteger _value;
 065     private final BigInteger _min;
 066     private final BigInteger _max;
 067
 068     private BigIntegerGene(
 069         final BigInteger value,
 070         final BigInteger min,
 071         final BigInteger max
 072     ) {
 073         _value = requireNonNull(value);
 074         _min = requireNonNull(min);
 075         _max = requireNonNull(max);
 076     }
 077
 078     @Override
 079     public BigInteger getAllele() {
 080         return _value;
 081     }
 082
 083     @Override
 084     public BigInteger getMin() {
 085         return _min;
 086     }
 087
 088     @Override
 089     public BigInteger getMax() {
 090         return _max;
 091     }
 092
 093     @Override
 094     public BigIntegerGene mean(final BigIntegerGene that) {
 095         final BigInteger value = _value.add(that._value).divide(TWO);
 096         return of(value, _min, _max);
 097     }
 098
 099     @Override
 100     public BigIntegerGene newInstance(final Number number) {
 101         return of(BigInteger.valueOf(number.longValue()), _min, _max);
 102     }
 103
 104     @Override
 105     public BigIntegerGene newInstance(final BigInteger value) {
 106         return of(value, _min, _max);
 107     }
 108
 109     @Override
 110     public BigIntegerGene newInstance() {
 111         return of(_min, _max);
 112     }
 113
 114     @Override
 115     public int hashCode() {
 116         return hash(_value, hash(_min, hash(_max, hash(getClass()))));
 117     }
 118
 119     @Override
 120     public boolean equals(final Object obj) {
 121         return obj == this ||
 122             obj instanceof BigIntegerGene &&
 123             Objects.equals(((BigIntegerGene)obj)._value, _value) &&
 124             Objects.equals(((BigIntegerGene)obj)._min, _min) &&
 125             Objects.equals(((BigIntegerGene)obj)._max, _max);
 126     }
 127
 128     @Override
 129     public String toString() {
 130         return String.format("[%s]", _value);
 131     }
 132
 133     /* *************************************************************************
 134      * Static factory methods.
 135      **************************************************************************/
 136
 137     static ISeq<BigIntegerGene> seq(
 138         final BigInteger minimum,
 139         final BigInteger maximum,
 140         final int length
 141     ) {
 142         require.positive(length);
 143
 144         final Random r = getRandom();
 145
 146         return MSeq.<BigIntegerGene>ofLength(length)
 147             .fill(() -> new BigIntegerGene(
 148                 random.nextBigInteger(minimum, maximum, r), minimum, maximum))
 149             .toISeq();
 150     }
 151
 152     /**
 153      * Create a new random {@code BigIntegerGene} with the given value and the
 154      * given range. If the {@code value} isn't within the interval [min, max],
 155      * no exception is thrown. In this case the method
 156      * {@link BigIntegerGene#isValid()} returns {@code false}.
 157      *
 158      * @param value the value of the gene.
 159      * @param min the minimal valid value of this gene (inclusively).
 160      * @param max the maximal valid value of this gene (inclusively).
 161      * @return a new random {@code BigIntegerGene}
 162      * @throws NullPointerException if one of the arguments is {@code null}
 163      */
 164     public static BigIntegerGene of(
 165         final BigInteger value,
 166         final BigInteger min,
 167         final BigInteger max
 168     ) {
 169         return new BigIntegerGene(value, min, max);
 170     }
 171
 172     /**
 173      * Create a new random {@code BigIntegerGene}. It is guaranteed that the
 174      * value of the {@code BigIntegerGene} lies in the interval [min, max].
 175      *
 176      * @param min the minimal valid value of this gene (inclusively).
 177      * @param max the maximal valid value of this gene (inclusively).
 178      * @return a new random {@code BigIntegerGene}
 179      * @throws NullPointerException if one of the arguments is {@code null}
 180      */
 181     public static BigIntegerGene of(final BigInteger min, final BigInteger max) {
 182         return of(
 183             random.nextBigInteger(min, max, RandomRegistry.getRandom()),
 184             min,
 185             max
 186         );
 187     }
 188
 189 }
 |