Skip to main content

Crate symbios_neat

Crate symbios_neat 

Source
Expand description

§Symbios NEAT

A high-performance NeuroEvolution of Augmenting Topologies (NEAT) engine for morphogenetic engineering applications.

§Features

  • Hash-Based Innovation: Lock-free, deterministic parallel mutation using Hash(input_node, output_node) instead of global counters
  • Arena-Graph Model: Cache-friendly SlotMap storage for nodes and connections
  • CPPN Support: Periodic and radial activation functions (Sine, Cosine, Gaussian, Abs) for Compositional Pattern Producing Networks
  • HyperNEAT Substrates: Indirect encoding via substrate::substrate_to_network, with LayeredSubstrate, GridSubstrate2D, and GridSubstrate3D provided out of the box
  • Pattern / Voxel / Image Export: generate_pattern_2d, generate_voxel_grid, and (with the image feature) generate_image
  • Speciation: species::NeatDistance adapter for symbios_genetics::speciation
  • Genotype Trait: Implements symbios_genetics::Genotype for use with evolutionary algorithms

§Quick Start

use symbios_neat::{NeatGenome, NeatConfig, CppnEvaluator};
use rand::SeedableRng;
use rand_chacha::ChaCha8Rng;

// Create a CPPN for 2D pattern generation
let config = NeatConfig::cppn(2, 1);
let mut rng = ChaCha8Rng::seed_from_u64(42);
let genome = NeatGenome::fully_connected(config, &mut rng);

// Compile and evaluate. `new` returns `Result<_, EvaluatorError>` —
// it errors on cyclic genomes; call `genome.break_cycles()` first if needed.
let evaluator = CppnEvaluator::new(&genome).expect("acyclic genome");
let output = evaluator.query_2d(0.5, -0.5);
println!("Output: {:?}", output);

§Using with Symbios Genetics

use symbios_genetics::{Evaluator, Evolver, algorithms::simple::SimpleGA};
use symbios_neat::{NeatGenome, NeatConfig, CppnEvaluator};

// Define fitness function
struct XorFitness;
impl Evaluator<NeatGenome> for XorFitness {
    fn evaluate(&self, genome: &NeatGenome) -> (f32, Vec<f32>, Vec<f32>) {
        // CppnEvaluator::new returns Err on cyclic genomes; assign worst fitness if so.
        let Ok(eval) = CppnEvaluator::new(genome) else {
            return (0.0, vec![0.0], vec![]);
        };
        let mut error = 0.0;

        // XOR truth table
        for (inputs, expected) in &[
            ([0.0, 0.0], 0.0),
            ([0.0, 1.0], 1.0),
            ([1.0, 0.0], 1.0),
            ([1.0, 1.0], 0.0),
        ] {
            let output = eval.evaluate(inputs)[0];
            error += (output - expected).powi(2);
        }

        let fitness = 4.0 - error; // Max fitness = 4.0
        (fitness, vec![fitness], vec![])
    }
}

// Run evolution
let config = NeatConfig::minimal(2, 1);
let mut rng = rand::rng();
let initial: Vec<NeatGenome> = (0..100)
    .map(|_| NeatGenome::fully_connected(config.clone(), &mut rng))
    .collect();

let mut ga = SimpleGA::new(initial, 0.3, 5, 42);
for _ in 0..100 {
    ga.step(&XorFitness);
}

§Architecture

§Hash-Based Innovation (Sovereign Innovation)

Traditional NEAT uses a global innovation counter requiring synchronization. This crate uses deterministic hashing:

  • Connections: innovation = Hash(input_node_innovation, output_node_innovation)
  • Nodes (from split): innovation = Hash(connection_innovation, SPLIT_MARKER)

This enables lock-free parallel mutation across threads without coordination.

§Arena-Graph Model

Nodes and connections are stored in flat SlotMap buffers:

  • No reference counting overhead
  • Cache-friendly memory layout
  • Trivially serializable via Serde
  • Safe generational indices prevent use-after-free

Re-exports§

pub use activation::Activation;
pub use evaluator::CppnEvaluator;
pub use evaluator::EvalScratchpad;
pub use evaluator::EvaluatorError;
pub use evaluator::PatternError;
pub use gene::ConnectionGene;
pub use gene::ConnectionId;
pub use gene::NodeGene;
pub use gene::NodeId;
pub use gene::NodeType;
pub use genome::NeatConfig;
pub use genome::NeatGenome;
pub use innovation::connection_innovation;
pub use innovation::node_split_innovation;
pub use innovation::split_connection_a_innovation;
pub use innovation::split_connection_b_innovation;
pub use network::FeedforwardNetwork;
pub use network::Scratchpad;
pub use species::NeatDistance;
pub use substrate::GridSubstrate2D;
pub use substrate::GridSubstrate3D;
pub use substrate::LayeredSubstrate;
pub use substrate::Substrate;
pub use substrate::SubstrateNode;
pub use substrate::substrate_to_network;
pub use topology::GraphTopology;

Modules§

activation
Activation functions for NEAT networks.
evaluator
CPPN evaluator for NEAT genomes.
gene
Gene types for NEAT genomes.
genome
NEAT genome implementation with arena-allocated graph topology.
innovation
Hash-based innovation tracking for NEAT.
network
Generic feed-forward network with CSR-format forward propagation.
species
NEAT adapter for the generic symbios_genetics::speciation primitives.
substrate
HyperNEAT substrate trait and concrete implementations.
topology
Graph topology analysis using CSR format.