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