SpeciesIdGenerator.java

package net.bmahe.genetics4j.neat;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Generates unique identifiers for NEAT (NeuroEvolution of Augmenting Topologies) species.
 * 
 * <p>SpeciesIdGenerator provides thread-safe generation of unique species identifiers used
 * to distinguish between different species in the NEAT population. Each species receives
 * a unique ID that remains constant throughout its lifecycle, enabling species tracking
 * across generations and proper species management.
 * 
 * <p>Key characteristics:
 * <ul>
 * <li><strong>Thread safety</strong>: Concurrent ID generation for parallel species creation</li>
 * <li><strong>Uniqueness guarantee</strong>: Each generated ID is unique across the generator's lifetime</li>
 * <li><strong>Sequential ordering</strong>: IDs are generated in sequential order for consistent tracking</li>
 * <li><strong>Configurable start</strong>: Initial ID value can be customized for different scenarios</li>
 * </ul>
 * 
 * <p>Species lifecycle integration:
 * <ul>
 * <li><strong>Species creation</strong>: New species receive unique IDs upon formation</li>
 * <li><strong>Species tracking</strong>: IDs enable consistent species identification across generations</li>
 * <li><strong>Population management</strong>: Species IDs facilitate population organization and statistics</li>
 * <li><strong>Evolution monitoring</strong>: IDs enable tracking of species formation, growth, and extinction</li>
 * </ul>
 * 
 * <p>Common usage patterns:
 * <pre>{@code
 * // Default species ID generator (starts from 0)
 * SpeciesIdGenerator generator = new SpeciesIdGenerator();
 * 
 * // Custom starting ID
 * SpeciesIdGenerator customGenerator = new SpeciesIdGenerator(1000);
 * 
 * // Generate unique species IDs
 * int speciesId1 = generator.computeNewId();  // Returns 0
 * int speciesId2 = generator.computeNewId();  // Returns 1
 * int speciesId3 = generator.computeNewId();  // Returns 2
 * 
 * // Create species with generated IDs
 * Species<Double> species1 = new Species<>(speciesId1, ancestors1);
 * Species<Double> species2 = new Species<>(speciesId2, ancestors2);
 * 
 * // Thread-safe concurrent generation
 * CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(generator::computeNewId);
 * CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(generator::computeNewId);
 * // Both futures will receive unique IDs
 * }</pre>
 * 
 * <p>Integration with NEAT species management:
 * <ul>
 * <li><strong>Species formation</strong>: New species created during population organization get unique IDs</li>
 * <li><strong>Selection handlers</strong>: Used by NeatSelectionPolicyHandler for species tracking</li>
 * <li><strong>Population statistics</strong>: Enables species-based metrics and analysis</li>
 * <li><strong>Evolution context</strong>: Integrated into NEAT execution contexts for species management</li>
 * </ul>
 * 
 * <p>Thread safety considerations:
 * <ul>
 * <li><strong>Atomic operations</strong>: Uses AtomicInteger for thread-safe ID generation</li>
 * <li><strong>Concurrent access</strong>: Multiple threads can safely generate IDs simultaneously</li>
 * <li><strong>Lock-free</strong>: No synchronization overhead for high-performance scenarios</li>
 * <li><strong>Consistency</strong>: Guarantees unique IDs even under high concurrency</li>
 * </ul>
 * 
 * <p>Performance characteristics:
 * <ul>
 * <li><strong>O(1) generation</strong>: Constant time ID generation</li>
 * <li><strong>Memory efficient</strong>: Minimal memory footprint with single atomic counter</li>
 * <li><strong>High throughput</strong>: Suitable for high-frequency species creation</li>
 * <li><strong>No contention</strong>: Lock-free implementation avoids thread contention</li>
 * </ul>
 * 
 * @see Species
 * @see net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandler
 * @see NeatEAExecutionContexts
 */
public class SpeciesIdGenerator {

	public static final int DEFAULT_INITIAL_ID = 0;

	private final AtomicInteger currentId;

	/**
	 * Constructs a new species ID generator with the specified initial value.
	 * 
	 * <p>The initial value determines the first ID that will be generated.
	 * Subsequent IDs will be incremented sequentially from this starting point.
	 * 
	 * @param initialValue the first ID value to generate
	 */
	public SpeciesIdGenerator(final int initialValue) {
		currentId = new AtomicInteger(initialValue);
	}

	/**
	 * Constructs a new species ID generator with the default initial value (0).
	 */
	public SpeciesIdGenerator() {
		this(DEFAULT_INITIAL_ID);
	}

	/**
	 * Generates and returns a new unique species ID.
	 * 
	 * <p>This method atomically increments the internal counter and returns
	 * the previous value, ensuring that each call produces a unique identifier.
	 * The operation is thread-safe and can be called concurrently from multiple
	 * threads without risk of duplicate IDs.
	 * 
	 * @return a unique species identifier
	 */
	public int computeNewId() {
		return currentId.getAndIncrement();
	}
}