1 package net.bmahe.genetics4j.core.chromosomes;
2
3 import java.util.Arrays;
4 import java.util.Objects;
5
6 import org.apache.commons.lang3.Validate;
7
8 /**
9 * A chromosome implementation that represents genetic information as an array of integer values.
10 *
11 * <p>IntChromosome is widely used for discrete optimization problems where solutions can be encoded as sequences of
12 * integer values within specified ranges. Each position in the array represents a gene, and the integer value at that
13 * position represents the allele.
14 *
15 * <p>This chromosome type is particularly suitable for:
16 * <ul>
17 * <li><strong>Combinatorial optimization</strong>: Problems with discrete decision variables</li>
18 * <li><strong>Parameter optimization</strong>: Integer hyperparameters, configuration settings</li>
19 * <li><strong>Permutation encoding</strong>: When combined with appropriate operators</li>
20 * <li><strong>Resource allocation</strong>: Assignment and scheduling problems</li>
21 * <li><strong>Graph problems</strong>: Node labeling, path encoding</li>
22 * </ul>
23 *
24 * <p>Key features:
25 * <ul>
26 * <li><strong>Bounded values</strong>: All integers are constrained to [minValue, maxValue]</li>
27 * <li><strong>Fixed length</strong>: Chromosome size is determined at creation time</li>
28 * <li><strong>Immutable</strong>: Values cannot be changed after construction</li>
29 * <li><strong>Type-safe</strong>: Compile-time guarantees for integer operations</li>
30 * </ul>
31 *
32 * <p>The chromosome maintains bounds information which is used by genetic operators to ensure that crossover and
33 * mutation operations produce valid offspring within the specified constraints.
34 *
35 * @see Chromosome
36 * @see net.bmahe.genetics4j.core.spec.chromosome.IntChromosomeSpec
37 * @see net.bmahe.genetics4j.core.chromosomes.factory.IntChromosomeFactory
38 */
39 public class IntChromosome implements Chromosome {
40
41 private final int size;
42 private final int minValue;
43 private final int maxValue;
44 private final int[] values;
45
46 /**
47 * Creates a new integer chromosome with the specified parameters and values.
48 *
49 * @param _size the number of integer values in this chromosome
50 * @param _minValue the minimum allowed value for any integer in this chromosome
51 * @param _maxValue the maximum allowed value for any integer in this chromosome
52 * @param _values the array of integer values for this chromosome
53 * @throws IllegalArgumentException if size is not positive, if minValue > maxValue, if values array is null, or if
54 * the array length doesn't match the specified size
55 */
56 public IntChromosome(final int _size, final int _minValue, final int _maxValue, final int[] _values) {
57 Validate.isTrue(_size > 0);
58 Validate.isTrue(_minValue <= _maxValue);
59 Objects.requireNonNull(_values);
60 Validate.isTrue(_size == _values.length, "Provided size does not match the size of the content");
61
62 this.size = _size;
63 this.minValue = _minValue;
64 this.maxValue = _maxValue;
65 this.values = Arrays.copyOf(_values, _size);
66 }
67
68 @Override
69 public int getNumAlleles() {
70 return size;
71 }
72
73 /**
74 * Returns the integer value at the specified index.
75 *
76 * @param index the index of the allele to retrieve (0-based)
77 * @return the integer value at the specified position
78 * @throws IllegalArgumentException if index is negative or greater than or equal to the chromosome size
79 */
80 public int getAllele(final int index) {
81 Validate.inclusiveBetween(0, size - 1, index);
82
83 return values[index];
84 }
85
86 /**
87 * Returns the number of integer values in this chromosome.
88 *
89 * @return the chromosome size
90 */
91 public int getSize() {
92 return size;
93 }
94
95 /**
96 * Returns the minimum allowed value for integers in this chromosome.
97 *
98 * @return the minimum value constraint
99 */
100 public int getMinValue() {
101 return minValue;
102 }
103
104 /**
105 * Returns the maximum allowed value for integers in this chromosome.
106 *
107 * @return the maximum value constraint
108 */
109 public int getMaxValue() {
110 return maxValue;
111 }
112
113 /**
114 * Returns a copy of the integer values in this chromosome.
115 *
116 * <p>The returned array is a defensive copy; modifications to it will not affect this chromosome.
117 *
118 * @return a copy of the integer values array
119 */
120 public int[] getValues() {
121 return values;
122 }
123
124 /**
125 * Calculates and returns the sum of all integer values in this chromosome.
126 *
127 * <p>This method performs arithmetic addition of all alleles in the chromosome. The result may overflow if the sum
128 * exceeds the range of a 32-bit integer.
129 *
130 * @return the sum of all integer values in this chromosome
131 */
132 public int sum() {
133 int sum = 0;
134 for (int i = 0; i < size; i++) {
135 sum += values[i];
136 }
137
138 return sum;
139 }
140
141 /**
142 * Counts and returns the number of non-zero integer values in this chromosome.
143 *
144 * <p>This method iterates through all alleles and counts those that are not equal to zero.
145 *
146 * @return the count of non-zero integer values in this chromosome (0 to chromosome size)
147 */
148 public int countNonZeros() {
149 int numNonZeros = 0;
150 for (int i = 0; i < size; i++) {
151 if (values[i] != 0) {
152 numNonZeros++;
153 }
154 }
155 return numNonZeros;
156 }
157
158 @Override
159 public int hashCode() {
160 final int prime = 31;
161 int result = 1;
162 result = prime * result + maxValue;
163 result = prime * result + minValue;
164 result = prime * result + size;
165 result = prime * result + Arrays.hashCode(values);
166 return result;
167 }
168
169 @Override
170 public boolean equals(Object obj) {
171 if (this == obj)
172 return true;
173 if (obj == null)
174 return false;
175 if (getClass() != obj.getClass())
176 return false;
177 IntChromosome other = (IntChromosome) obj;
178 if (maxValue != other.maxValue)
179 return false;
180 if (minValue != other.minValue)
181 return false;
182 if (size != other.size)
183 return false;
184 if (!Arrays.equals(values, other.values))
185 return false;
186 return true;
187 }
188
189 @Override
190 public String toString() {
191 return "IntChromosome [size=" + size + ", minValue=" + minValue + ", maxValue=" + maxValue + ", values="
192 + Arrays.toString(values) + "]";
193 }
194 }