diff --git a/src/lib.rs b/src/lib.rs
index 9508737..e94ca92 100644
@@ -13,6 +13,7 @@ extern crate simple_parallel;
use rand::{Rand, Rng};
use std::cmp::PartialOrd;
use simple_parallel::Pool;
+use std::ops::Deref;
pub mod bit_string;
@@ -93,44 +94,27 @@ pub trait Evaluator<I:Individual, F:Fitness>: Sync {
fn fitness(&self, individual: &I) -> F;
}
-/// Caches the `fitness` value for an individual.
-#[derive(Clone, Debug)]
-pub struct EvaluatedIndividual<I: Individual, F: Fitness> {
- individual: I,
- fitness: Option<F>,
-}
-
-impl<I:Individual, F:Fitness> EvaluatedIndividual<I,F> {
- pub fn new(ind: I) -> EvaluatedIndividual<I, F> {
- EvaluatedIndividual {
- individual: ind,
- fitness: None,
- }
- }
- #[inline(always)]
- pub fn fitness(&self) -> Option<F> {
- self.fitness.clone()
- }
- #[inline(always)]
- pub fn individual<'a>(&'a self) -> &'a I {
- &self.individual
- }
-}
-
/// Manages a population of individuals.
#[derive(Clone, Debug)]
-pub struct Population<I: Individual, F: Fitness> {
- population: Vec<EvaluatedIndividual<I, F>>,
+pub struct Population<W, I, F>
+where W:Deref<Target=I>,
+ I:Individual,
+ F:Fitness,
+{
+ population: Vec<(W, Option<F>)>,
}
// XXX: Have Population and EvaluatedPopulation. This avoids having two arrays.
-impl<I:Individual, F:Fitness> Population<I,F>
+impl<W, I, F> Population<W, I, F>
+where W:Deref<Target=I>,
+ I:Individual,
+ F:Fitness,
{
- pub fn new() -> Population<I, F> {
+ pub fn new() -> Population<W, I, F> {
Population { population: Vec::new() }
}
- pub fn with_capacity(capa: usize) -> Population<I, F> {
+ pub fn with_capacity(capa: usize) -> Population<W, I, F> {
Population { population: Vec::with_capacity(capa) }
}
@@ -143,8 +127,8 @@ impl<I:Individual, F:Fitness> Population<I,F>
pub fn fittest(&self) -> Option<(usize, F)> {
let mut fittest: Option<(usize, F)> = None;
- for (i, ref ind) in self.population.iter().enumerate() {
- if let Some(ref f) = ind.fitness {
+ for (i, ref elm) in self.population.iter().enumerate() {
+ if let Some(ref f) = elm.1 {
let mut is_better = true;
if let Some((_, ref best_f)) = fittest {
if !f.fitter_than(best_f) {
@@ -161,20 +145,20 @@ impl<I:Individual, F:Fitness> Population<I,F>
#[inline]
pub fn get_individual(&self, idx: usize) -> &I {
- &self.population[idx].individual
+ &self.population[idx].0
}
#[inline]
pub fn get_fitness(&self, idx: usize) -> F {
- (&self.population[idx]).fitness.clone().unwrap()
+ (&self.population[idx]).1.clone().unwrap()
}
- pub fn add_individual(&mut self, ind: I) {
- self.population.push(EvaluatedIndividual::new(ind));
+ pub fn add_individual(&mut self, ind: W) {
+ self.population.push((ind, None));
}
pub fn add_individual_with_fitness(&mut self, ind: I, fitness: F) {
- self.population.push(EvaluatedIndividual{individual: ind, fitness: Some(fitness)});
+ self.population.push((ind, Some(fitness)));
}
/// Evaluates the whole population, i.e. determines the fitness of
@@ -185,10 +169,10 @@ impl<I:Individual, F:Fitness> Population<I,F>
{
let mut nevals = 0;
for i in self.population.iter_mut() {
- if i.fitness.is_some() {
+ if i.1.is_some() {
continue;
}
- i.fitness = Some(evaluator.fitness(&i.individual));
+ i.1 = Some(evaluator.fitness(&(*i.0)));
nevals += 1;
}
return nevals;
@@ -215,8 +199,8 @@ impl<I:Individual, F:Fitness> Population<I,F>
}
});
*/
- pool.for_(self.population.iter_mut(), |ind| {
- ind.fitness = Some(evaluator.fitness(&ind.individual));
+ pool.for_(self.population.iter_mut().map(|ind| ind), |ind| {
+ ind.1 = Some(evaluator.fitness(&ind.0));
});
return nevals;