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