View Javadoc
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 }