radiate-rust 0.3.0

A Rust library for genetic algorithms and artificial evolution.
Documentation
use rand::Rng;

use super::gene::{BoundGene, Gene, NumericGene, Valid};

pub struct IntGene {
    allele: i32,
    min: i32,
    max: i32,
    upper_bound: i32,
    lower_bound: i32,
}

impl IntGene {
    pub fn new(min: i32, max: i32) -> Self {
        let (min, max) = if min > max { (max, min) } else { (min, max) };
        let mut rand = rand::thread_rng();
        IntGene {
            allele: rand.gen_range(min..max),
            min,
            max,
            upper_bound: i32::MAX,
            lower_bound: i32::MIN,
        }
    }
}

impl Gene<IntGene, i32> for IntGene {
    fn allele(&self) -> &i32 {
        &self.allele
    }

    fn new_instance(&self) -> IntGene {
        let mut rand = rand::thread_rng();
        IntGene {
            allele: rand.gen_range(self.min..self.max),
            min: self.min,
            max: self.max,
            upper_bound: self.upper_bound,
            lower_bound: self.lower_bound,
        }
    }

    fn from_allele(&self, allele: &i32) -> IntGene {
        IntGene {
            allele: *allele,
            min: self.min,
            max: self.max,
            upper_bound: self.upper_bound,
            lower_bound: self.lower_bound
        }
    }
}

impl Valid for IntGene {
    fn is_valid(&self) -> bool {
        self.allele >= self.min && self.allele <= self.max
    }
}

impl BoundGene<IntGene, i32> for IntGene {
    fn upper_bound(&self) -> &i32 {
        &self.upper_bound
    }

    fn lower_bound(&self) -> &i32 {
        &self.lower_bound
    }

    fn with_bounds(self, upper_bound: i32, lower_bound: i32) -> IntGene {
        IntGene {
            upper_bound,
            lower_bound,
            ..self
        }
    }
}

impl NumericGene<IntGene, i32> for IntGene {
    fn add(&self, other: &IntGene) -> IntGene {
        IntGene {
            allele: self.allele + other.allele,
            ..*self
        }
    }

    fn sub(&self, other: &IntGene) -> IntGene {
        IntGene {
            allele: self.allele - other.allele,
            ..*self
        }
    }

    fn mul(&self, other: &IntGene) -> IntGene {
        IntGene {
            allele: self.allele * other.allele,
            ..*self
        }
    }

    fn div(&self, other: &IntGene) -> IntGene {
        let other_allele = match other.allele() == &0_i32 {
            true => 1_i32,
            false => *other.allele()
        };
        
        IntGene {
            allele: self.allele / other_allele,
            ..*self
        }
    }

    fn mean(&self, other: &IntGene) -> IntGene {
        IntGene {
            allele: (self.allele + other.allele) / 2,
            ..*self
        }
    }
}

impl Clone for IntGene {
    fn clone(&self) -> Self {
        IntGene {
            allele: self.allele,
            min: self.min,
            max: self.max,
            upper_bound: self.upper_bound,
            lower_bound: self.lower_bound,
        }
    }
}

impl PartialEq for IntGene {
    fn eq(&self, other: &Self) -> bool {
        self.allele == other.allele
    }
}

impl std::fmt::Debug for IntGene {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.allele)
    }
}