BigIntegerChromosome.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.9.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.ext;
021 
022 import static org.jenetics.internal.util.Equality.eq;
023 
024 import java.io.IOException;
025 import java.io.ObjectInputStream;
026 import java.io.ObjectOutputStream;
027 import java.io.Serializable;
028 import java.math.BigInteger;
029 
030 import org.jenetics.internal.util.Equality;
031 import org.jenetics.internal.util.Hash;
032 
033 import org.jenetics.AbstractChromosome;
034 import org.jenetics.DoubleGene;
035 import org.jenetics.NumericChromosome;
036 import org.jenetics.util.ISeq;
037 import org.jenetics.util.MSeq;
038 
039 /**
040  * Numeric chromosome implementation which holds arbitrary sized integer numbers.
041  *
042  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
043  @version 3.5
044  @since 3.5
045  */
046 public class BigIntegerChromosome
047     extends AbstractChromosome<BigIntegerGene>
048     implements
049         NumericChromosome<BigInteger, BigIntegerGene>,
050         Serializable
051 {
052 
053     private static final long serialVersionUID = 1L;
054 
055     private BigInteger _min;
056     private BigInteger _max;
057 
058     /**
059      * Create a new chromosome from the given genes array.
060      *
061      @param genes the genes of the new chromosome.
062      @throws IllegalArgumentException if the {@code genes.length()} is smaller
063      *         than one.
064      @throws NullPointerException if the {@code genes} are {@code null}.
065      @throws IllegalArgumentException if the gene sequence is empty
066      */
067     protected BigIntegerChromosome(final ISeq<BigIntegerGene> genes) {
068         super(genes);
069         _min = genes.get(0).getMin();
070         _max = genes.get(0).getMax();
071     }
072 
073     /**
074      * Create a new random {@code BigIntegerChromosome} with the given
075      * {@code length}.
076      *
077      @param min the min value of the {@link BigIntegerGene}s (inclusively).
078      @param max the max value of the {@link BigIntegerGene}s (inclusively).
079      @param length the length of the chromosome.
080      @throws NullPointerException if one of the arguments is {@code null}.
081      @throws IllegalArgumentException if the {@code length} is smaller than
082      *         one.
083      */
084     public BigIntegerChromosome(
085         final BigInteger min,
086         final BigInteger max,
087         final int length
088     ) {
089         this(BigIntegerGene.seq(min, max, length));
090         _valid = true;
091     }
092 
093     /**
094      * Create a new random {@code DoubleChromosome} of length one.
095      *
096      @param min the minimal value of this chromosome (inclusively).
097      @param max the maximal value of this chromosome (exclusively).
098      @throws NullPointerException if one of the arguments is {@code null}.
099      */
100     public BigIntegerChromosome(final BigInteger min, final BigInteger max) {
101         this(min, max, 1);
102     }
103 
104     @Override
105     public BigInteger getMin() {
106         return _min;
107     }
108 
109     @Override
110     public BigInteger getMax() {
111         return _max;
112     }
113 
114     @Override
115     public BigIntegerChromosome newInstance(final ISeq<BigIntegerGene> genes) {
116         return new BigIntegerChromosome(genes);
117     }
118 
119     @Override
120     public BigIntegerChromosome newInstance() {
121         return new BigIntegerChromosome(_min, _max, length());
122     }
123 
124     @Override
125     public int hashCode() {
126         return Hash.of(getClass())
127             .and(super.hashCode())
128             .and(_min)
129             .and(_max).value();
130     }
131 
132     @Override
133     public boolean equals(final Object object) {
134         return Equality.of(this, object).test(nc ->
135             eq(_min, nc._min&&
136                 eq(_max, nc._max&&
137                 super.equals(object)
138         );
139     }
140 
141     /* *************************************************************************
142      * Static factory methods.
143      **************************************************************************/
144 
145     /**
146      * Create a new {@code DoubleChromosome} with the given genes.
147      *
148      @param genes the genes of the chromosome.
149      @return a new chromosome with the given genes.
150      @throws IllegalArgumentException if the length of the genes array is
151      *         empty.
152      @throws NullPointerException if the given {@code genes} array is
153      *         {@code null}
154      */
155     public static BigIntegerChromosome of(final BigIntegerGene... genes) {
156         return new BigIntegerChromosome(ISeq.of(genes));
157     }
158 
159     /**
160      * Create a new random {@code DoubleChromosome}.
161      *
162      @param min the min value of the {@link DoubleGene}s (inclusively).
163      @param max the max value of the {@link DoubleGene}s (exclusively).
164      @param length the length of the chromosome.
165      @return a new {@code DoubleChromosome} with the given parameter
166      */
167     public static BigIntegerChromosome of(final BigInteger min, BigInteger max, final int length) {
168         return new BigIntegerChromosome(min, max, length);
169     }
170 
171     /**
172      * Create a new random {@code DoubleChromosome} of length one.
173      *
174      @param min the minimal value of this chromosome (inclusively).
175      @param max the maximal value of this chromosome (exclusively).
176      @return a new {@code DoubleChromosome} with the given parameter
177      */
178     public static BigIntegerChromosome of(final BigInteger min, final BigInteger max) {
179         return new BigIntegerChromosome(min, max);
180     }
181 
182     /* *************************************************************************
183      *  Java object serialization
184      * ************************************************************************/
185 
186     private void writeObject(final ObjectOutputStream out)
187         throws IOException
188     {
189         out.defaultWriteObject();
190 
191         out.writeInt(length());
192         out.writeObject(_min);
193         out.writeObject(_max);
194 
195         for (BigIntegerGene gene : _genes) {
196             out.writeObject(gene.getAllele());
197         }
198     }
199 
200     private void readObject(final ObjectInputStream in)
201         throws IOException, ClassNotFoundException
202     {
203         in.defaultReadObject();
204 
205         final MSeq<BigIntegerGene> genes = MSeq.ofLength(in.readInt());
206         _min = (BigInteger)in.readObject();
207         _max = (BigInteger)in.readObject();
208 
209         for (int i = 0; i < genes.length(); ++i) {
210             final BigInteger value = (BigInteger)in.readObject();
211             genes.set(i, BigIntegerGene.of(value, _min, _max));
212         }
213 
214         _genes = genes.toISeq();
215     }
216 
217 }