neat_lib 0.1.1

Rust implementation of NeuroEvolution of Augmenting Topologies
Documentation
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use crate::neat::attribute::FloatAttribute;
use crate::neat::config::Config;

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum GeneType {
    Input,
    Output,
    Hidden,
}

#[derive(Clone, Serialize, Deserialize)]
pub struct Gene {
    config: Config,
    pub key: usize,
    pub value: FloatAttribute,
    pub bias: FloatAttribute,
    pub response: FloatAttribute,
    pub gene_type: GeneType,
    pub incoming_conns: HashSet<usize>
}

impl Gene {
    pub fn new(config: &Config, key: usize, gene_type: GeneType) -> Self {
        Self::new_with_value(config, key,0.0, gene_type)
    }

    pub fn new_with_value(config: &Config, key: usize, value: f64, gene_type: GeneType) -> Self {
        Gene { 
            config: config.clone(),
            key,
            value: FloatAttribute::new(value), 
            bias: FloatAttribute::new_norm(0.0, 1.0), 
            response: FloatAttribute::new_norm(0.0, 1.0), 
            incoming_conns: HashSet::new(), 
            gene_type 
        }
    }

    pub fn mutate(&mut self) {
        self.bias.mutate(self.config.bias_replace_rate, self.config.bias_mutate_rate, self.config.bias_mutate_power, self.config.bias_min_value, self.config.bias_max_value, self.config.bias_init_mean, self.config.bias_init_stdev);
        self.response.mutate(self.config.response_replace_rate, self.config.response_mutate_rate, self.config.response_mutate_power, self.config.response_min_value, self.config.response_max_value, self.config.response_init_mean, self.config.response_init_stdev);
    }

    pub fn add_incomming_conn(&mut self, incoming_conn: usize) -> bool {
        self.incoming_conns.insert(incoming_conn)
    }

    pub fn remove_incoming_conn(&mut self, incoming_conn: &usize) -> bool {
        self.incoming_conns.remove(incoming_conn)
    }
}

impl std::fmt::Debug for Gene {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Gene[ key:{:?} type:{:?} \tvalue:{:?} \tbias:{:?} \tresponse:{:?} \tincoming_conns:{:?} ]", self.key, self.gene_type, self.value, self.bias, self.response, self.incoming_conns)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_new_with_value() {
        let config = Config::default();
        let gene = Gene::new_with_value(&config, 1, 0.0, GeneType::Input);
    }
}