genetic 0.2.1

a little lib to use genetic algorithm
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   universe.rs                                        :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: crenault <crenault@student.42.fr>          +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2015/07/06 14:47:32 by crenault          #+#    #+#             */
/*   Updated: 2015/07/07 12:10:03 by crenault         ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

use evaluable::Evaluable;
use evaluator::Evaluator;
use reproducer::Reproducer;
use mutable::Mutable;

// prefer copy at clone ?
pub struct Universe<'a, 'b, T: Evaluable + Mutable + Ord + PartialOrd + Clone + ToString> {

	population: Vec<T>,
	evaluator: &'a mut Evaluator<T>,
	reproducer: &'b mut Reproducer<T>,

	// settings
	pop_limit: usize,
	limit_cycle: usize,
	mutation_rate: f32
}

impl<'a, 'b, T: Evaluable + Mutable + Ord + PartialOrd + Clone + ToString> Universe<'a, 'b, T> {

	pub fn new(evaluator: &'a mut Evaluator<T>, reproducer: &'b mut Reproducer<T>) -> Universe<'a, 'b, T> {

		let pop_limit = 50;

		Universe{

			population: Vec::with_capacity(pop_limit),
			evaluator: evaluator,
			reproducer: reproducer,

			// settings
			pop_limit: pop_limit,
			limit_cycle: 10_000,
			mutation_rate: 0.01
		}
	}

	// todo: settings like "nn crates.io"

	pub fn go(&mut self, pop_vec: &Vec<T>) {

		self.population = pop_vec.clone();

		// each cycle
		for cycle in 0..self.limit_cycle {

			println!("cycle: {}", cycle);
			self.print_best();

			// compute new population
			self.evaluator.measure_fitness(&mut self.population);
			self.order_population();

			self.reproducer.reproduce(&mut self.population);
			self.mutate_population();
		}
	}

	fn order_population(&mut self) {

		self.population.sort_by(|a, b| b.cmp(a));
	}

	fn mutate_population(&mut self) {

		// use threads
		for indi in self.population.iter_mut() {

			indi.mutate(self.mutation_rate);
		}
	}

	fn print_best(&self) {

		if let Some(indi) = self.population.first() {
			println!("best: {}", indi.to_string());
		}
		else {
			println!("Empty population!");
		}
	}
}