001/* 002 * Java Genetic Algorithm Library (jenetics-9.1.0). 003 * Copyright (c) 2007-2026 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 java.util.Objects.requireNonNull; 023import static io.jenetics.util.RandomRegistry.random; 024 025import java.io.Serial; 026import java.io.Serializable; 027import java.math.BigInteger; 028import java.util.Objects; 029 030import io.jenetics.NumericGene; 031import io.jenetics.internal.util.Requires; 032import io.jenetics.util.ISeq; 033import io.jenetics.util.MSeq; 034import io.jenetics.util.Mean; 035import io.jenetics.util.RandomRegistry; 036 037import io.jenetics.ext.internal.util.Randoms; 038 039/** 040 * Numeric chromosome implementation which holds an arbitrary sized integer 041 * number. 042 * 043 * <p>This is a <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html"> 044 * value-based</a> class; use of identity-sensitive operations (including 045 * reference equality ({@code ==}), identity hash code, or synchronization) on 046 * instances of {@code IntegerGene} may have unpredictable results and should 047 * be avoided. 048 * 049 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 050 * @since 3.5 051 * @version 6.0 052 */ 053public final class BigIntegerGene 054 implements 055 NumericGene<BigInteger, BigIntegerGene>, 056 Mean<BigIntegerGene>, 057 Serializable 058{ 059 @Serial 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 allele() { 080 return _value; 081 } 082 083 @Override 084 public BigInteger min() { 085 return _min; 086 } 087 088 @Override 089 public BigInteger max() { 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 Objects.hash(_value, _min, _max); 117 } 118 119 @Override 120 public boolean equals(final Object obj) { 121 return obj instanceof BigIntegerGene other && 122 Objects.equals(other._value, _value) && 123 Objects.equals(other._min, _min) && 124 Objects.equals(other._max, _max); 125 } 126 127 @Override 128 public String toString() { 129 return String.format("[%s]", _value); 130 } 131 132 /* ************************************************************************* 133 * Static factory methods. 134 **************************************************************************/ 135 136 static ISeq<BigIntegerGene> seq( 137 final BigInteger minimum, 138 final BigInteger maximum, 139 final int length 140 ) { 141 Requires.positive(length); 142 143 final var r = random(); 144 145 return MSeq.<BigIntegerGene>ofLength(length) 146 .fill(() -> new BigIntegerGene( 147 Randoms.nextBigInteger(minimum, maximum, r), minimum, maximum)) 148 .toISeq(); 149 } 150 151 /** 152 * Create a new random {@code BigIntegerGene} with the given value and the 153 * given range. If the {@code value} isn't within the interval [min, max), 154 * no exception is thrown. In this case the method 155 * {@link BigIntegerGene#isValid()} returns {@code false}. 156 * 157 * @param value the value of the gene. 158 * @param min the minimal valid value of this gene (inclusively). 159 * @param max the maximal valid value of this gene (exclusively). 160 * @return a new random {@code BigIntegerGene} 161 * @throws NullPointerException if one of the arguments is {@code null} 162 */ 163 public static BigIntegerGene of( 164 final BigInteger value, 165 final BigInteger min, 166 final BigInteger max 167 ) { 168 return new BigIntegerGene(value, min, max); 169 } 170 171 /** 172 * Create a new random {@code BigIntegerGene}. It is guaranteed that the 173 * value of the {@code BigIntegerGene} lies in the interval [min, max). 174 * 175 * @param min the minimal valid value of this gene (inclusively). 176 * @param max the maximal valid value of this gene (exclusively). 177 * @return a new random {@code BigIntegerGene} 178 * @throws NullPointerException if one of the arguments is {@code null} 179 */ 180 public static BigIntegerGene of(final BigInteger min, final BigInteger max) { 181 return of( 182 Randoms.nextBigInteger(min, max, RandomRegistry.random()), 183 min, 184 max 185 ); 186 } 187 188}