Class NeatChromosome

java.lang.Object
net.bmahe.genetics4j.neat.chromosomes.NeatChromosome
All Implemented Interfaces:
Chromosome

public class NeatChromosome extends Object implements Chromosome
Represents a neural network chromosome in the NEAT (NeuroEvolution of Augmenting Topologies) algorithm.

NeatChromosome is the core genetic representation in NEAT, encoding a neural network as a collection of connections between nodes. Each chromosome defines a complete neural network topology with input nodes, output nodes, optional hidden nodes, and weighted connections. The chromosome maintains essential parameters for network construction and genetic operations.

Key characteristics:

  • Network topology: Encoded as a list of connections with innovation numbers
  • Node organization: Fixed input/output nodes with dynamically added hidden nodes
  • Weight constraints: Configurable minimum and maximum weight bounds
  • Innovation tracking: Connections sorted by innovation number for genetic alignment

NEAT algorithm integration:

  • Structural mutations: Add/delete nodes and connections while preserving innovation tracking
  • Weight mutations: Modify connection weights within specified bounds
  • Genetic crossover: Innovation-number-based gene alignment for topology recombination
  • Compatibility distance: Genetic similarity measurement for speciation

Network structure:

  • Input nodes: Indices 0 to (numInputs - 1), receive external inputs
  • Output nodes: Indices numInputs to (numInputs + numOutputs - 1), produce network outputs
  • Hidden nodes: Indices starting from (numInputs + numOutputs), created by add-node mutations
  • Connections: Weighted links between nodes with enable/disable states and innovation numbers

Common usage patterns:


 // Create a basic NEAT chromosome
 List<Connection> connections = List.of(
     Connection.of(0, 2, 0.5f, true, 0),   // input 0 -> output 0
     Connection.of(1, 3, -0.3f, true, 1)   // input 1 -> output 1
 );
 
 NeatChromosome chromosome = new NeatChromosome(
     2,      // number of inputs
     2,      // number of outputs  
     -1.0f,  // minimum weight
     1.0f,   // maximum weight
     connections
 );
 
 // Access chromosome properties
 int numAlleles = chromosome.getNumAlleles();
 Set<Integer> inputNodes = chromosome.getInputNodeIndices();
 Set<Integer> outputNodes = chromosome.getOutputNodeIndices();
 List<Connection> allConnections = chromosome.getConnections();
 
 // Create feed-forward network for evaluation
 FeedForwardNetwork network = new FeedForwardNetwork(
     chromosome.getInputNodeIndices(),
     chromosome.getOutputNodeIndices(),
     chromosome.getConnections(),
     Activations::sigmoid
 );
 

Genetic operations compatibility:

  • Mutation operations: Compatible with weight, add-node, add-connection, and state mutations
  • Crossover operations: Innovation numbers enable proper gene alignment between parents
  • Selection operations: Supports species-based selection through compatibility distance
  • Evaluation operations: Can be converted to executable neural networks

Innovation number organization:

  • Sorted connections: Connections automatically sorted by innovation number
  • Genetic alignment: Enables efficient crossover and compatibility calculations
  • Historical tracking: Maintains evolutionary history of structural changes
  • Population consistency: Same innovation numbers across population for same connection types

Performance considerations:

  • Immutable connections: Connection list is sorted once and made immutable
  • Efficient lookup: Node indices computed deterministically for fast access
  • Memory efficiency: Only stores necessary network topology information
  • Cache-friendly: Sorted connections improve cache locality for genetic operations

Integration with NEAT ecosystem:

  • Chromosome factories: Created by NeatConnectedChromosomeFactory and similar
  • Genetic operators: Processed by NEAT-specific mutation and crossover handlers
  • Network evaluation: Converted to FeedForwardNetwork for fitness computation
  • Speciation: Used in compatibility distance calculations for species formation
See Also:
  • Field Details

    • numInputs

      private final int numInputs
    • numOutputs

      private final int numOutputs
    • minWeightValue

      private final float minWeightValue
    • maxWeightValue

      private final float maxWeightValue
    • connections

      private final List<Connection> connections
  • Constructor Details

    • NeatChromosome

      public NeatChromosome(int _numInputs, int _numOutputs, float _minWeightValue, float _maxWeightValue, List<Connection> _connections)
      Constructs a new NEAT chromosome with the specified network topology and parameters.

      This constructor creates an immutable neural network chromosome by copying and sorting the provided connections by their innovation numbers. The sorting ensures efficient genetic operations and proper gene alignment during crossover operations.

      Network structure validation:

      • Input and output counts must be positive
      • Weight bounds must be properly ordered (min < max)
      • Connections list must not be null (but can be empty)
      • Connection endpoints should reference valid nodes (not enforced here)
      Parameters:
      _numInputs - number of input nodes in the network (must be positive)
      _numOutputs - number of output nodes in the network (must be positive)
      _minWeightValue - minimum allowed connection weight value
      _maxWeightValue - maximum allowed connection weight value (must be > minWeightValue)
      _connections - list of network connections (will be copied and sorted by innovation number)
      Throws:
      IllegalArgumentException - if numInputs <= 0, numOutputs <= 0, minWeightValue >= maxWeightValue, or connections is null
  • Method Details

    • getNumAlleles

      public int getNumAlleles()
      Returns the total number of alleles (genetic components) in this chromosome.

      For NEAT chromosomes, the allele count includes:

      • Input nodes: Each input node represents one allele
      • Output nodes: Each output node represents one allele
      • Connections: Each connection (with its weight and state) represents one allele

      Hidden nodes are not counted separately as they are implicit in the connection structure. This count is used by the genetic algorithm framework for population statistics and compatibility calculations.

      Specified by:
      getNumAlleles in interface Chromosome
      Returns:
      the total number of alleles in this chromosome
    • getNumInputs

      public int getNumInputs()
      Returns the number of input nodes in this neural network.

      Input nodes are the entry points for external data into the network. They are assigned node indices from 0 to (numInputs - 1) and do not apply activation functions to their input values.

      Returns:
      the number of input nodes (always positive)
    • getNumOutputs

      public int getNumOutputs()
      Returns the number of output nodes in this neural network.

      Output nodes produce the final results of network computation. They are assigned node indices from numInputs to (numInputs + numOutputs - 1) and apply activation functions to their weighted input sums.

      Returns:
      the number of output nodes (always positive)
    • getMinWeightValue

      public float getMinWeightValue()
      Returns the minimum allowed connection weight value for this network.

      This bound is used by mutation operators to constrain weight perturbations and ensure that connection weights remain within reasonable ranges. Weight mutations should respect this bound to maintain network stability.

      Returns:
      the minimum allowed connection weight
    • getMaxWeightValue

      public float getMaxWeightValue()
      Returns the maximum allowed connection weight value for this network.

      This bound is used by mutation operators to constrain weight perturbations and ensure that connection weights remain within reasonable ranges. Weight mutations should respect this bound to maintain network stability.

      Returns:
      the maximum allowed connection weight
    • getConnections

      public List<Connection> getConnections()
      Returns an immutable list of all connections in this neural network.

      The connections are sorted by innovation number to ensure consistent ordering for genetic operations. Each connection defines a weighted link between two nodes and includes an enabled/disabled state for topology exploration.

      Connection properties:

      • Immutable ordering: Connections are sorted by innovation number
      • Complete topology: Includes both enabled and disabled connections
      • Genetic information: Each connection carries innovation tracking data
      • Network structure: Defines the complete computational graph
      Returns:
      immutable list of network connections, sorted by innovation number
    • getInputNodeIndices

      public Set<Integer> getInputNodeIndices()
      Returns the set of input node indices for this neural network.

      Input node indices are deterministically assigned as consecutive integers starting from 0. Input nodes receive external data and do not apply activation functions to their values. These indices are used for network construction and evaluation.

      Index assignment:

      • Range: 0 to (numInputs - 1)
      • Fixed assignment: Input indices never change during evolution
      • External interface: These indices map to external input data
      • No activation: Input nodes pass through their values unchanged
      Returns:
      set of input node indices (0 to numInputs-1)
    • getOutputNodeIndices

      public Set<Integer> getOutputNodeIndices()
      Returns the set of output node indices for this neural network.

      Output node indices are deterministically assigned as consecutive integers starting immediately after the input nodes. Output nodes apply activation functions to their weighted input sums and produce the final network results.

      Index assignment:

      • Range: numInputs to (numInputs + numOutputs - 1)
      • Fixed assignment: Output indices never change during evolution
      • Network results: These nodes produce the final computational output
      • Activation applied: Output nodes apply activation functions to their sums
      Returns:
      set of output node indices (numInputs to numInputs+numOutputs-1)
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object