SpeciesIdGenerator.java

1
package net.bmahe.genetics4j.neat;
2
3
import java.util.concurrent.atomic.AtomicInteger;
4
5
/**
6
 * Generates unique identifiers for NEAT (NeuroEvolution of Augmenting Topologies) species.
7
 * 
8
 * <p>SpeciesIdGenerator provides thread-safe generation of unique species identifiers used
9
 * to distinguish between different species in the NEAT population. Each species receives
10
 * a unique ID that remains constant throughout its lifecycle, enabling species tracking
11
 * across generations and proper species management.
12
 * 
13
 * <p>Key characteristics:
14
 * <ul>
15
 * <li><strong>Thread safety</strong>: Concurrent ID generation for parallel species creation</li>
16
 * <li><strong>Uniqueness guarantee</strong>: Each generated ID is unique across the generator's lifetime</li>
17
 * <li><strong>Sequential ordering</strong>: IDs are generated in sequential order for consistent tracking</li>
18
 * <li><strong>Configurable start</strong>: Initial ID value can be customized for different scenarios</li>
19
 * </ul>
20
 * 
21
 * <p>Species lifecycle integration:
22
 * <ul>
23
 * <li><strong>Species creation</strong>: New species receive unique IDs upon formation</li>
24
 * <li><strong>Species tracking</strong>: IDs enable consistent species identification across generations</li>
25
 * <li><strong>Population management</strong>: Species IDs facilitate population organization and statistics</li>
26
 * <li><strong>Evolution monitoring</strong>: IDs enable tracking of species formation, growth, and extinction</li>
27
 * </ul>
28
 * 
29
 * <p>Common usage patterns:
30
 * <pre>{@code
31
 * // Default species ID generator (starts from 0)
32
 * SpeciesIdGenerator generator = new SpeciesIdGenerator();
33
 * 
34
 * // Custom starting ID
35
 * SpeciesIdGenerator customGenerator = new SpeciesIdGenerator(1000);
36
 * 
37
 * // Generate unique species IDs
38
 * int speciesId1 = generator.computeNewId();  // Returns 0
39
 * int speciesId2 = generator.computeNewId();  // Returns 1
40
 * int speciesId3 = generator.computeNewId();  // Returns 2
41
 * 
42
 * // Create species with generated IDs
43
 * Species<Double> species1 = new Species<>(speciesId1, ancestors1);
44
 * Species<Double> species2 = new Species<>(speciesId2, ancestors2);
45
 * 
46
 * // Thread-safe concurrent generation
47
 * CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(generator::computeNewId);
48
 * CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(generator::computeNewId);
49
 * // Both futures will receive unique IDs
50
 * }</pre>
51
 * 
52
 * <p>Integration with NEAT species management:
53
 * <ul>
54
 * <li><strong>Species formation</strong>: New species created during population organization get unique IDs</li>
55
 * <li><strong>Selection handlers</strong>: Used by NeatSelectionPolicyHandler for species tracking</li>
56
 * <li><strong>Population statistics</strong>: Enables species-based metrics and analysis</li>
57
 * <li><strong>Evolution context</strong>: Integrated into NEAT execution contexts for species management</li>
58
 * </ul>
59
 * 
60
 * <p>Thread safety considerations:
61
 * <ul>
62
 * <li><strong>Atomic operations</strong>: Uses AtomicInteger for thread-safe ID generation</li>
63
 * <li><strong>Concurrent access</strong>: Multiple threads can safely generate IDs simultaneously</li>
64
 * <li><strong>Lock-free</strong>: No synchronization overhead for high-performance scenarios</li>
65
 * <li><strong>Consistency</strong>: Guarantees unique IDs even under high concurrency</li>
66
 * </ul>
67
 * 
68
 * <p>Performance characteristics:
69
 * <ul>
70
 * <li><strong>O(1) generation</strong>: Constant time ID generation</li>
71
 * <li><strong>Memory efficient</strong>: Minimal memory footprint with single atomic counter</li>
72
 * <li><strong>High throughput</strong>: Suitable for high-frequency species creation</li>
73
 * <li><strong>No contention</strong>: Lock-free implementation avoids thread contention</li>
74
 * </ul>
75
 * 
76
 * @see Species
77
 * @see net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandler
78
 * @see NeatEAExecutionContexts
79
 */
80
public class SpeciesIdGenerator {
81
82
	public static final int DEFAULT_INITIAL_ID = 0;
83
84
	private final AtomicInteger currentId;
85
86
	/**
87
	 * Constructs a new species ID generator with the specified initial value.
88
	 * 
89
	 * <p>The initial value determines the first ID that will be generated.
90
	 * Subsequent IDs will be incremented sequentially from this starting point.
91
	 * 
92
	 * @param initialValue the first ID value to generate
93
	 */
94
	public SpeciesIdGenerator(final int initialValue) {
95 2 1. <init> : Removed assignment to member variable currentId → KILLED
2. <init> : removed call to java/util/concurrent/atomic/AtomicInteger::<init> → KILLED
		currentId = new AtomicInteger(initialValue);
96
	}
97
98
	/**
99
	 * Constructs a new species ID generator with the default initial value (0).
100
	 */
101
	public SpeciesIdGenerator() {
102 1 1. <init> : Substituted 0 with 1 → SURVIVED
		this(DEFAULT_INITIAL_ID);
103
	}
104
105
	/**
106
	 * Generates and returns a new unique species ID.
107
	 * 
108
	 * <p>This method atomically increments the internal counter and returns
109
	 * the previous value, ensuring that each call produces a unique identifier.
110
	 * The operation is thread-safe and can be called concurrently from multiple
111
	 * threads without risk of duplicate IDs.
112
	 * 
113
	 * @return a unique species identifier
114
	 */
115
	public int computeNewId() {
116 2 1. computeNewId : replaced int return with 0 for net/bmahe/genetics4j/neat/SpeciesIdGenerator::computeNewId → SURVIVED
2. computeNewId : removed call to java/util/concurrent/atomic/AtomicInteger::getAndIncrement → SURVIVED
		return currentId.getAndIncrement();
117
	}
118
}

Mutations

95

1.1
Location : <init>
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest]/[method:select()]
Removed assignment to member variable currentId → KILLED

2.2
Location : <init>
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest]/[method:select()]
removed call to java/util/concurrent/atomic/AtomicInteger::<init> → KILLED

102

1.1
Location : <init>
Killed by : none
Substituted 0 with 1 → SURVIVED
Covering tests

116

1.1
Location : computeNewId
Killed by : none
replaced int return with 0 for net/bmahe/genetics4j/neat/SpeciesIdGenerator::computeNewId → SURVIVED
Covering tests

2.2
Location : computeNewId
Killed by : none
removed call to java/util/concurrent/atomic/AtomicInteger::getAndIncrement → SURVIVED Covering tests

Active mutators

Tests examined


Report generated by PIT 1.19.6