1
|
|
package net.bmahe.genetics4j.core; |
2
|
|
|
3
|
|
import java.util.Iterator; |
4
|
|
|
5
|
|
import org.apache.commons.lang3.Validate; |
6
|
|
|
7
|
|
/** |
8
|
|
* Iterator implementation for traversing individuals in a population during evolutionary algorithms. |
9
|
|
* |
10
|
|
* <p>PopulationIterator provides a standard Java Iterator interface for accessing individuals |
11
|
|
* in a {@link Population}, combining genotypes with their corresponding fitness values to create |
12
|
|
* complete {@link Individual} instances during iteration. |
13
|
|
* |
14
|
|
* <p>This iterator enables convenient traversal patterns such as: |
15
|
|
* <ul> |
16
|
|
* <li><strong>Enhanced for loops</strong>: Iterate over individuals using for-each syntax</li> |
17
|
|
* <li><strong>Stream operations</strong>: Convert populations to streams for functional processing</li> |
18
|
|
* <li><strong>Sequential access</strong>: Process individuals one at a time without loading all into memory</li> |
19
|
|
* <li><strong>Collection integration</strong>: Use with Java Collection framework methods</li> |
20
|
|
* </ul> |
21
|
|
* |
22
|
|
* <p>The iterator maintains internal state to track the current position and constructs |
23
|
|
* {@link Individual} objects on-demand by combining genotypes and fitness values from the |
24
|
|
* underlying population at the same index. |
25
|
|
* |
26
|
|
* <p>Key characteristics: |
27
|
|
* <ul> |
28
|
|
* <li><strong>Type safety</strong>: Parameterized with fitness type for compile-time type checking</li> |
29
|
|
* <li><strong>Lazy evaluation</strong>: Creates Individual objects only when requested</li> |
30
|
|
* <li><strong>Memory efficient</strong>: Doesn't duplicate population data, references original</li> |
31
|
|
* <li><strong>Standard interface</strong>: Implements Java Iterator contract completely</li> |
32
|
|
* </ul> |
33
|
|
* |
34
|
|
* <p>Usage patterns: |
35
|
|
* <pre>{@code |
36
|
|
* // Enhanced for loop iteration |
37
|
|
* Population<Double> population = getPopulation(); |
38
|
|
* for (Individual<Double> individual : population) { |
39
|
|
* System.out.println("Fitness: " + individual.fitness()); |
40
|
|
* } |
41
|
|
* |
42
|
|
* // Stream-based processing |
43
|
|
* population.stream() |
44
|
|
* .filter(individual -> individual.fitness() > threshold) |
45
|
|
* .mapToDouble(Individual::fitness) |
46
|
|
* .average(); |
47
|
|
* |
48
|
|
* // Manual iteration |
49
|
|
* Iterator<Individual<Double>> iterator = population.iterator(); |
50
|
|
* while (iterator.hasNext()) { |
51
|
|
* Individual<Double> individual = iterator.next(); |
52
|
|
* processIndividual(individual); |
53
|
|
* } |
54
|
|
* }</pre> |
55
|
|
* |
56
|
|
* <p>Thread safety considerations: |
57
|
|
* <ul> |
58
|
|
* <li><strong>Single-threaded use</strong>: Iterator instances are not thread-safe</li> |
59
|
|
* <li><strong>Population stability</strong>: Underlying population should not be modified during iteration</li> |
60
|
|
* <li><strong>Concurrent iterations</strong>: Multiple iterators can be created for the same population</li> |
61
|
|
* </ul> |
62
|
|
* |
63
|
|
* @param <T> the type of fitness values in the population, must be comparable for selection operations |
64
|
|
* @see Population |
65
|
|
* @see Individual |
66
|
|
* @see java.util.Iterator |
67
|
|
*/ |
68
|
|
public class PopulationIterator<T extends Comparable<T>> implements Iterator<Individual<T>> { |
69
|
|
|
70
|
|
private final Population<T> population; |
71
|
|
|
72
|
2
1. <init> : Removed assignment to member variable currentIndex → SURVIVED
2. <init> : Substituted 0 with 1 → KILLED
|
private int currentIndex = 0; |
73
|
|
|
74
|
|
/** |
75
|
|
* Constructs a new iterator for the specified population. |
76
|
|
* |
77
|
|
* <p>Creates an iterator that will traverse all individuals in the given population, |
78
|
|
* starting from index 0 and proceeding sequentially through all individuals. |
79
|
|
* |
80
|
|
* @param _population the population to iterate over |
81
|
|
* @throws IllegalArgumentException if the population is null |
82
|
|
*/ |
83
|
|
public PopulationIterator(final Population<T> _population) { |
84
|
|
Validate.notNull(_population); |
85
|
|
|
86
|
1
1. <init> : Removed assignment to member variable population → KILLED
|
this.population = _population; |
87
|
|
} |
88
|
|
|
89
|
|
/** |
90
|
|
* Returns {@code true} if there are more individuals to iterate over. |
91
|
|
* |
92
|
|
* <p>Checks whether the current position is within the bounds of the population. |
93
|
|
* This method can be called multiple times without advancing the iterator position. |
94
|
|
* |
95
|
|
* @return {@code true} if there are more individuals, {@code false} if all have been visited |
96
|
|
*/ |
97
|
|
@Override |
98
|
|
public boolean hasNext() { |
99
|
8
1. hasNext : Substituted 1 with 0 → KILLED
2. hasNext : changed conditional boundary → KILLED
3. hasNext : removed call to net/bmahe/genetics4j/core/Population::size → KILLED
4. hasNext : removed conditional - replaced comparison check with true → KILLED
5. hasNext : removed conditional - replaced comparison check with false → KILLED
6. hasNext : Substituted 0 with 1 → KILLED
7. hasNext : replaced boolean return with true for net/bmahe/genetics4j/core/PopulationIterator::hasNext → KILLED
8. hasNext : negated conditional → KILLED
|
return currentIndex < population.size(); |
100
|
|
} |
101
|
|
|
102
|
|
/** |
103
|
|
* Returns the next individual in the population and advances the iterator position. |
104
|
|
* |
105
|
|
* <p>Constructs an {@link Individual} by combining the genotype and fitness value |
106
|
|
* at the current position, then advances to the next position for subsequent calls. |
107
|
|
* |
108
|
|
* @return the next individual in the iteration sequence |
109
|
|
* @throws java.util.NoSuchElementException if there are no more individuals (when {@link #hasNext()} returns false) |
110
|
|
*/ |
111
|
|
@Override |
112
|
|
public Individual<T> next() { |
113
|
1
1. next : removed call to net/bmahe/genetics4j/core/Population::getGenotype → KILLED
|
final Genotype genotype = population.getGenotype(currentIndex); |
114
|
1
1. next : removed call to net/bmahe/genetics4j/core/Population::getFitness → KILLED
|
final T fitness = population.getFitness(currentIndex); |
115
|
3
1. next : Removed assignment to member variable currentIndex → KILLED
2. next : Replaced integer addition with subtraction → KILLED
3. next : Substituted 1 with 0 → KILLED
|
currentIndex++; |
116
|
2
1. next : replaced return value with null for net/bmahe/genetics4j/core/PopulationIterator::next → KILLED
2. next : removed call to net/bmahe/genetics4j/core/Individual::of → KILLED
|
return Individual.of(genotype, fitness); |
117
|
|
} |
118
|
|
} |
| | Mutations |
72 |
|
1.1 Location : <init> Killed by : none Removed assignment to member variable currentIndex → SURVIVED
Covering tests
Covered by tests:
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:constructorWithValidPopulation()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:constructorWithNullPopulation()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnNonEmptyPopulation()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextAdvancesIterator()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:iteratorStateConsistency()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextAfterIterationComplete()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:multipleIteratorsOnSamePopulation()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:iteratorWithDifferentGeneticTypes()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextMultipleCalls()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:iteratorWithJavaIteratorInterface()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:completeIteration()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:singleElementPopulation()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:iteratorIntegrationWithEnhancedForLoop()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextOnEmptyPopulation()]
- net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:iteratorIntegrationWithWhileLoop()]
2.2 Location : <init> Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()] Substituted 0 with 1 → KILLED
|
86 |
|
1.1 Location : <init> Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()] Removed assignment to member variable population → KILLED
|
99 |
|
1.1 Location : hasNext Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnNonEmptyPopulation()] Substituted 1 with 0 → KILLED
2.2 Location : hasNext Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()] changed conditional boundary → KILLED
3.3 Location : hasNext Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnNonEmptyPopulation()] removed call to net/bmahe/genetics4j/core/Population::size → KILLED
4.4 Location : hasNext Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()] removed conditional - replaced comparison check with true → KILLED
5.5 Location : hasNext Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnNonEmptyPopulation()] removed conditional - replaced comparison check with false → KILLED
6.6 Location : hasNext Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()] Substituted 0 with 1 → KILLED
7.7 Location : hasNext Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()] replaced boolean return with true for net/bmahe/genetics4j/core/PopulationIterator::hasNext → KILLED
8.8 Location : hasNext Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()] negated conditional → KILLED
|
113 |
|
1.1 Location : next Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()] removed call to net/bmahe/genetics4j/core/Population::getGenotype → KILLED
|
114 |
|
1.1 Location : next Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()] removed call to net/bmahe/genetics4j/core/Population::getFitness → KILLED
|
115 |
|
1.1 Location : next Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextAdvancesIterator()] Removed assignment to member variable currentIndex → KILLED
2.2 Location : next Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextAdvancesIterator()] Replaced integer addition with subtraction → KILLED
3.3 Location : next Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextAdvancesIterator()] Substituted 1 with 0 → KILLED
|
116 |
|
1.1 Location : next Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()] replaced return value with null for net/bmahe/genetics4j/core/PopulationIterator::next → KILLED
2.2 Location : next Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()] removed call to net/bmahe/genetics4j/core/Individual::of → KILLED
|