mod tests {
extern crate calco;
extern crate rand;
use self::rand::Rng;
use self::calco::{ Universe, Config };
use self::calco::StopCondition::*;
use self::calco::{ Mutable, Reproducible, Evaluable };
#[derive(Clone)]
struct Individual(f32, f32, f32);
impl Mutable for Individual {
fn mutate(&mut self) {
match rand::thread_rng().gen_range(0, 3) {
0 => { self.0 = rand::thread_rng().gen_range(-10_000.0, 10_000.0) },
1 => { self.1 = rand::thread_rng().gen_range(-10_000.0, 10_000.0) },
_ => { self.2 = rand::thread_rng().gen_range(-10_000.0, 10_000.0) }
}
}
}
impl Reproducible for Individual {
fn reproduce_with(&self, other: &Self) -> Vec<Self> {
vec![Individual(
(self.0 + other.0) / 2.0,
(self.1 + other.1) / 2.0,
(self.2 + other.2) / 2.0
),
Individual(other.0, self.1, other.2),
Individual(self.0, other.1, self.2)
]
}
}
impl Evaluable for Individual {
fn evaluate(&self) -> f32 {
let optimum = Individual(100.0, 0.0, -300.0);
let a = self.0 - optimum.0;
let b = self.1 - optimum.1;
let c = self.2 - optimum.2;
let pow_a = a * a;
let pow_b = b * b;
let pow_c = c * c;
let dist = (pow_a + pow_b + pow_c).sqrt();
let invert_dist = 1.0 / dist;
return invert_dist;
}
}
#[test]
fn test_complete_working() {
let config = Config{
mutate_ratio: 0.01,
pop_max: 100,
stop_condition: GenerationReached(12_000)
};
let pop = vec![
Individual(1200.0, -2328.0, 1816.0),
Individual(-8234.0, 6472.0, 784.0),
Individual(9451.0, -4613.0, -5131.0),
Individual(-8641.0, -2358.0, -9761.0),
Individual(-3715.0, 6.0, 3489.0),
Individual(-651.0, 258.0, -6851.0)
];
let mut world = Universe::from_pop(config, pop);
for _ in 0..1_000 {
world.evaluate();
world.mutate();
world.reproduce();
}
}
}