1 package net.bmahe.genetics4j.neat; 2 3 /** 4 * Represents a pair of node indices defining a potential connection in NEAT neural networks. 5 * 6 * <p>ConnectionPair is a simple record that encapsulates the source and target node indices for a neural network 7 * connection. This immutable data structure is primarily used as a key for innovation number caching in the 8 * InnovationManager, enabling efficient lookup and assignment of innovation numbers based on connection topology. 9 * 10 * <p>Key characteristics: 11 * <ul> 12 * <li><strong>Immutable</strong>: Record provides immutability for safe use as hash keys</li> 13 * <li><strong>Value semantics</strong>: Equality based on both from and to node indices</li> 14 * <li><strong>Hash key</strong>: Optimized for use in hash-based collections</li> 15 * <li><strong>Lightweight</strong>: Minimal memory overhead with just two integer fields</li> 16 * </ul> 17 * 18 * <p>Usage in innovation tracking: 19 * <ul> 20 * <li><strong>Cache key</strong>: Used as key in InnovationManager's innovation cache</li> 21 * <li><strong>Connection identification</strong>: Uniquely identifies connection types</li> 22 * <li><strong>Historical tracking</strong>: Enables consistent innovation number assignment</li> 23 * <li><strong>Population consistency</strong>: Same connection pairs get same innovation numbers</li> 24 * </ul> 25 * 26 * <p>Common usage patterns: 27 * 28 * <pre>{@code 29 * // Create connection pair for innovation tracking 30 * ConnectionPair pair = new ConnectionPair(0, 3); // Input 0 -> Output 3 31 * 32 * // Use as cache key in innovation manager 33 * Map<ConnectionPair, Integer> innovationCache = new HashMap<>(); 34 * int innovationNumber = innovationCache.computeIfAbsent(pair, k -> innovationManager.getNextInnovationNumber()); 35 * 36 * // Connection pair represents potential connection topology 37 * List<ConnectionPair> possibleConnections = List.of(new ConnectionPair(0, 2), // Input 0 -> Output 2 38 * new ConnectionPair(1, 2), // Input 1 -> Output 2 39 * new ConnectionPair(0, 3), // Input 0 -> Output 3 40 * new ConnectionPair(1, 3) // Input 1 -> Output 3 41 * ); 42 * }</pre> 43 * 44 * <p>Integration with NEAT algorithm: 45 * <ul> 46 * <li><strong>Innovation management</strong>: Key component of innovation number caching</li> 47 * <li><strong>Structural mutations</strong>: Used when adding new connections to networks</li> 48 * <li><strong>Genetic tracking</strong>: Enables consistent gene identification across population</li> 49 * <li><strong>Crossover operations</strong>: Supports gene alignment during recombination</li> 50 * </ul> 51 * 52 * <p>Performance considerations: 53 * <ul> 54 * <li><strong>Efficient hashing</strong>: Record provides optimized hash code implementation</li> 55 * <li><strong>Memory efficient</strong>: Compact representation with minimal overhead</li> 56 * <li><strong>Cache friendly</strong>: Small size improves cache locality</li> 57 * <li><strong>GC efficient</strong>: Immutable objects reduce garbage collection pressure</li> 58 * </ul> 59 * 60 * <p>Value semantics: 61 * <ul> 62 * <li><strong>Equality</strong>: Two pairs are equal if both from and to indices match</li> 63 * <li><strong>Hash code</strong>: Computed from both node indices for efficient hash table usage</li> 64 * <li><strong>String representation</strong>: Readable format showing connection direction</li> 65 * <li><strong>Comparison</strong>: Natural ordering based on from index, then to index</li> 66 * </ul> 67 * 68 * @param from the source node index of the connection 69 * @param to the target node index of the connection 70 * @see InnovationManager 71 * @see Connection 72 * @see net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandler 73 */ 74 public record ConnectionPair(int from, int to) { 75 76 }